mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
d04fa49a0d
RWLayer will now have more operations and be protected through a referenced type rather than always looked up by string in the layer store. Separates creation of RWLayer (write capture layer) from mounting of the layer. This allows mount labels to be applied after creation and allowing RWLayer objects to have the same lifespan as a container without performance regressions from requiring mount. Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
96 lines
2 KiB
Go
96 lines
2 KiB
Go
package layer
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
"github.com/docker/distribution/digest"
|
|
)
|
|
|
|
// 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()
|
|
|
|
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
|
|
}
|