config.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package distribution // import "github.com/docker/docker/distribution"
  2. import (
  3. "context"
  4. "encoding/json"
  5. "io"
  6. "runtime"
  7. "github.com/distribution/reference"
  8. "github.com/docker/distribution"
  9. "github.com/docker/distribution/manifest/schema2"
  10. "github.com/docker/docker/api/types/events"
  11. "github.com/docker/docker/api/types/registry"
  12. "github.com/docker/docker/distribution/metadata"
  13. "github.com/docker/docker/distribution/xfer"
  14. "github.com/docker/docker/image"
  15. "github.com/docker/docker/layer"
  16. "github.com/docker/docker/pkg/progress"
  17. refstore "github.com/docker/docker/reference"
  18. registrypkg "github.com/docker/docker/registry"
  19. "github.com/opencontainers/go-digest"
  20. ocispec "github.com/opencontainers/image-spec/specs-go/v1"
  21. "github.com/pkg/errors"
  22. )
  23. // Config stores configuration for communicating
  24. // with a registry.
  25. type Config struct {
  26. // MetaHeaders stores HTTP headers with metadata about the image
  27. MetaHeaders map[string][]string
  28. // AuthConfig holds authentication credentials for authenticating with
  29. // the registry.
  30. AuthConfig *registry.AuthConfig
  31. // ProgressOutput is the interface for showing the status of the pull
  32. // operation.
  33. ProgressOutput progress.Output
  34. // RegistryService is the registry service to use for TLS configuration
  35. // and endpoint lookup.
  36. RegistryService RegistryResolver
  37. // ImageEventLogger notifies events for a given image
  38. ImageEventLogger func(id, name string, action events.Action)
  39. // MetadataStore is the storage backend for distribution-specific
  40. // metadata.
  41. MetadataStore metadata.Store
  42. // ImageStore manages images.
  43. ImageStore ImageConfigStore
  44. // ReferenceStore manages tags. This value is optional, when excluded
  45. // content will not be tagged.
  46. ReferenceStore refstore.Store
  47. }
  48. // ImagePullConfig stores pull configuration.
  49. type ImagePullConfig struct {
  50. Config
  51. // DownloadManager manages concurrent pulls.
  52. DownloadManager *xfer.LayerDownloadManager
  53. // Schema2Types is an optional list of valid schema2 configuration types
  54. // allowed by the pull operation. If omitted, the default list of accepted
  55. // types is used.
  56. Schema2Types []string
  57. // Platform is the requested platform of the image being pulled
  58. Platform *ocispec.Platform
  59. }
  60. // ImagePushConfig stores push configuration.
  61. type ImagePushConfig struct {
  62. Config
  63. // ConfigMediaType is the configuration media type for
  64. // schema2 manifests.
  65. ConfigMediaType string
  66. // LayerStores manages layers.
  67. LayerStores PushLayerProvider
  68. // UploadManager dispatches uploads.
  69. UploadManager *xfer.LayerUploadManager
  70. }
  71. // RegistryResolver is used for TLS configuration and endpoint lookup.
  72. type RegistryResolver interface {
  73. LookupPushEndpoints(hostname string) (endpoints []registrypkg.APIEndpoint, err error)
  74. LookupPullEndpoints(hostname string) (endpoints []registrypkg.APIEndpoint, err error)
  75. ResolveRepository(name reference.Named) (*registrypkg.RepositoryInfo, error)
  76. }
  77. // ImageConfigStore handles storing and getting image configurations
  78. // by digest. Allows getting an image configurations rootfs from the
  79. // configuration.
  80. type ImageConfigStore interface {
  81. Put(context.Context, []byte) (digest.Digest, error)
  82. Get(context.Context, digest.Digest) ([]byte, error)
  83. }
  84. // PushLayerProvider provides layers to be pushed by ChainID.
  85. type PushLayerProvider interface {
  86. Get(layer.ChainID) (PushLayer, error)
  87. }
  88. // PushLayer is a pushable layer with metadata about the layer
  89. // and access to the content of the layer.
  90. type PushLayer interface {
  91. ChainID() layer.ChainID
  92. DiffID() layer.DiffID
  93. Parent() PushLayer
  94. Open() (io.ReadCloser, error)
  95. Size() int64
  96. MediaType() string
  97. Release()
  98. }
  99. type imageConfigStore struct {
  100. image.Store
  101. }
  102. // NewImageConfigStoreFromStore returns an ImageConfigStore backed
  103. // by an image.Store for container images.
  104. func NewImageConfigStoreFromStore(is image.Store) ImageConfigStore {
  105. return &imageConfigStore{
  106. Store: is,
  107. }
  108. }
  109. func (s *imageConfigStore) Put(_ context.Context, c []byte) (digest.Digest, error) {
  110. id, err := s.Store.Create(c)
  111. return digest.Digest(id), err
  112. }
  113. func (s *imageConfigStore) Get(_ context.Context, d digest.Digest) ([]byte, error) {
  114. img, err := s.Store.Get(image.ID(d))
  115. if err != nil {
  116. return nil, err
  117. }
  118. return img.RawJSON(), nil
  119. }
  120. func rootFSFromConfig(c []byte) (*image.RootFS, error) {
  121. var unmarshalledConfig image.Image
  122. if err := json.Unmarshal(c, &unmarshalledConfig); err != nil {
  123. return nil, err
  124. }
  125. return unmarshalledConfig.RootFS, nil
  126. }
  127. func platformFromConfig(c []byte) (*ocispec.Platform, error) {
  128. var unmarshalledConfig image.Image
  129. if err := json.Unmarshal(c, &unmarshalledConfig); err != nil {
  130. return nil, err
  131. }
  132. os := unmarshalledConfig.OS
  133. if os == "" {
  134. os = runtime.GOOS
  135. }
  136. if err := image.CheckOS(os); err != nil {
  137. return nil, errors.Wrapf(err, "image operating system %q cannot be used on this platform", os)
  138. }
  139. return &ocispec.Platform{
  140. OS: os,
  141. Architecture: unmarshalledConfig.Architecture,
  142. Variant: unmarshalledConfig.Variant,
  143. OSVersion: unmarshalledConfig.OSVersion,
  144. }, nil
  145. }
  146. type storeLayerProvider struct {
  147. ls layer.Store
  148. }
  149. // NewLayerProvidersFromStore returns layer providers backed by
  150. // an instance of LayerStore. Only getting layers as gzipped
  151. // tars is supported.
  152. func NewLayerProvidersFromStore(ls layer.Store) PushLayerProvider {
  153. return &storeLayerProvider{ls: ls}
  154. }
  155. func (p *storeLayerProvider) Get(lid layer.ChainID) (PushLayer, error) {
  156. if lid == "" {
  157. return &storeLayer{
  158. Layer: layer.EmptyLayer,
  159. }, nil
  160. }
  161. l, err := p.ls.Get(lid)
  162. if err != nil {
  163. return nil, err
  164. }
  165. sl := storeLayer{
  166. Layer: l,
  167. ls: p.ls,
  168. }
  169. if d, ok := l.(distribution.Describable); ok {
  170. return &describableStoreLayer{
  171. storeLayer: sl,
  172. describable: d,
  173. }, nil
  174. }
  175. return &sl, nil
  176. }
  177. type storeLayer struct {
  178. layer.Layer
  179. ls layer.Store
  180. }
  181. func (l *storeLayer) Parent() PushLayer {
  182. p := l.Layer.Parent()
  183. if p == nil {
  184. return nil
  185. }
  186. sl := storeLayer{
  187. Layer: p,
  188. ls: l.ls,
  189. }
  190. if d, ok := p.(distribution.Describable); ok {
  191. return &describableStoreLayer{
  192. storeLayer: sl,
  193. describable: d,
  194. }
  195. }
  196. return &sl
  197. }
  198. func (l *storeLayer) Open() (io.ReadCloser, error) {
  199. return l.Layer.TarStream()
  200. }
  201. func (l *storeLayer) Size() int64 {
  202. return l.Layer.DiffSize()
  203. }
  204. func (l *storeLayer) MediaType() string {
  205. // layer store always returns uncompressed tars
  206. return schema2.MediaTypeUncompressedLayer
  207. }
  208. func (l *storeLayer) Release() {
  209. if l.ls != nil {
  210. layer.ReleaseAndLog(l.ls, l.Layer)
  211. }
  212. }
  213. type describableStoreLayer struct {
  214. storeLayer
  215. describable distribution.Describable
  216. }
  217. func (l *describableStoreLayer) Descriptor() distribution.Descriptor {
  218. return l.describable.Descriptor()
  219. }