config.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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
  129. if runtime.GOOS == "windows" && unmarshalledConfig.OS == "linux" {
  130. return nil, fmt.Errorf("image operating system %q cannot be used on this platform", unmarshalledConfig.OS)
  131. }
  132. return unmarshalledConfig.RootFS, nil
  133. }
  134. type storeLayerProvider struct {
  135. ls layer.Store
  136. }
  137. // NewLayerProviderFromStore returns a layer provider backed by
  138. // an instance of LayerStore. Only getting layers as gzipped
  139. // tars is supported.
  140. func NewLayerProviderFromStore(ls layer.Store) PushLayerProvider {
  141. return &storeLayerProvider{
  142. ls: ls,
  143. }
  144. }
  145. func (p *storeLayerProvider) Get(lid layer.ChainID) (PushLayer, error) {
  146. if lid == "" {
  147. return &storeLayer{
  148. Layer: layer.EmptyLayer,
  149. }, nil
  150. }
  151. l, err := p.ls.Get(lid)
  152. if err != nil {
  153. return nil, err
  154. }
  155. sl := storeLayer{
  156. Layer: l,
  157. ls: p.ls,
  158. }
  159. if d, ok := l.(distribution.Describable); ok {
  160. return &describableStoreLayer{
  161. storeLayer: sl,
  162. describable: d,
  163. }, nil
  164. }
  165. return &sl, nil
  166. }
  167. type storeLayer struct {
  168. layer.Layer
  169. ls layer.Store
  170. }
  171. func (l *storeLayer) Parent() PushLayer {
  172. p := l.Layer.Parent()
  173. if p == nil {
  174. return nil
  175. }
  176. sl := storeLayer{
  177. Layer: p,
  178. ls: l.ls,
  179. }
  180. if d, ok := p.(distribution.Describable); ok {
  181. return &describableStoreLayer{
  182. storeLayer: sl,
  183. describable: d,
  184. }
  185. }
  186. return &sl
  187. }
  188. func (l *storeLayer) Open() (io.ReadCloser, error) {
  189. return l.Layer.TarStream()
  190. }
  191. func (l *storeLayer) Size() (int64, error) {
  192. return l.Layer.DiffSize()
  193. }
  194. func (l *storeLayer) MediaType() string {
  195. // layer store always returns uncompressed tars
  196. return schema2.MediaTypeUncompressedLayer
  197. }
  198. func (l *storeLayer) Release() {
  199. if l.ls != nil {
  200. layer.ReleaseAndLog(l.ls, l.Layer)
  201. }
  202. }
  203. type describableStoreLayer struct {
  204. storeLayer
  205. describable distribution.Describable
  206. }
  207. func (l *describableStoreLayer) Descriptor() distribution.Descriptor {
  208. return l.describable.Descriptor()
  209. }