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