config.go 6.4 KB

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