123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- package distribution // import "github.com/docker/docker/distribution"
- import (
- "context"
- "encoding/json"
- "io"
- "runtime"
- "github.com/distribution/reference"
- "github.com/docker/distribution"
- "github.com/docker/distribution/manifest/schema2"
- "github.com/docker/docker/api/types/events"
- "github.com/docker/docker/api/types/registry"
- "github.com/docker/docker/distribution/metadata"
- "github.com/docker/docker/distribution/xfer"
- "github.com/docker/docker/image"
- "github.com/docker/docker/layer"
- "github.com/docker/docker/pkg/progress"
- refstore "github.com/docker/docker/reference"
- registrypkg "github.com/docker/docker/registry"
- "github.com/opencontainers/go-digest"
- ocispec "github.com/opencontainers/image-spec/specs-go/v1"
- "github.com/pkg/errors"
- )
- // Config stores configuration for communicating
- // with a registry.
- type Config struct {
- // MetaHeaders stores HTTP headers with metadata about the image
- MetaHeaders map[string][]string
- // AuthConfig holds authentication credentials for authenticating with
- // the registry.
- AuthConfig *registry.AuthConfig
- // ProgressOutput is the interface for showing the status of the pull
- // operation.
- ProgressOutput progress.Output
- // RegistryService is the registry service to use for TLS configuration
- // and endpoint lookup.
- RegistryService RegistryResolver
- // ImageEventLogger notifies events for a given image
- ImageEventLogger func(id, name string, action events.Action)
- // MetadataStore is the storage backend for distribution-specific
- // metadata.
- MetadataStore metadata.Store
- // ImageStore manages images.
- ImageStore ImageConfigStore
- // ReferenceStore manages tags. This value is optional, when excluded
- // content will not be tagged.
- ReferenceStore refstore.Store
- }
- // ImagePullConfig stores pull configuration.
- type ImagePullConfig struct {
- Config
- // DownloadManager manages concurrent pulls.
- DownloadManager *xfer.LayerDownloadManager
- // Schema2Types is an optional list of valid schema2 configuration types
- // allowed by the pull operation. If omitted, the default list of accepted
- // types is used.
- Schema2Types []string
- // Platform is the requested platform of the image being pulled
- Platform *ocispec.Platform
- }
- // ImagePushConfig stores push configuration.
- type ImagePushConfig struct {
- Config
- // ConfigMediaType is the configuration media type for
- // schema2 manifests.
- ConfigMediaType string
- // LayerStores manages layers.
- LayerStores PushLayerProvider
- // UploadManager dispatches uploads.
- UploadManager *xfer.LayerUploadManager
- }
- // RegistryResolver is used for TLS configuration and endpoint lookup.
- type RegistryResolver interface {
- LookupPushEndpoints(hostname string) (endpoints []registrypkg.APIEndpoint, err error)
- LookupPullEndpoints(hostname string) (endpoints []registrypkg.APIEndpoint, err error)
- ResolveRepository(name reference.Named) (*registrypkg.RepositoryInfo, error)
- }
- // ImageConfigStore handles storing and getting image configurations
- // by digest. Allows getting an image configurations rootfs from the
- // configuration.
- type ImageConfigStore interface {
- Put(context.Context, []byte) (digest.Digest, error)
- Get(context.Context, digest.Digest) ([]byte, error)
- }
- // PushLayerProvider provides layers to be pushed by ChainID.
- type PushLayerProvider interface {
- Get(layer.ChainID) (PushLayer, error)
- }
- // PushLayer is a pushable layer with metadata about the layer
- // and access to the content of the layer.
- type PushLayer interface {
- ChainID() layer.ChainID
- DiffID() layer.DiffID
- Parent() PushLayer
- Open() (io.ReadCloser, error)
- Size() int64
- MediaType() string
- Release()
- }
- type imageConfigStore struct {
- image.Store
- }
- // NewImageConfigStoreFromStore returns an ImageConfigStore backed
- // by an image.Store for container images.
- func NewImageConfigStoreFromStore(is image.Store) ImageConfigStore {
- return &imageConfigStore{
- Store: is,
- }
- }
- func (s *imageConfigStore) Put(_ context.Context, c []byte) (digest.Digest, error) {
- id, err := s.Store.Create(c)
- return digest.Digest(id), err
- }
- func (s *imageConfigStore) Get(_ context.Context, d digest.Digest) ([]byte, error) {
- img, err := s.Store.Get(image.ID(d))
- if err != nil {
- return nil, err
- }
- return img.RawJSON(), nil
- }
- func rootFSFromConfig(c []byte) (*image.RootFS, error) {
- var unmarshalledConfig image.Image
- if err := json.Unmarshal(c, &unmarshalledConfig); err != nil {
- return nil, err
- }
- return unmarshalledConfig.RootFS, nil
- }
- func platformFromConfig(c []byte) (*ocispec.Platform, error) {
- var unmarshalledConfig image.Image
- if err := json.Unmarshal(c, &unmarshalledConfig); err != nil {
- return nil, err
- }
- os := unmarshalledConfig.OS
- if os == "" {
- os = runtime.GOOS
- }
- if err := image.CheckOS(os); err != nil {
- return nil, errors.Wrapf(err, "image operating system %q cannot be used on this platform", os)
- }
- return &ocispec.Platform{
- OS: os,
- Architecture: unmarshalledConfig.Architecture,
- Variant: unmarshalledConfig.Variant,
- OSVersion: unmarshalledConfig.OSVersion,
- }, nil
- }
- type storeLayerProvider struct {
- ls layer.Store
- }
- // NewLayerProvidersFromStore returns layer providers backed by
- // an instance of LayerStore. Only getting layers as gzipped
- // tars is supported.
- func NewLayerProvidersFromStore(ls layer.Store) PushLayerProvider {
- return &storeLayerProvider{ls: ls}
- }
- func (p *storeLayerProvider) Get(lid layer.ChainID) (PushLayer, error) {
- if lid == "" {
- return &storeLayer{
- Layer: layer.EmptyLayer,
- }, nil
- }
- l, err := p.ls.Get(lid)
- if err != nil {
- return nil, err
- }
- sl := storeLayer{
- Layer: l,
- ls: p.ls,
- }
- if d, ok := l.(distribution.Describable); ok {
- return &describableStoreLayer{
- storeLayer: sl,
- describable: d,
- }, nil
- }
- return &sl, nil
- }
- type storeLayer struct {
- layer.Layer
- ls layer.Store
- }
- func (l *storeLayer) Parent() PushLayer {
- p := l.Layer.Parent()
- if p == nil {
- return nil
- }
- sl := storeLayer{
- Layer: p,
- ls: l.ls,
- }
- if d, ok := p.(distribution.Describable); ok {
- return &describableStoreLayer{
- storeLayer: sl,
- describable: d,
- }
- }
- return &sl
- }
- func (l *storeLayer) Open() (io.ReadCloser, error) {
- return l.Layer.TarStream()
- }
- func (l *storeLayer) Size() int64 {
- return l.Layer.DiffSize()
- }
- func (l *storeLayer) MediaType() string {
- // layer store always returns uncompressed tars
- return schema2.MediaTypeUncompressedLayer
- }
- func (l *storeLayer) Release() {
- if l.ls != nil {
- layer.ReleaseAndLog(l.ls, l.Layer)
- }
- }
- type describableStoreLayer struct {
- storeLayer
- describable distribution.Describable
- }
- func (l *describableStoreLayer) Descriptor() distribution.Descriptor {
- return l.describable.Descriptor()
- }
|