manifests.go 4.2 KB

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