github.com/lusis/distribution@v2.0.1+incompatible/manifest/manifest.go (about)

     1  package manifest
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	"github.com/docker/distribution/digest"
     7  	"github.com/docker/libtrust"
     8  )
     9  
    10  // TODO(stevvooe): When we rev the manifest format, the contents of this
    11  // package should me moved to manifest/v1.
    12  
    13  const (
    14  	// ManifestMediaType specifies the mediaType for the current version. Note
    15  	// that for schema version 1, the the media is optionally
    16  	// "application/json".
    17  	ManifestMediaType = "application/vnd.docker.distribution.manifest.v1+json"
    18  )
    19  
    20  // Versioned provides a struct with just the manifest schemaVersion. Incoming
    21  // content with unknown schema version can be decoded against this struct to
    22  // check the version.
    23  type Versioned struct {
    24  	// SchemaVersion is the image manifest schema that this image follows
    25  	SchemaVersion int `json:"schemaVersion"`
    26  }
    27  
    28  // Manifest provides the base accessible fields for working with V2 image
    29  // format in the registry.
    30  type Manifest struct {
    31  	Versioned
    32  
    33  	// Name is the name of the image's repository
    34  	Name string `json:"name"`
    35  
    36  	// Tag is the tag of the image specified by this manifest
    37  	Tag string `json:"tag"`
    38  
    39  	// Architecture is the host architecture on which this image is intended to
    40  	// run
    41  	Architecture string `json:"architecture"`
    42  
    43  	// FSLayers is a list of filesystem layer blobSums contained in this image
    44  	FSLayers []FSLayer `json:"fsLayers"`
    45  
    46  	// History is a list of unstructured historical data for v1 compatibility
    47  	History []History `json:"history"`
    48  }
    49  
    50  // SignedManifest provides an envelope for a signed image manifest, including
    51  // the format sensitive raw bytes. It contains fields to
    52  type SignedManifest struct {
    53  	Manifest
    54  
    55  	// Raw is the byte representation of the ImageManifest, used for signature
    56  	// verification. The value of Raw must be used directly during
    57  	// serialization, or the signature check will fail. The manifest byte
    58  	// representation cannot change or it will have to be re-signed.
    59  	Raw []byte `json:"-"`
    60  }
    61  
    62  // UnmarshalJSON populates a new ImageManifest struct from JSON data.
    63  func (sm *SignedManifest) UnmarshalJSON(b []byte) error {
    64  	var manifest Manifest
    65  	if err := json.Unmarshal(b, &manifest); err != nil {
    66  		return err
    67  	}
    68  
    69  	sm.Manifest = manifest
    70  	sm.Raw = make([]byte, len(b), len(b))
    71  	copy(sm.Raw, b)
    72  
    73  	return nil
    74  }
    75  
    76  // Payload returns the raw, signed content of the signed manifest. The
    77  // contents can be used to calculate the content identifier.
    78  func (sm *SignedManifest) Payload() ([]byte, error) {
    79  	jsig, err := libtrust.ParsePrettySignature(sm.Raw, "signatures")
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	// Resolve the payload in the manifest.
    85  	return jsig.Payload()
    86  }
    87  
    88  // Signatures returns the signatures as provided by
    89  // (*libtrust.JSONSignature).Signatures. The byte slices are opaque jws
    90  // signatures.
    91  func (sm *SignedManifest) Signatures() ([][]byte, error) {
    92  	jsig, err := libtrust.ParsePrettySignature(sm.Raw, "signatures")
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  
    97  	// Resolve the payload in the manifest.
    98  	return jsig.Signatures()
    99  }
   100  
   101  // MarshalJSON returns the contents of raw. If Raw is nil, marshals the inner
   102  // contents. Applications requiring a marshaled signed manifest should simply
   103  // use Raw directly, since the the content produced by json.Marshal will be
   104  // compacted and will fail signature checks.
   105  func (sm *SignedManifest) MarshalJSON() ([]byte, error) {
   106  	if len(sm.Raw) > 0 {
   107  		return sm.Raw, nil
   108  	}
   109  
   110  	// If the raw data is not available, just dump the inner content.
   111  	return json.Marshal(&sm.Manifest)
   112  }
   113  
   114  // FSLayer is a container struct for BlobSums defined in an image manifest
   115  type FSLayer struct {
   116  	// BlobSum is the tarsum of the referenced filesystem image layer
   117  	BlobSum digest.Digest `json:"blobSum"`
   118  }
   119  
   120  // History stores unstructured v1 compatibility information
   121  type History struct {
   122  	// V1Compatibility is the raw v1 compatibility information
   123  	V1Compatibility string `json:"v1Compatibility"`
   124  }