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