github.com/dpiddy/docker@v1.12.2-rc1/layer/layer_store.go (about)

     1  package layer
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"sync"
     9  
    10  	"github.com/Sirupsen/logrus"
    11  	"github.com/docker/distribution"
    12  	"github.com/docker/distribution/digest"
    13  	"github.com/docker/docker/daemon/graphdriver"
    14  	"github.com/docker/docker/pkg/archive"
    15  	"github.com/docker/docker/pkg/idtools"
    16  	"github.com/docker/docker/pkg/stringid"
    17  	"github.com/vbatts/tar-split/tar/asm"
    18  	"github.com/vbatts/tar-split/tar/storage"
    19  )
    20  
    21  // maxLayerDepth represents the maximum number of
    22  // layers which can be chained together. 125 was
    23  // chosen to account for the 127 max in some
    24  // graphdrivers plus the 2 additional layers
    25  // used to create a rwlayer.
    26  const maxLayerDepth = 125
    27  
    28  type layerStore struct {
    29  	store  MetadataStore
    30  	driver graphdriver.Driver
    31  
    32  	layerMap map[ChainID]*roLayer
    33  	layerL   sync.Mutex
    34  
    35  	mounts map[string]*mountedLayer
    36  	mountL sync.Mutex
    37  }
    38  
    39  // StoreOptions are the options used to create a new Store instance
    40  type StoreOptions struct {
    41  	StorePath                 string
    42  	MetadataStorePathTemplate string
    43  	GraphDriver               string
    44  	GraphDriverOptions        []string
    45  	UIDMaps                   []idtools.IDMap
    46  	GIDMaps                   []idtools.IDMap
    47  }
    48  
    49  // NewStoreFromOptions creates a new Store instance
    50  func NewStoreFromOptions(options StoreOptions) (Store, error) {
    51  	driver, err := graphdriver.New(
    52  		options.StorePath,
    53  		options.GraphDriver,
    54  		options.GraphDriverOptions,
    55  		options.UIDMaps,
    56  		options.GIDMaps)
    57  	if err != nil {
    58  		return nil, fmt.Errorf("error initializing graphdriver: %v", err)
    59  	}
    60  	logrus.Debugf("Using graph driver %s", driver)
    61  
    62  	fms, err := NewFSMetadataStore(fmt.Sprintf(options.MetadataStorePathTemplate, driver))
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	return NewStoreFromGraphDriver(fms, driver)
    68  }
    69  
    70  // NewStoreFromGraphDriver creates a new Store instance using the provided
    71  // metadata store and graph driver. The metadata store will be used to restore
    72  // the Store.
    73  func NewStoreFromGraphDriver(store MetadataStore, driver graphdriver.Driver) (Store, error) {
    74  	ls := &layerStore{
    75  		store:    store,
    76  		driver:   driver,
    77  		layerMap: map[ChainID]*roLayer{},
    78  		mounts:   map[string]*mountedLayer{},
    79  	}
    80  
    81  	ids, mounts, err := store.List()
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  
    86  	for _, id := range ids {
    87  		l, err := ls.loadLayer(id)
    88  		if err != nil {
    89  			logrus.Debugf("Failed to load layer %s: %s", id, err)
    90  			continue
    91  		}
    92  		if l.parent != nil {
    93  			l.parent.referenceCount++
    94  		}
    95  	}
    96  
    97  	for _, mount := range mounts {
    98  		if err := ls.loadMount(mount); err != nil {
    99  			logrus.Debugf("Failed to load mount %s: %s", mount, err)
   100  		}
   101  	}
   102  
   103  	return ls, nil
   104  }
   105  
   106  func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) {
   107  	cl, ok := ls.layerMap[layer]
   108  	if ok {
   109  		return cl, nil
   110  	}
   111  
   112  	diff, err := ls.store.GetDiffID(layer)
   113  	if err != nil {
   114  		return nil, fmt.Errorf("failed to get diff id for %s: %s", layer, err)
   115  	}
   116  
   117  	size, err := ls.store.GetSize(layer)
   118  	if err != nil {
   119  		return nil, fmt.Errorf("failed to get size for %s: %s", layer, err)
   120  	}
   121  
   122  	cacheID, err := ls.store.GetCacheID(layer)
   123  	if err != nil {
   124  		return nil, fmt.Errorf("failed to get cache id for %s: %s", layer, err)
   125  	}
   126  
   127  	parent, err := ls.store.GetParent(layer)
   128  	if err != nil {
   129  		return nil, fmt.Errorf("failed to get parent for %s: %s", layer, err)
   130  	}
   131  
   132  	descriptor, err := ls.store.GetDescriptor(layer)
   133  	if err != nil {
   134  		return nil, fmt.Errorf("failed to get descriptor for %s: %s", layer, err)
   135  	}
   136  
   137  	cl = &roLayer{
   138  		chainID:    layer,
   139  		diffID:     diff,
   140  		size:       size,
   141  		cacheID:    cacheID,
   142  		layerStore: ls,
   143  		references: map[Layer]struct{}{},
   144  		descriptor: descriptor,
   145  	}
   146  
   147  	if parent != "" {
   148  		p, err := ls.loadLayer(parent)
   149  		if err != nil {
   150  			return nil, err
   151  		}
   152  		cl.parent = p
   153  	}
   154  
   155  	ls.layerMap[cl.chainID] = cl
   156  
   157  	return cl, nil
   158  }
   159  
   160  func (ls *layerStore) loadMount(mount string) error {
   161  	if _, ok := ls.mounts[mount]; ok {
   162  		return nil
   163  	}
   164  
   165  	mountID, err := ls.store.GetMountID(mount)
   166  	if err != nil {
   167  		return err
   168  	}
   169  
   170  	initID, err := ls.store.GetInitID(mount)
   171  	if err != nil {
   172  		return err
   173  	}
   174  
   175  	parent, err := ls.store.GetMountParent(mount)
   176  	if err != nil {
   177  		return err
   178  	}
   179  
   180  	ml := &mountedLayer{
   181  		name:       mount,
   182  		mountID:    mountID,
   183  		initID:     initID,
   184  		layerStore: ls,
   185  		references: map[RWLayer]*referencedRWLayer{},
   186  	}
   187  
   188  	if parent != "" {
   189  		p, err := ls.loadLayer(parent)
   190  		if err != nil {
   191  			return err
   192  		}
   193  		ml.parent = p
   194  
   195  		p.referenceCount++
   196  	}
   197  
   198  	ls.mounts[ml.name] = ml
   199  
   200  	return nil
   201  }
   202  
   203  func (ls *layerStore) applyTar(tx MetadataTransaction, ts io.Reader, parent string, layer *roLayer) error {
   204  	digester := digest.Canonical.New()
   205  	tr := io.TeeReader(ts, digester.Hash())
   206  
   207  	tsw, err := tx.TarSplitWriter(true)
   208  	if err != nil {
   209  		return err
   210  	}
   211  	metaPacker := storage.NewJSONPacker(tsw)
   212  	defer tsw.Close()
   213  
   214  	// we're passing nil here for the file putter, because the ApplyDiff will
   215  	// handle the extraction of the archive
   216  	rdr, err := asm.NewInputTarStream(tr, metaPacker, nil)
   217  	if err != nil {
   218  		return err
   219  	}
   220  
   221  	applySize, err := ls.driver.ApplyDiff(layer.cacheID, parent, archive.Reader(rdr))
   222  	if err != nil {
   223  		return err
   224  	}
   225  
   226  	// Discard trailing data but ensure metadata is picked up to reconstruct stream
   227  	io.Copy(ioutil.Discard, rdr) // ignore error as reader may be closed
   228  
   229  	layer.size = applySize
   230  	layer.diffID = DiffID(digester.Digest())
   231  
   232  	logrus.Debugf("Applied tar %s to %s, size: %d", layer.diffID, layer.cacheID, applySize)
   233  
   234  	return nil
   235  }
   236  
   237  func (ls *layerStore) Register(ts io.Reader, parent ChainID) (Layer, error) {
   238  	return ls.registerWithDescriptor(ts, parent, distribution.Descriptor{})
   239  }
   240  
   241  func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, descriptor distribution.Descriptor) (Layer, error) {
   242  	// err is used to hold the error which will always trigger
   243  	// cleanup of creates sources but may not be an error returned
   244  	// to the caller (already exists).
   245  	var err error
   246  	var pid string
   247  	var p *roLayer
   248  	if string(parent) != "" {
   249  		p = ls.get(parent)
   250  		if p == nil {
   251  			return nil, ErrLayerDoesNotExist
   252  		}
   253  		pid = p.cacheID
   254  		// Release parent chain if error
   255  		defer func() {
   256  			if err != nil {
   257  				ls.layerL.Lock()
   258  				ls.releaseLayer(p)
   259  				ls.layerL.Unlock()
   260  			}
   261  		}()
   262  		if p.depth() >= maxLayerDepth {
   263  			err = ErrMaxDepthExceeded
   264  			return nil, err
   265  		}
   266  	}
   267  
   268  	// Create new roLayer
   269  	layer := &roLayer{
   270  		parent:         p,
   271  		cacheID:        stringid.GenerateRandomID(),
   272  		referenceCount: 1,
   273  		layerStore:     ls,
   274  		references:     map[Layer]struct{}{},
   275  		descriptor:     descriptor,
   276  	}
   277  
   278  	if err = ls.driver.Create(layer.cacheID, pid, "", nil); err != nil {
   279  		return nil, err
   280  	}
   281  
   282  	tx, err := ls.store.StartTransaction()
   283  	if err != nil {
   284  		return nil, err
   285  	}
   286  
   287  	defer func() {
   288  		if err != nil {
   289  			logrus.Debugf("Cleaning up layer %s: %v", layer.cacheID, err)
   290  			if err := ls.driver.Remove(layer.cacheID); err != nil {
   291  				logrus.Errorf("Error cleaning up cache layer %s: %v", layer.cacheID, err)
   292  			}
   293  			if err := tx.Cancel(); err != nil {
   294  				logrus.Errorf("Error canceling metadata transaction %q: %s", tx.String(), err)
   295  			}
   296  		}
   297  	}()
   298  
   299  	if err = ls.applyTar(tx, ts, pid, layer); err != nil {
   300  		return nil, err
   301  	}
   302  
   303  	if layer.parent == nil {
   304  		layer.chainID = ChainID(layer.diffID)
   305  	} else {
   306  		layer.chainID = createChainIDFromParent(layer.parent.chainID, layer.diffID)
   307  	}
   308  
   309  	if err = storeLayer(tx, layer); err != nil {
   310  		return nil, err
   311  	}
   312  
   313  	ls.layerL.Lock()
   314  	defer ls.layerL.Unlock()
   315  
   316  	if existingLayer := ls.getWithoutLock(layer.chainID); existingLayer != nil {
   317  		// Set error for cleanup, but do not return the error
   318  		err = errors.New("layer already exists")
   319  		return existingLayer.getReference(), nil
   320  	}
   321  
   322  	if err = tx.Commit(layer.chainID); err != nil {
   323  		return nil, err
   324  	}
   325  
   326  	ls.layerMap[layer.chainID] = layer
   327  
   328  	return layer.getReference(), nil
   329  }
   330  
   331  func (ls *layerStore) getWithoutLock(layer ChainID) *roLayer {
   332  	l, ok := ls.layerMap[layer]
   333  	if !ok {
   334  		return nil
   335  	}
   336  
   337  	l.referenceCount++
   338  
   339  	return l
   340  }
   341  
   342  func (ls *layerStore) get(l ChainID) *roLayer {
   343  	ls.layerL.Lock()
   344  	defer ls.layerL.Unlock()
   345  	return ls.getWithoutLock(l)
   346  }
   347  
   348  func (ls *layerStore) Get(l ChainID) (Layer, error) {
   349  	ls.layerL.Lock()
   350  	defer ls.layerL.Unlock()
   351  
   352  	layer := ls.getWithoutLock(l)
   353  	if layer == nil {
   354  		return nil, ErrLayerDoesNotExist
   355  	}
   356  
   357  	return layer.getReference(), nil
   358  }
   359  
   360  func (ls *layerStore) deleteLayer(layer *roLayer, metadata *Metadata) error {
   361  	err := ls.driver.Remove(layer.cacheID)
   362  	if err != nil {
   363  		return err
   364  	}
   365  
   366  	err = ls.store.Remove(layer.chainID)
   367  	if err != nil {
   368  		return err
   369  	}
   370  	metadata.DiffID = layer.diffID
   371  	metadata.ChainID = layer.chainID
   372  	metadata.Size, err = layer.Size()
   373  	if err != nil {
   374  		return err
   375  	}
   376  	metadata.DiffSize = layer.size
   377  
   378  	return nil
   379  }
   380  
   381  func (ls *layerStore) releaseLayer(l *roLayer) ([]Metadata, error) {
   382  	depth := 0
   383  	removed := []Metadata{}
   384  	for {
   385  		if l.referenceCount == 0 {
   386  			panic("layer not retained")
   387  		}
   388  		l.referenceCount--
   389  		if l.referenceCount != 0 {
   390  			return removed, nil
   391  		}
   392  
   393  		if len(removed) == 0 && depth > 0 {
   394  			panic("cannot remove layer with child")
   395  		}
   396  		if l.hasReferences() {
   397  			panic("cannot delete referenced layer")
   398  		}
   399  		var metadata Metadata
   400  		if err := ls.deleteLayer(l, &metadata); err != nil {
   401  			return nil, err
   402  		}
   403  
   404  		delete(ls.layerMap, l.chainID)
   405  		removed = append(removed, metadata)
   406  
   407  		if l.parent == nil {
   408  			return removed, nil
   409  		}
   410  
   411  		depth++
   412  		l = l.parent
   413  	}
   414  }
   415  
   416  func (ls *layerStore) Release(l Layer) ([]Metadata, error) {
   417  	ls.layerL.Lock()
   418  	defer ls.layerL.Unlock()
   419  	layer, ok := ls.layerMap[l.ChainID()]
   420  	if !ok {
   421  		return []Metadata{}, nil
   422  	}
   423  	if !layer.hasReference(l) {
   424  		return nil, ErrLayerNotRetained
   425  	}
   426  
   427  	layer.deleteReference(l)
   428  
   429  	return ls.releaseLayer(layer)
   430  }
   431  
   432  func (ls *layerStore) CreateRWLayer(name string, parent ChainID, mountLabel string, initFunc MountInit, storageOpt map[string]string) (RWLayer, error) {
   433  	ls.mountL.Lock()
   434  	defer ls.mountL.Unlock()
   435  	m, ok := ls.mounts[name]
   436  	if ok {
   437  		return nil, ErrMountNameConflict
   438  	}
   439  
   440  	var err error
   441  	var pid string
   442  	var p *roLayer
   443  	if string(parent) != "" {
   444  		p = ls.get(parent)
   445  		if p == nil {
   446  			return nil, ErrLayerDoesNotExist
   447  		}
   448  		pid = p.cacheID
   449  
   450  		// Release parent chain if error
   451  		defer func() {
   452  			if err != nil {
   453  				ls.layerL.Lock()
   454  				ls.releaseLayer(p)
   455  				ls.layerL.Unlock()
   456  			}
   457  		}()
   458  	}
   459  
   460  	m = &mountedLayer{
   461  		name:       name,
   462  		parent:     p,
   463  		mountID:    ls.mountID(name),
   464  		layerStore: ls,
   465  		references: map[RWLayer]*referencedRWLayer{},
   466  	}
   467  
   468  	if initFunc != nil {
   469  		pid, err = ls.initMount(m.mountID, pid, mountLabel, initFunc, storageOpt)
   470  		if err != nil {
   471  			return nil, err
   472  		}
   473  		m.initID = pid
   474  	}
   475  
   476  	if err = ls.driver.CreateReadWrite(m.mountID, pid, "", storageOpt); err != nil {
   477  		return nil, err
   478  	}
   479  
   480  	if err = ls.saveMount(m); err != nil {
   481  		return nil, err
   482  	}
   483  
   484  	return m.getReference(), nil
   485  }
   486  
   487  func (ls *layerStore) GetRWLayer(id string) (RWLayer, error) {
   488  	ls.mountL.Lock()
   489  	defer ls.mountL.Unlock()
   490  	mount, ok := ls.mounts[id]
   491  	if !ok {
   492  		return nil, ErrMountDoesNotExist
   493  	}
   494  
   495  	return mount.getReference(), nil
   496  }
   497  
   498  func (ls *layerStore) GetMountID(id string) (string, error) {
   499  	ls.mountL.Lock()
   500  	defer ls.mountL.Unlock()
   501  	mount, ok := ls.mounts[id]
   502  	if !ok {
   503  		return "", ErrMountDoesNotExist
   504  	}
   505  	logrus.Debugf("GetMountID id: %s -> mountID: %s", id, mount.mountID)
   506  
   507  	return mount.mountID, nil
   508  }
   509  
   510  func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) {
   511  	ls.mountL.Lock()
   512  	defer ls.mountL.Unlock()
   513  	m, ok := ls.mounts[l.Name()]
   514  	if !ok {
   515  		return []Metadata{}, nil
   516  	}
   517  
   518  	if err := m.deleteReference(l); err != nil {
   519  		return nil, err
   520  	}
   521  
   522  	if m.hasReferences() {
   523  		return []Metadata{}, nil
   524  	}
   525  
   526  	if err := ls.driver.Remove(m.mountID); err != nil {
   527  		logrus.Errorf("Error removing mounted layer %s: %s", m.name, err)
   528  		m.retakeReference(l)
   529  		return nil, err
   530  	}
   531  
   532  	if m.initID != "" {
   533  		if err := ls.driver.Remove(m.initID); err != nil {
   534  			logrus.Errorf("Error removing init layer %s: %s", m.name, err)
   535  			m.retakeReference(l)
   536  			return nil, err
   537  		}
   538  	}
   539  
   540  	if err := ls.store.RemoveMount(m.name); err != nil {
   541  		logrus.Errorf("Error removing mount metadata: %s: %s", m.name, err)
   542  		m.retakeReference(l)
   543  		return nil, err
   544  	}
   545  
   546  	delete(ls.mounts, m.Name())
   547  
   548  	ls.layerL.Lock()
   549  	defer ls.layerL.Unlock()
   550  	if m.parent != nil {
   551  		return ls.releaseLayer(m.parent)
   552  	}
   553  
   554  	return []Metadata{}, nil
   555  }
   556  
   557  func (ls *layerStore) saveMount(mount *mountedLayer) error {
   558  	if err := ls.store.SetMountID(mount.name, mount.mountID); err != nil {
   559  		return err
   560  	}
   561  
   562  	if mount.initID != "" {
   563  		if err := ls.store.SetInitID(mount.name, mount.initID); err != nil {
   564  			return err
   565  		}
   566  	}
   567  
   568  	if mount.parent != nil {
   569  		if err := ls.store.SetMountParent(mount.name, mount.parent.chainID); err != nil {
   570  			return err
   571  		}
   572  	}
   573  
   574  	ls.mounts[mount.name] = mount
   575  
   576  	return nil
   577  }
   578  
   579  func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (string, error) {
   580  	// Use "<graph-id>-init" to maintain compatibility with graph drivers
   581  	// which are expecting this layer with this special name. If all
   582  	// graph drivers can be updated to not rely on knowing about this layer
   583  	// then the initID should be randomly generated.
   584  	initID := fmt.Sprintf("%s-init", graphID)
   585  
   586  	if err := ls.driver.Create(initID, parent, mountLabel, storageOpt); err != nil {
   587  		return "", err
   588  	}
   589  	p, err := ls.driver.Get(initID, "")
   590  	if err != nil {
   591  		return "", err
   592  	}
   593  
   594  	if err := initFunc(p); err != nil {
   595  		ls.driver.Put(initID)
   596  		return "", err
   597  	}
   598  
   599  	if err := ls.driver.Put(initID); err != nil {
   600  		return "", err
   601  	}
   602  
   603  	return initID, nil
   604  }
   605  
   606  func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size *int64, w io.Writer) error {
   607  	diffDriver, ok := ls.driver.(graphdriver.DiffGetterDriver)
   608  	if !ok {
   609  		diffDriver = &naiveDiffPathDriver{ls.driver}
   610  	}
   611  
   612  	defer metadata.Close()
   613  
   614  	// get our relative path to the container
   615  	fileGetCloser, err := diffDriver.DiffGetter(graphID)
   616  	if err != nil {
   617  		return err
   618  	}
   619  	defer fileGetCloser.Close()
   620  
   621  	metaUnpacker := storage.NewJSONUnpacker(metadata)
   622  	upackerCounter := &unpackSizeCounter{metaUnpacker, size}
   623  	logrus.Debugf("Assembling tar data for %s", graphID)
   624  	return asm.WriteOutputTarStream(fileGetCloser, upackerCounter, w)
   625  }
   626  
   627  func (ls *layerStore) Cleanup() error {
   628  	return ls.driver.Cleanup()
   629  }
   630  
   631  func (ls *layerStore) DriverStatus() [][2]string {
   632  	return ls.driver.Status()
   633  }
   634  
   635  func (ls *layerStore) DriverName() string {
   636  	return ls.driver.String()
   637  }
   638  
   639  type naiveDiffPathDriver struct {
   640  	graphdriver.Driver
   641  }
   642  
   643  type fileGetPutter struct {
   644  	storage.FileGetter
   645  	driver graphdriver.Driver
   646  	id     string
   647  }
   648  
   649  func (w *fileGetPutter) Close() error {
   650  	return w.driver.Put(w.id)
   651  }
   652  
   653  func (n *naiveDiffPathDriver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
   654  	p, err := n.Driver.Get(id, "")
   655  	if err != nil {
   656  		return nil, err
   657  	}
   658  	return &fileGetPutter{storage.NewPathFileGetter(p), n.Driver, id}, nil
   659  }