manifests.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. // Describable is an interface for descriptors
  52. type Describable interface {
  53. Descriptor() Descriptor
  54. }
  55. // ManifestMediaTypes returns the supported media types for manifests.
  56. func ManifestMediaTypes() (mediaTypes []string) {
  57. for t := range mappings {
  58. if t != "" {
  59. mediaTypes = append(mediaTypes, t)
  60. }
  61. }
  62. return
  63. }
  64. // UnmarshalFunc implements manifest unmarshalling a given MediaType
  65. type UnmarshalFunc func([]byte) (Manifest, Descriptor, error)
  66. var mappings = make(map[string]UnmarshalFunc, 0)
  67. // UnmarshalManifest looks up manifest unmarshal functions based on
  68. // MediaType
  69. func UnmarshalManifest(ctHeader string, p []byte) (Manifest, Descriptor, error) {
  70. // Need to look up by the actual media type, not the raw contents of
  71. // the header. Strip semicolons and anything following them.
  72. var mediatype string
  73. if ctHeader != "" {
  74. var err error
  75. mediatype, _, err = mime.ParseMediaType(ctHeader)
  76. if err != nil {
  77. return nil, Descriptor{}, err
  78. }
  79. }
  80. unmarshalFunc, ok := mappings[mediatype]
  81. if !ok {
  82. unmarshalFunc, ok = mappings[""]
  83. if !ok {
  84. return nil, Descriptor{}, fmt.Errorf("unsupported manifest mediatype and no default available: %s", mediatype)
  85. }
  86. }
  87. return unmarshalFunc(p)
  88. }
  89. // RegisterManifestSchema registers an UnmarshalFunc for a given schema type. This
  90. // should be called from specific
  91. func RegisterManifestSchema(mediatype string, u UnmarshalFunc) error {
  92. if _, ok := mappings[mediatype]; ok {
  93. return fmt.Errorf("manifest mediatype registration would overwrite existing: %s", mediatype)
  94. }
  95. mappings[mediatype] = u
  96. return nil
  97. }