2015-11-18 22:15:00 +00:00
|
|
|
package layer
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
|
|
"github.com/docker/distribution/digest"
|
2015-12-16 20:32:16 +00:00
|
|
|
"github.com/docker/docker/daemon/graphdriver"
|
2015-11-18 22:15:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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, err := digest.FromBytes([]byte(graphID))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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()
|
|
|
|
|
2015-11-20 12:35:01 +00:00
|
|
|
if existingLayer := ls.getWithoutLock(layer.chainID); existingLayer != nil {
|
2015-11-18 22:15:00 +00:00
|
|
|
// 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
|
|
|
|
}
|
2015-12-16 22:13:50 +00:00
|
|
|
|
|
|
|
func (ls *layerStore) mountID(name string) string {
|
|
|
|
// windows has issues if container ID doesn't match mount ID
|
|
|
|
return name
|
|
|
|
}
|
2015-12-16 20:32:16 +00:00
|
|
|
|
|
|
|
func (ls *layerStore) GraphDriver() graphdriver.Driver {
|
|
|
|
return ls.driver
|
|
|
|
}
|