config.go 6.9 KB

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