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  }