manifests.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package distribution
  2. import (
  3. "fmt"
  4. "mime"
  5. "github.com/docker/distribution/context"
  6. "github.com/opencontainers/go-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. // A reference is anything which can be represented by a
  13. // distribution.Descriptor. These can consist of layers, resources or other
  14. // manifests.
  15. //
  16. // While no particular order is required, implementations should return
  17. // them from highest to lowest priority. For example, one might want to
  18. // return the base layer before the top layer.
  19. References() []Descriptor
  20. // Payload provides the serialized format of the manifest, in addition to
  21. // the media type.
  22. Payload() (mediaType string, payload []byte, err error)
  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. // References returns a list of objects which have been added to this
  31. // builder. The dependencies are returned in the order they were added,
  32. // which should be from base to head.
  33. References() []Descriptor
  34. // AppendReference includes the given object in the manifest after any
  35. // existing dependencies. If the add fails, such as when adding an
  36. // unsupported dependency, an error may be returned.
  37. //
  38. // The destination of the reference is dependent on the manifest type and
  39. // the dependency type.
  40. AppendReference(dependency Describable) error
  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. // Get retrieves the manifest specified by the given digest
  47. Get(ctx context.Context, dgst digest.Digest, options ...ManifestServiceOption) (Manifest, error)
  48. // Put creates or updates the given manifest returning the manifest digest
  49. Put(ctx context.Context, manifest Manifest, options ...ManifestServiceOption) (digest.Digest, error)
  50. // Delete removes the manifest specified by the given digest. Deleting
  51. // a manifest that doesn't exist will return ErrManifestNotFound
  52. Delete(ctx context.Context, dgst digest.Digest) error
  53. }
  54. // ManifestEnumerator enables iterating over manifests
  55. type ManifestEnumerator interface {
  56. // Enumerate calls ingester for each manifest.
  57. Enumerate(ctx context.Context, ingester func(digest.Digest) error) error
  58. }
  59. // Describable is an interface for descriptors
  60. type Describable interface {
  61. Descriptor() Descriptor
  62. }
  63. // ManifestMediaTypes returns the supported media types for manifests.
  64. func ManifestMediaTypes() (mediaTypes []string) {
  65. for t := range mappings {
  66. if t != "" {
  67. mediaTypes = append(mediaTypes, t)
  68. }
  69. }
  70. return
  71. }
  72. // UnmarshalFunc implements manifest unmarshalling a given MediaType
  73. type UnmarshalFunc func([]byte) (Manifest, Descriptor, error)
  74. var mappings = make(map[string]UnmarshalFunc, 0)
  75. // UnmarshalManifest looks up manifest unmarshal functions based on
  76. // MediaType
  77. func UnmarshalManifest(ctHeader string, p []byte) (Manifest, Descriptor, error) {
  78. // Need to look up by the actual media type, not the raw contents of
  79. // the header. Strip semicolons and anything following them.
  80. var mediaType string
  81. if ctHeader != "" {
  82. var err error
  83. mediaType, _, err = mime.ParseMediaType(ctHeader)
  84. if err != nil {
  85. return nil, Descriptor{}, err
  86. }
  87. }
  88. unmarshalFunc, ok := mappings[mediaType]
  89. if !ok {
  90. unmarshalFunc, ok = mappings[""]
  91. if !ok {
  92. return nil, Descriptor{}, fmt.Errorf("unsupported manifest media type and no default available: %s", mediaType)
  93. }
  94. }
  95. return unmarshalFunc(p)
  96. }
  97. // RegisterManifestSchema registers an UnmarshalFunc for a given schema type. This
  98. // should be called from specific
  99. func RegisterManifestSchema(mediaType string, u UnmarshalFunc) error {
  100. if _, ok := mappings[mediaType]; ok {
  101. return fmt.Errorf("manifest media type registration would overwrite existing: %s", mediaType)
  102. }
  103. mappings[mediaType] = u
  104. return nil
  105. }