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