package layer import ( "errors" "fmt" "github.com/Sirupsen/logrus" "github.com/docker/distribution/digest" "github.com/docker/docker/daemon/graphdriver" ) // GetLayerPath returns the path to a layer func GetLayerPath(s Store, layer ChainID) (string, error) { ls, ok := s.(*layerStore) if !ok { return "", errors.New("unsupported layer store") } ls.layerL.Lock() defer ls.layerL.Unlock() rl, ok := ls.layerMap[layer] if !ok { return "", ErrLayerDoesNotExist } path, err := ls.driver.Get(rl.cacheID, "") if err != nil { return "", err } if err := ls.driver.Put(rl.cacheID); err != nil { return "", err } return path, nil } func (ls *layerStore) RegisterDiffID(graphID string, size int64) (Layer, error) { var err error // this is used for cleanup in existingLayer case diffID := digest.FromBytes([]byte(graphID)) // Create new roLayer layer := &roLayer{ cacheID: graphID, diffID: DiffID(diffID), referenceCount: 1, layerStore: ls, references: map[Layer]struct{}{}, size: size, } tx, err := ls.store.StartTransaction() if err != nil { return nil, err } defer func() { if err != nil { if err := tx.Cancel(); err != nil { logrus.Errorf("Error canceling metadata transaction %q: %s", tx.String(), err) } } }() layer.chainID = createChainIDFromParent("", layer.diffID) if !ls.driver.Exists(layer.cacheID) { return nil, fmt.Errorf("layer %q is unknown to driver", layer.cacheID) } if err = storeLayer(tx, layer); err != nil { return nil, err } ls.layerL.Lock() defer ls.layerL.Unlock() if existingLayer := ls.getWithoutLock(layer.chainID); existingLayer != nil { // Set error for cleanup, but do not return err = errors.New("layer already exists") return existingLayer.getReference(), nil } if err = tx.Commit(layer.chainID); err != nil { return nil, err } ls.layerMap[layer.chainID] = layer return layer.getReference(), nil } func (ls *layerStore) mountID(name string) string { // windows has issues if container ID doesn't match mount ID return name } func (ls *layerStore) GraphDriver() graphdriver.Driver { return ls.driver }