github.com/npaton/distribution@v2.3.1-rc.0+incompatible/manifests.go (about)

     1  package distribution
     2  
     3  import (
     4  	"fmt"
     5  	"mime"
     6  
     7  	"github.com/docker/distribution/context"
     8  	"github.com/docker/distribution/digest"
     9  )
    10  
    11  // Manifest represents a registry object specifying a set of
    12  // references and an optional target
    13  type Manifest interface {
    14  	// References returns a list of objects which make up this manifest.
    15  	// The references are strictly ordered from base to head. A reference
    16  	// is anything which can be represented by a distribution.Descriptor
    17  	References() []Descriptor
    18  
    19  	// Payload provides the serialized format of the manifest, in addition to
    20  	// the mediatype.
    21  	Payload() (mediatype string, payload []byte, err error)
    22  }
    23  
    24  // ManifestBuilder creates a manifest allowing one to include dependencies.
    25  // Instances can be obtained from a version-specific manifest package.  Manifest
    26  // specific data is passed into the function which creates the builder.
    27  type ManifestBuilder interface {
    28  	// Build creates the manifest from his builder.
    29  	Build(ctx context.Context) (Manifest, error)
    30  
    31  	// References returns a list of objects which have been added to this
    32  	// builder. The dependencies are returned in the order they were added,
    33  	// which should be from base to head.
    34  	References() []Descriptor
    35  
    36  	// AppendReference includes the given object in the manifest after any
    37  	// existing dependencies. If the add fails, such as when adding an
    38  	// unsupported dependency, an error may be returned.
    39  	AppendReference(dependency Describable) error
    40  }
    41  
    42  // ManifestService describes operations on image manifests.
    43  type ManifestService interface {
    44  	// Exists returns true if the manifest exists.
    45  	Exists(ctx context.Context, dgst digest.Digest) (bool, error)
    46  
    47  	// Get retrieves the manifest specified by the given digest
    48  	Get(ctx context.Context, dgst digest.Digest, options ...ManifestServiceOption) (Manifest, error)
    49  
    50  	// Put creates or updates the given manifest returning the manifest digest
    51  	Put(ctx context.Context, manifest Manifest, options ...ManifestServiceOption) (digest.Digest, error)
    52  
    53  	// Delete removes the manifest specified by the given digest. Deleting
    54  	// a manifest that doesn't exist will return ErrManifestNotFound
    55  	Delete(ctx context.Context, dgst digest.Digest) error
    56  
    57  	// Enumerate fills 'manifests' with the manifests in this service up
    58  	// to the size of 'manifests' and returns 'n' for the number of entries
    59  	// which were filled.  'last' contains an offset in the manifest set
    60  	// and can be used to resume iteration.
    61  	//Enumerate(ctx context.Context, manifests []Manifest, last Manifest) (n int, err error)
    62  }
    63  
    64  // Describable is an interface for descriptors
    65  type Describable interface {
    66  	Descriptor() Descriptor
    67  }
    68  
    69  // ManifestMediaTypes returns the supported media types for manifests.
    70  func ManifestMediaTypes() (mediaTypes []string) {
    71  	for t := range mappings {
    72  		if t != "" {
    73  			mediaTypes = append(mediaTypes, t)
    74  		}
    75  	}
    76  	return
    77  }
    78  
    79  // UnmarshalFunc implements manifest unmarshalling a given MediaType
    80  type UnmarshalFunc func([]byte) (Manifest, Descriptor, error)
    81  
    82  var mappings = make(map[string]UnmarshalFunc, 0)
    83  
    84  // UnmarshalManifest looks up manifest unmarshall functions based on
    85  // MediaType
    86  func UnmarshalManifest(ctHeader string, p []byte) (Manifest, Descriptor, error) {
    87  	// Need to look up by the actual media type, not the raw contents of
    88  	// the header. Strip semicolons and anything following them.
    89  	var mediatype string
    90  	if ctHeader != "" {
    91  		var err error
    92  		mediatype, _, err = mime.ParseMediaType(ctHeader)
    93  		if err != nil {
    94  			return nil, Descriptor{}, err
    95  		}
    96  	}
    97  
    98  	unmarshalFunc, ok := mappings[mediatype]
    99  	if !ok {
   100  		unmarshalFunc, ok = mappings[""]
   101  		if !ok {
   102  			return nil, Descriptor{}, fmt.Errorf("unsupported manifest mediatype and no default available: %s", mediatype)
   103  		}
   104  	}
   105  
   106  	return unmarshalFunc(p)
   107  }
   108  
   109  // RegisterManifestSchema registers an UnmarshalFunc for a given schema type.  This
   110  // should be called from specific
   111  func RegisterManifestSchema(mediatype string, u UnmarshalFunc) error {
   112  	if _, ok := mappings[mediatype]; ok {
   113  		return fmt.Errorf("manifest mediatype registration would overwrite existing: %s", mediatype)
   114  	}
   115  	mappings[mediatype] = u
   116  	return nil
   117  }