123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- package schema2
- import (
- "encoding/json"
- "errors"
- "fmt"
- "github.com/docker/distribution"
- "github.com/docker/distribution/digest"
- "github.com/docker/distribution/manifest"
- )
- const (
- // MediaTypeManifest specifies the mediaType for the current version.
- MediaTypeManifest = "application/vnd.docker.distribution.manifest.v2+json"
- // MediaTypeConfig specifies the mediaType for the image configuration.
- MediaTypeConfig = "application/vnd.docker.container.image.v1+json"
- // MediaTypeLayer is the mediaType used for layers referenced by the
- // manifest.
- MediaTypeLayer = "application/vnd.docker.image.rootfs.diff.tar.gzip"
- )
- var (
- // SchemaVersion provides a pre-initialized version structure for this
- // packages version of the manifest.
- SchemaVersion = manifest.Versioned{
- SchemaVersion: 2,
- MediaType: MediaTypeManifest,
- }
- )
- func init() {
- schema2Func := func(b []byte) (distribution.Manifest, distribution.Descriptor, error) {
- m := new(DeserializedManifest)
- err := m.UnmarshalJSON(b)
- if err != nil {
- return nil, distribution.Descriptor{}, err
- }
- dgst := digest.FromBytes(b)
- return m, distribution.Descriptor{Digest: dgst, Size: int64(len(b)), MediaType: MediaTypeManifest}, err
- }
- err := distribution.RegisterManifestSchema(MediaTypeManifest, schema2Func)
- if err != nil {
- panic(fmt.Sprintf("Unable to register manifest: %s", err))
- }
- }
- // Manifest defines a schema2 manifest.
- type Manifest struct {
- manifest.Versioned
- // Config references the image configuration as a blob.
- Config distribution.Descriptor `json:"config"`
- // Layers lists descriptors for the layers referenced by the
- // configuration.
- Layers []distribution.Descriptor `json:"layers"`
- }
- // References returnes the descriptors of this manifests references.
- func (m Manifest) References() []distribution.Descriptor {
- return m.Layers
- }
- // Target returns the target of this signed manifest.
- func (m Manifest) Target() distribution.Descriptor {
- return m.Config
- }
- // DeserializedManifest wraps Manifest with a copy of the original JSON.
- // It satisfies the distribution.Manifest interface.
- type DeserializedManifest struct {
- Manifest
- // canonical is the canonical byte representation of the Manifest.
- canonical []byte
- }
- // FromStruct takes a Manifest structure, marshals it to JSON, and returns a
- // DeserializedManifest which contains the manifest and its JSON representation.
- func FromStruct(m Manifest) (*DeserializedManifest, error) {
- var deserialized DeserializedManifest
- deserialized.Manifest = m
- var err error
- deserialized.canonical, err = json.MarshalIndent(&m, "", " ")
- return &deserialized, err
- }
- // UnmarshalJSON populates a new Manifest struct from JSON data.
- func (m *DeserializedManifest) UnmarshalJSON(b []byte) error {
- m.canonical = make([]byte, len(b), len(b))
- // store manifest in canonical
- copy(m.canonical, b)
- // Unmarshal canonical JSON into Manifest object
- var manifest Manifest
- if err := json.Unmarshal(m.canonical, &manifest); err != nil {
- return err
- }
- m.Manifest = manifest
- return nil
- }
- // MarshalJSON returns the contents of canonical. If canonical is empty,
- // marshals the inner contents.
- func (m *DeserializedManifest) MarshalJSON() ([]byte, error) {
- if len(m.canonical) > 0 {
- return m.canonical, nil
- }
- return nil, errors.New("JSON representation not initialized in DeserializedManifest")
- }
- // Payload returns the raw content of the manifest. The contents can be used to
- // calculate the content identifier.
- func (m DeserializedManifest) Payload() (string, []byte, error) {
- return m.MediaType, m.canonical, nil
- }
|