github.com/olljanat/moby@v1.13.1/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/digest"
    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/reference"
    19  	"github.com/docker/docker/registry"
    20  	"github.com/docker/libtrust"
    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 reference.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
   146  	if runtime.GOOS == "windows" && unmarshalledConfig.OS == "linux" {
   147  		return nil, fmt.Errorf("image operating system %q cannot be used on this platform", unmarshalledConfig.OS)
   148  	}
   149  
   150  	return unmarshalledConfig.RootFS, nil
   151  }
   152  
   153  type storeLayerProvider struct {
   154  	ls layer.Store
   155  }
   156  
   157  // NewLayerProviderFromStore returns a layer provider backed by
   158  // an instance of LayerStore. Only getting layers as gzipped
   159  // tars is supported.
   160  func NewLayerProviderFromStore(ls layer.Store) PushLayerProvider {
   161  	return &storeLayerProvider{
   162  		ls: ls,
   163  	}
   164  }
   165  
   166  func (p *storeLayerProvider) Get(lid layer.ChainID) (PushLayer, error) {
   167  	if lid == "" {
   168  		return &storeLayer{
   169  			Layer: layer.EmptyLayer,
   170  		}, nil
   171  	}
   172  	l, err := p.ls.Get(lid)
   173  	if err != nil {
   174  		return nil, err
   175  	}
   176  
   177  	sl := storeLayer{
   178  		Layer: l,
   179  		ls:    p.ls,
   180  	}
   181  	if d, ok := l.(distribution.Describable); ok {
   182  		return &describableStoreLayer{
   183  			storeLayer:  sl,
   184  			describable: d,
   185  		}, nil
   186  	}
   187  
   188  	return &sl, nil
   189  }
   190  
   191  type storeLayer struct {
   192  	layer.Layer
   193  	ls layer.Store
   194  }
   195  
   196  func (l *storeLayer) Parent() PushLayer {
   197  	p := l.Layer.Parent()
   198  	if p == nil {
   199  		return nil
   200  	}
   201  	sl := storeLayer{
   202  		Layer: p,
   203  		ls:    l.ls,
   204  	}
   205  	if d, ok := p.(distribution.Describable); ok {
   206  		return &describableStoreLayer{
   207  			storeLayer:  sl,
   208  			describable: d,
   209  		}
   210  	}
   211  
   212  	return &sl
   213  }
   214  
   215  func (l *storeLayer) Open() (io.ReadCloser, error) {
   216  	return l.Layer.TarStream()
   217  }
   218  
   219  func (l *storeLayer) Size() (int64, error) {
   220  	return l.Layer.DiffSize()
   221  }
   222  
   223  func (l *storeLayer) MediaType() string {
   224  	// layer store always returns uncompressed tars
   225  	return schema2.MediaTypeUncompressedLayer
   226  }
   227  
   228  func (l *storeLayer) Release() {
   229  	if l.ls != nil {
   230  		layer.ReleaseAndLog(l.ls, l.Layer)
   231  	}
   232  }
   233  
   234  type describableStoreLayer struct {
   235  	storeLayer
   236  	describable distribution.Describable
   237  }
   238  
   239  func (l *describableStoreLayer) Descriptor() distribution.Descriptor {
   240  	return l.describable.Descriptor()
   241  }