aboutsummaryrefslogtreecommitdiff
path: root/layer
diff options
context:
space:
mode:
authorJohn Howard <jhoward@microsoft.com>2017-09-19 12:14:46 -0700
committerJohn Howard <jhoward@microsoft.com>2018-01-18 08:31:05 -0800
commitafd305c4b5682fbc297e1685e2b7a49628b7c7f0 (patch)
tree03158e6d34824d13482af4a40276291c949f5f08 /layer
parentce8e529e182bde057cdfafded62c210b7293b8ba (diff)
LCOW: Refactor to multiple layer-stores based on feedback
Signed-off-by: John Howard <jhoward@microsoft.com>
Diffstat (limited to 'layer')
-rw-r--r--layer/empty.go9
-rw-r--r--layer/layer.go11
-rw-r--r--layer/layer_store.go158
-rw-r--r--layer/layer_store_windows.go4
-rw-r--r--layer/layer_test.go32
-rw-r--r--layer/layer_unix_test.go3
-rw-r--r--layer/layer_windows.go6
-rw-r--r--layer/migration.go22
-rw-r--r--layer/migration_test.go22
-rw-r--r--layer/mount_test.go6
-rw-r--r--layer/mounted_layer.go20
-rw-r--r--layer/ro_layer.go15
-rw-r--r--layer/ro_layer_unix.go9
-rw-r--r--layer/ro_layer_windows.go7
14 files changed, 132 insertions, 192 deletions
diff --git a/layer/empty.go b/layer/empty.go
index 90cb031457..e8ae2a7457 100644
--- a/layer/empty.go
+++ b/layer/empty.go
@@ -6,7 +6,6 @@ import (
"fmt"
"io"
"io/ioutil"
- "runtime"
)
// DigestSHA256EmptyTar is the canonical sha256 digest of empty tar file -
@@ -44,6 +43,10 @@ func (el *emptyLayer) Parent() Layer {
return nil
}
+func (el *emptyLayer) OS() string {
+ return ""
+}
+
func (el *emptyLayer) Size() (size int64, err error) {
return 0, nil
}
@@ -56,10 +59,6 @@ func (el *emptyLayer) Metadata() (map[string]string, error) {
return make(map[string]string), nil
}
-func (el *emptyLayer) OS() string {
- return runtime.GOOS
-}
-
// IsEmpty returns true if the layer is an EmptyLayer
func IsEmpty(diffID DiffID) bool {
return diffID == DigestSHA256EmptyTar
diff --git a/layer/layer.go b/layer/layer.go
index cfbc7ac83a..13c194af6f 100644
--- a/layer/layer.go
+++ b/layer/layer.go
@@ -186,25 +186,26 @@ type CreateRWLayerOpts struct {
// Store represents a backend for managing both
// read-only and read-write layers.
type Store interface {
- Register(io.Reader, ChainID, string) (Layer, error)
+ Register(io.Reader, ChainID) (Layer, error)
Get(ChainID) (Layer, error)
Map() map[ChainID]Layer
Release(Layer) ([]Metadata, error)
- CreateRWLayer(id string, parent ChainID, os string, opts *CreateRWLayerOpts) (RWLayer, error)
+ CreateRWLayer(id string, parent ChainID, opts *CreateRWLayerOpts) (RWLayer, error)
GetRWLayer(id string) (RWLayer, error)
GetMountID(id string) (string, error)
ReleaseRWLayer(RWLayer) ([]Metadata, error)
Cleanup() error
- DriverStatus(os string) [][2]string
- DriverName(os string) string
+ DriverStatus() [][2]string
+ DriverName() string
+ OS() string
}
// DescribableStore represents a layer store capable of storing
// descriptors for layers.
type DescribableStore interface {
- RegisterWithDescriptor(io.Reader, ChainID, string, distribution.Descriptor) (Layer, error)
+ RegisterWithDescriptor(io.Reader, ChainID, distribution.Descriptor) (Layer, error)
}
// MetadataTransaction represents functions for setting layer metadata
diff --git a/layer/layer_store.go b/layer/layer_store.go
index bd09af47a2..fa42dfa505 100644
--- a/layer/layer_store.go
+++ b/layer/layer_store.go
@@ -5,7 +5,6 @@ import (
"fmt"
"io"
"io/ioutil"
- "runtime"
"sync"
"github.com/docker/distribution"
@@ -29,76 +28,70 @@ const maxLayerDepth = 125
type layerStore struct {
store MetadataStore
- drivers map[string]graphdriver.Driver
- useTarSplit map[string]bool
+ driver graphdriver.Driver
+ useTarSplit bool
layerMap map[ChainID]*roLayer
layerL sync.Mutex
mounts map[string]*mountedLayer
mountL sync.Mutex
+ os string
}
// StoreOptions are the options used to create a new Store instance
type StoreOptions struct {
Root string
- GraphDrivers map[string]string
MetadataStorePathTemplate string
+ GraphDriver string
GraphDriverOptions []string
IDMappings *idtools.IDMappings
PluginGetter plugingetter.PluginGetter
ExperimentalEnabled bool
+ OS string
}
// NewStoreFromOptions creates a new Store instance
func NewStoreFromOptions(options StoreOptions) (Store, error) {
- drivers := make(map[string]graphdriver.Driver)
- for os, drivername := range options.GraphDrivers {
- var err error
- drivers[os], err = graphdriver.New(drivername,
- options.PluginGetter,
- graphdriver.Options{
- Root: options.Root,
- DriverOptions: options.GraphDriverOptions,
- UIDMaps: options.IDMappings.UIDs(),
- GIDMaps: options.IDMappings.GIDs(),
- ExperimentalEnabled: options.ExperimentalEnabled,
- })
- if err != nil {
- return nil, fmt.Errorf("error initializing graphdriver: %v", err)
- }
- logrus.Debugf("Initialized graph driver %s", drivername)
+ driver, err := graphdriver.New(options.GraphDriver, options.PluginGetter, graphdriver.Options{
+ Root: options.Root,
+ DriverOptions: options.GraphDriverOptions,
+ UIDMaps: options.IDMappings.UIDs(),
+ GIDMaps: options.IDMappings.GIDs(),
+ ExperimentalEnabled: options.ExperimentalEnabled,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("error initializing graphdriver: %v", err)
}
+ logrus.Debugf("Initialized graph driver %s", driver)
- fms, err := NewFSMetadataStore(fmt.Sprintf(options.MetadataStorePathTemplate, options.GraphDrivers[runtime.GOOS]))
+ fms, err := NewFSMetadataStore(fmt.Sprintf(options.MetadataStorePathTemplate, driver))
if err != nil {
return nil, err
}
- return NewStoreFromGraphDrivers(fms, drivers)
+ return NewStoreFromGraphDriver(fms, driver, options.OS)
}
-// NewStoreFromGraphDrivers creates a new Store instance using the provided
-// metadata store and graph drivers. The metadata store will be used to restore
+// NewStoreFromGraphDriver creates a new Store instance using the provided
+// metadata store and graph driver. The metadata store will be used to restore
// the Store.
-func NewStoreFromGraphDrivers(store MetadataStore, drivers map[string]graphdriver.Driver) (Store, error) {
-
- useTarSplit := make(map[string]bool)
- for os, driver := range drivers {
-
- caps := graphdriver.Capabilities{}
- if capDriver, ok := driver.(graphdriver.CapabilityDriver); ok {
- caps = capDriver.Capabilities()
- }
- useTarSplit[os] = !caps.ReproducesExactDiffs
+func NewStoreFromGraphDriver(store MetadataStore, driver graphdriver.Driver, os string) (Store, error) {
+ if !system.IsOSSupported(os) {
+ return nil, fmt.Errorf("failed to initialize layer store as operating system '%s' is not supported", os)
+ }
+ caps := graphdriver.Capabilities{}
+ if capDriver, ok := driver.(graphdriver.CapabilityDriver); ok {
+ caps = capDriver.Capabilities()
}
ls := &layerStore{
store: store,
- drivers: drivers,
+ driver: driver,
layerMap: map[ChainID]*roLayer{},
mounts: map[string]*mountedLayer{},
- useTarSplit: useTarSplit,
+ useTarSplit: !caps.ReproducesExactDiffs,
+ os: os,
}
ids, mounts, err := store.List()
@@ -162,6 +155,10 @@ func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) {
return nil, fmt.Errorf("failed to get operating system for %s: %s", layer, err)
}
+ if os != ls.os {
+ return nil, fmt.Errorf("failed to load layer with os %s into layerstore for %s", os, ls.os)
+ }
+
cl = &roLayer{
chainID: layer,
diffID: diff,
@@ -170,7 +167,6 @@ func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) {
layerStore: ls,
references: map[Layer]struct{}{},
descriptor: descriptor,
- os: os,
}
if parent != "" {
@@ -234,7 +230,7 @@ func (ls *layerStore) applyTar(tx MetadataTransaction, ts io.Reader, parent stri
tr := io.TeeReader(ts, digester.Hash())
rdr := tr
- if ls.useTarSplit[layer.os] {
+ if ls.useTarSplit {
tsw, err := tx.TarSplitWriter(true)
if err != nil {
return err
@@ -250,7 +246,7 @@ func (ls *layerStore) applyTar(tx MetadataTransaction, ts io.Reader, parent stri
}
}
- applySize, err := ls.drivers[layer.os].ApplyDiff(layer.cacheID, parent, rdr)
+ applySize, err := ls.driver.ApplyDiff(layer.cacheID, parent, rdr)
if err != nil {
return err
}
@@ -266,11 +262,11 @@ func (ls *layerStore) applyTar(tx MetadataTransaction, ts io.Reader, parent stri
return nil
}
-func (ls *layerStore) Register(ts io.Reader, parent ChainID, os string) (Layer, error) {
- return ls.registerWithDescriptor(ts, parent, os, distribution.Descriptor{})
+func (ls *layerStore) Register(ts io.Reader, parent ChainID) (Layer, error) {
+ return ls.registerWithDescriptor(ts, parent, distribution.Descriptor{})
}
-func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, os string, descriptor distribution.Descriptor) (Layer, error) {
+func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, descriptor distribution.Descriptor) (Layer, error) {
// err is used to hold the error which will always trigger
// cleanup of creates sources but may not be an error returned
// to the caller (already exists).
@@ -298,14 +294,6 @@ func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, os st
}
}
- // Validate the operating system is valid
- if os == "" {
- os = runtime.GOOS
- }
- if err := system.ValidatePlatform(system.ParsePlatform(os)); err != nil {
- return nil, err
- }
-
// Create new roLayer
layer := &roLayer{
parent: p,
@@ -314,10 +302,9 @@ func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, os st
layerStore: ls,
references: map[Layer]struct{}{},
descriptor: descriptor,
- os: os,
}
- if err = ls.drivers[os].Create(layer.cacheID, pid, nil); err != nil {
+ if err = ls.driver.Create(layer.cacheID, pid, nil); err != nil {
return nil, err
}
@@ -329,7 +316,7 @@ func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, os st
defer func() {
if err != nil {
logrus.Debugf("Cleaning up layer %s: %v", layer.cacheID, err)
- if err := ls.drivers[os].Remove(layer.cacheID); err != nil {
+ if err := ls.driver.Remove(layer.cacheID); err != nil {
logrus.Errorf("Error cleaning up cache layer %s: %v", layer.cacheID, err)
}
if err := tx.Cancel(); err != nil {
@@ -413,7 +400,7 @@ func (ls *layerStore) Map() map[ChainID]Layer {
}
func (ls *layerStore) deleteLayer(layer *roLayer, metadata *Metadata) error {
- err := ls.drivers[layer.os].Remove(layer.cacheID)
+ err := ls.driver.Remove(layer.cacheID)
if err != nil {
return err
}
@@ -483,7 +470,7 @@ func (ls *layerStore) Release(l Layer) ([]Metadata, error) {
return ls.releaseLayer(layer)
}
-func (ls *layerStore) CreateRWLayer(name string, parent ChainID, os string, opts *CreateRWLayerOpts) (RWLayer, error) {
+func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWLayerOpts) (RWLayer, error) {
var (
storageOpt map[string]string
initFunc MountInit
@@ -523,21 +510,16 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, os string, opts
}()
}
- // Ensure the operating system is set to the host OS if not populated.
- if os == "" {
- os = runtime.GOOS
- }
m = &mountedLayer{
name: name,
parent: p,
mountID: ls.mountID(name),
layerStore: ls,
references: map[RWLayer]*referencedRWLayer{},
- os: os,
}
if initFunc != nil {
- pid, err = ls.initMount(m.mountID, m.os, pid, mountLabel, initFunc, storageOpt)
+ pid, err = ls.initMount(m.mountID, pid, mountLabel, initFunc, storageOpt)
if err != nil {
return nil, err
}
@@ -548,7 +530,7 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, os string, opts
StorageOpt: storageOpt,
}
- if err = ls.drivers[os].CreateReadWrite(m.mountID, pid, createOpts); err != nil {
+ if err = ls.driver.CreateReadWrite(m.mountID, pid, createOpts); err != nil {
return nil, err
}
if err = ls.saveMount(m); err != nil {
@@ -597,14 +579,14 @@ func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) {
return []Metadata{}, nil
}
- if err := ls.drivers[l.OS()].Remove(m.mountID); err != nil {
+ if err := ls.driver.Remove(m.mountID); err != nil {
logrus.Errorf("Error removing mounted layer %s: %s", m.name, err)
m.retakeReference(l)
return nil, err
}
if m.initID != "" {
- if err := ls.drivers[l.OS()].Remove(m.initID); err != nil {
+ if err := ls.driver.Remove(m.initID); err != nil {
logrus.Errorf("Error removing init layer %s: %s", m.name, err)
m.retakeReference(l)
return nil, err
@@ -650,7 +632,7 @@ func (ls *layerStore) saveMount(mount *mountedLayer) error {
return nil
}
-func (ls *layerStore) initMount(graphID, os, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (string, error) {
+func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (string, error) {
// Use "<graph-id>-init" to maintain compatibility with graph drivers
// which are expecting this layer with this special name. If all
// graph drivers can be updated to not rely on knowing about this layer
@@ -662,20 +644,20 @@ func (ls *layerStore) initMount(graphID, os, parent, mountLabel string, initFunc
StorageOpt: storageOpt,
}
- if err := ls.drivers[os].CreateReadWrite(initID, parent, createOpts); err != nil {
+ if err := ls.driver.CreateReadWrite(initID, parent, createOpts); err != nil {
return "", err
}
- p, err := ls.drivers[os].Get(initID, "")
+ p, err := ls.driver.Get(initID, "")
if err != nil {
return "", err
}
if err := initFunc(p); err != nil {
- ls.drivers[os].Put(initID)
+ ls.driver.Put(initID)
return "", err
}
- if err := ls.drivers[os].Put(initID); err != nil {
+ if err := ls.driver.Put(initID); err != nil {
return "", err
}
@@ -683,13 +665,13 @@ func (ls *layerStore) initMount(graphID, os, parent, mountLabel string, initFunc
}
func (ls *layerStore) getTarStream(rl *roLayer) (io.ReadCloser, error) {
- if !ls.useTarSplit[rl.os] {
+ if !ls.useTarSplit {
var parentCacheID string
if rl.parent != nil {
parentCacheID = rl.parent.cacheID
}
- return ls.drivers[rl.os].Diff(rl.cacheID, parentCacheID)
+ return ls.driver.Diff(rl.cacheID, parentCacheID)
}
r, err := ls.store.TarSplitReader(rl.chainID)
@@ -699,7 +681,7 @@ func (ls *layerStore) getTarStream(rl *roLayer) (io.ReadCloser, error) {
pr, pw := io.Pipe()
go func() {
- err := ls.assembleTarTo(rl.cacheID, rl.os, r, nil, pw)
+ err := ls.assembleTarTo(rl.cacheID, r, nil, pw)
if err != nil {
pw.CloseWithError(err)
} else {
@@ -710,10 +692,10 @@ func (ls *layerStore) getTarStream(rl *roLayer) (io.ReadCloser, error) {
return pr, nil
}
-func (ls *layerStore) assembleTarTo(graphID, os string, metadata io.ReadCloser, size *int64, w io.Writer) error {
- diffDriver, ok := ls.drivers[os].(graphdriver.DiffGetterDriver)
+func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size *int64, w io.Writer) error {
+ diffDriver, ok := ls.driver.(graphdriver.DiffGetterDriver)
if !ok {
- diffDriver = &naiveDiffPathDriver{ls.drivers[os]}
+ diffDriver = &naiveDiffPathDriver{ls.driver}
}
defer metadata.Close()
@@ -732,27 +714,19 @@ func (ls *layerStore) assembleTarTo(graphID, os string, metadata io.ReadCloser,
}
func (ls *layerStore) Cleanup() error {
- var err error
- for _, driver := range ls.drivers {
- if e := driver.Cleanup(); e != nil {
- err = fmt.Errorf("%s - %s", err.Error(), e.Error())
- }
- }
- return err
+ return ls.driver.Cleanup()
}
-func (ls *layerStore) DriverStatus(os string) [][2]string {
- if os == "" {
- os = runtime.GOOS
- }
- return ls.drivers[os].Status()
+func (ls *layerStore) DriverStatus() [][2]string {
+ return ls.driver.Status()
}
-func (ls *layerStore) DriverName(os string) string {
- if os == "" {
- os = runtime.GOOS
- }
- return ls.drivers[os].String()
+func (ls *layerStore) DriverName() string {
+ return ls.driver.String()
+}
+
+func (ls *layerStore) OS() string {
+ return ls.os
}
type naiveDiffPathDriver struct {
diff --git a/layer/layer_store_windows.go b/layer/layer_store_windows.go
index ceee16e26f..1276a912cc 100644
--- a/layer/layer_store_windows.go
+++ b/layer/layer_store_windows.go
@@ -6,6 +6,6 @@ import (
"github.com/docker/distribution"
)
-func (ls *layerStore) RegisterWithDescriptor(ts io.Reader, parent ChainID, os string, descriptor distribution.Descriptor) (Layer, error) {
- return ls.registerWithDescriptor(ts, parent, os, descriptor)
+func (ls *layerStore) RegisterWithDescriptor(ts io.Reader, parent ChainID, descriptor distribution.Descriptor) (Layer, error) {
+ return ls.registerWithDescriptor(ts, parent, descriptor)
}
diff --git a/layer/layer_test.go b/layer/layer_test.go
index 6f6d2cd3f4..edd9c9f4c2 100644
--- a/layer/layer_test.go
+++ b/layer/layer_test.go
@@ -73,9 +73,7 @@ func newTestStore(t *testing.T) (Store, string, func()) {
if err != nil {
t.Fatal(err)
}
- graphs := make(map[string]graphdriver.Driver)
- graphs[runtime.GOOS] = graph
- ls, err := NewStoreFromGraphDrivers(fms, graphs)
+ ls, err := NewStoreFromGraphDriver(fms, graph, runtime.GOOS)
if err != nil {
t.Fatal(err)
}
@@ -90,7 +88,7 @@ type layerInit func(root containerfs.ContainerFS) error
func createLayer(ls Store, parent ChainID, layerFunc layerInit) (Layer, error) {
containerID := stringid.GenerateRandomID()
- mount, err := ls.CreateRWLayer(containerID, parent, runtime.GOOS, nil)
+ mount, err := ls.CreateRWLayer(containerID, parent, nil)
if err != nil {
return nil, err
}
@@ -110,7 +108,7 @@ func createLayer(ls Store, parent ChainID, layerFunc layerInit) (Layer, error) {
}
defer ts.Close()
- layer, err := ls.Register(ts, parent, runtime.GOOS)
+ layer, err := ls.Register(ts, parent)
if err != nil {
return nil, err
}
@@ -279,7 +277,7 @@ func TestMountAndRegister(t *testing.T) {
size, _ := layer.Size()
t.Logf("Layer size: %d", size)
- mount2, err := ls.CreateRWLayer("new-test-mount", layer.ChainID(), runtime.GOOS, nil)
+ mount2, err := ls.CreateRWLayer("new-test-mount", layer.ChainID(), nil)
if err != nil {
t.Fatal(err)
}
@@ -387,7 +385,7 @@ func TestStoreRestore(t *testing.T) {
t.Fatal(err)
}
- m, err := ls.CreateRWLayer("some-mount_name", layer3.ChainID(), runtime.GOOS, nil)
+ m, err := ls.CreateRWLayer("some-mount_name", layer3.ChainID(), nil)
if err != nil {
t.Fatal(err)
}
@@ -405,7 +403,7 @@ func TestStoreRestore(t *testing.T) {
t.Fatal(err)
}
- ls2, err := NewStoreFromGraphDrivers(ls.(*layerStore).store, ls.(*layerStore).drivers)
+ ls2, err := NewStoreFromGraphDriver(ls.(*layerStore).store, ls.(*layerStore).driver, runtime.GOOS)
if err != nil {
t.Fatal(err)
}
@@ -418,7 +416,7 @@ func TestStoreRestore(t *testing.T) {
assertLayerEqual(t, layer3b, layer3)
// Create again with same name, should return error
- if _, err := ls2.CreateRWLayer("some-mount_name", layer3b.ChainID(), runtime.GOOS, nil); err == nil {
+ if _, err := ls2.CreateRWLayer("some-mount_name", layer3b.ChainID(), nil); err == nil {
t.Fatal("Expected error creating mount with same name")
} else if err != ErrMountNameConflict {
t.Fatal(err)
@@ -500,13 +498,13 @@ func TestTarStreamStability(t *testing.T) {
t.Fatal(err)
}
- layer1, err := ls.Register(bytes.NewReader(tar1), "", runtime.GOOS)
+ layer1, err := ls.Register(bytes.NewReader(tar1), "")
if err != nil {
t.Fatal(err)
}
// hack layer to add file
- p, err := ls.(*layerStore).drivers[runtime.GOOS].Get(layer1.(*referencedCacheLayer).cacheID, "")
+ p, err := ls.(*layerStore).driver.Get(layer1.(*referencedCacheLayer).cacheID, "")
if err != nil {
t.Fatal(err)
}
@@ -515,11 +513,11 @@ func TestTarStreamStability(t *testing.T) {
t.Fatal(err)
}
- if err := ls.(*layerStore).drivers[runtime.GOOS].Put(layer1.(*referencedCacheLayer).cacheID); err != nil {
+ if err := ls.(*layerStore).driver.Put(layer1.(*referencedCacheLayer).cacheID); err != nil {
t.Fatal(err)
}
- layer2, err := ls.Register(bytes.NewReader(tar2), layer1.ChainID(), runtime.GOOS)
+ layer2, err := ls.Register(bytes.NewReader(tar2), layer1.ChainID())
if err != nil {
t.Fatal(err)
}
@@ -687,12 +685,12 @@ func TestRegisterExistingLayer(t *testing.T) {
t.Fatal(err)
}
- layer2a, err := ls.Register(bytes.NewReader(tar1), layer1.ChainID(), runtime.GOOS)
+ layer2a, err := ls.Register(bytes.NewReader(tar1), layer1.ChainID())
if err != nil {
t.Fatal(err)
}
- layer2b, err := ls.Register(bytes.NewReader(tar1), layer1.ChainID(), runtime.GOOS)
+ layer2b, err := ls.Register(bytes.NewReader(tar1), layer1.ChainID())
if err != nil {
t.Fatal(err)
}
@@ -727,12 +725,12 @@ func TestTarStreamVerification(t *testing.T) {
t.Fatal(err)
}
- layer1, err := ls.Register(bytes.NewReader(tar1), "", runtime.GOOS)
+ layer1, err := ls.Register(bytes.NewReader(tar1), "")
if err != nil {
t.Fatal(err)
}
- layer2, err := ls.Register(bytes.NewReader(tar2), "", runtime.GOOS)
+ layer2, err := ls.Register(bytes.NewReader(tar2), "")
if err != nil {
t.Fatal(err)
}
diff --git a/layer/layer_unix_test.go b/layer/layer_unix_test.go
index ddfac76150..c11f3becea 100644
--- a/layer/layer_unix_test.go
+++ b/layer/layer_unix_test.go
@@ -3,7 +3,6 @@
package layer
import (
- "runtime"
"testing"
)
@@ -13,7 +12,7 @@ func graphDiffSize(ls Store, l Layer) (int64, error) {
if cl.parent != nil {
parent = cl.parent.cacheID
}
- return ls.(*layerStore).drivers[runtime.GOOS].DiffSize(cl.cacheID, parent)
+ return ls.(*layerStore).driver.DiffSize(cl.cacheID, parent)
}
// Unix as Windows graph driver does not support Changes which is indirectly
diff --git a/layer/layer_windows.go b/layer/layer_windows.go
index 1d621229be..c379c1b86e 100644
--- a/layer/layer_windows.go
+++ b/layer/layer_windows.go
@@ -25,15 +25,15 @@ func GetLayerPath(s Store, layer ChainID) (string, error) {
return "", ErrLayerDoesNotExist
}
- if layerGetter, ok := ls.drivers[rl.os].(Getter); ok {
+ if layerGetter, ok := ls.driver.(Getter); ok {
return layerGetter.GetLayerPath(rl.cacheID)
}
- path, err := ls.drivers[rl.os].Get(rl.cacheID, "")
+ path, err := ls.driver.Get(rl.cacheID, "")
if err != nil {
return "", err
}
- if err := ls.drivers[rl.os].Put(rl.cacheID); err != nil {
+ if err := ls.driver.Put(rl.cacheID); err != nil {
return "", err
}
diff --git a/layer/migration.go b/layer/migration.go
index f42cfa9af0..21b43b73ee 100644
--- a/layer/migration.go
+++ b/layer/migration.go
@@ -6,7 +6,6 @@ import (
"fmt"
"io"
"os"
- "runtime"
"github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
@@ -17,7 +16,7 @@ import (
// CreateRWLayerByGraphID creates a RWLayer in the layer store using
// the provided name with the given graphID. To get the RWLayer
// after migration the layer may be retrieved by the given name.
-func (ls *layerStore) CreateRWLayerByGraphID(name, graphID, os string, parent ChainID) (err error) {
+func (ls *layerStore) CreateRWLayerByGraphID(name, graphID string, parent ChainID) (err error) {
ls.mountL.Lock()
defer ls.mountL.Unlock()
m, ok := ls.mounts[name]
@@ -32,11 +31,7 @@ func (ls *layerStore) CreateRWLayerByGraphID(name, graphID, os string, parent Ch
return nil
}
- // Ensure the operating system is set to the host OS if not populated.
- if os == "" {
- os = runtime.GOOS
- }
- if !ls.drivers[os].Exists(graphID) {
+ if !ls.driver.Exists(graphID) {
return fmt.Errorf("graph ID does not exist: %q", graphID)
}
@@ -65,12 +60,11 @@ func (ls *layerStore) CreateRWLayerByGraphID(name, graphID, os string, parent Ch
mountID: graphID,
layerStore: ls,
references: map[RWLayer]*referencedRWLayer{},
- os: os,
}
// Check for existing init layer
initID := fmt.Sprintf("%s-init", graphID)
- if ls.drivers[os].Exists(initID) {
+ if ls.driver.Exists(initID) {
m.initID = initID
}
@@ -101,10 +95,7 @@ func (ls *layerStore) ChecksumForGraphID(id, parent, oldTarDataPath, newTarDataP
}
dgst := digest.Canonical.Digester()
- // Note - we use the host OS here. This is a safe assumption as its during migration, and
- // no host OS which supports migration also supports multiple image OS's. In other words,
- // it's only on Linux, not on Windows.
- err = ls.assembleTarTo(id, runtime.GOOS, uncompressed, &size, dgst.Hash())
+ err = ls.assembleTarTo(id, uncompressed, &size, dgst.Hash())
if err != nil {
return
}
@@ -120,10 +111,7 @@ func (ls *layerStore) ChecksumForGraphID(id, parent, oldTarDataPath, newTarDataP
}
func (ls *layerStore) checksumForGraphIDNoTarsplit(id, parent, newTarDataPath string) (diffID DiffID, size int64, err error) {
- // Note - we use the host OS here. This is a safe assumption as its during migration, and
- // no host OS which supports migration also supports multiple image OS's. In other words,
- // it's only on Linux, not on Windows.
- rawarchive, err := ls.drivers[runtime.GOOS].Diff(id, parent)
+ rawarchive, err := ls.driver.Diff(id, parent)
if err != nil {
return
}
diff --git a/layer/migration_test.go b/layer/migration_test.go
index cc4e14877a..e2acd19c2c 100644
--- a/layer/migration_test.go
+++ b/layer/migration_test.go
@@ -94,9 +94,7 @@ func TestLayerMigration(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- graphs := make(map[string]graphdriver.Driver)
- graphs[runtime.GOOS] = graph
- ls, err := NewStoreFromGraphDrivers(fms, graphs)
+ ls, err := NewStoreFromGraphDriver(fms, graph, runtime.GOOS)
if err != nil {
t.Fatal(err)
}
@@ -112,14 +110,14 @@ func TestLayerMigration(t *testing.T) {
t.Fatal(err)
}
- layer1b, err := ls.Register(bytes.NewReader(tar1), "", runtime.GOOS)
+ layer1b, err := ls.Register(bytes.NewReader(tar1), "")
if err != nil {
t.Fatal(err)
}
assertReferences(t, layer1a, layer1b)
// Attempt register, should be same
- layer2a, err := ls.Register(bytes.NewReader(tar2), layer1a.ChainID(), runtime.GOOS)
+ layer2a, err := ls.Register(bytes.NewReader(tar2), layer1a.ChainID())
if err != nil {
t.Fatal(err)
}
@@ -224,9 +222,7 @@ func TestLayerMigrationNoTarsplit(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- graphs := make(map[string]graphdriver.Driver)
- graphs[runtime.GOOS] = graph
- ls, err := NewStoreFromGraphDrivers(fms, graphs)
+ ls, err := NewStoreFromGraphDriver(fms, graph, runtime.GOOS)
if err != nil {
t.Fatal(err)
}
@@ -242,7 +238,7 @@ func TestLayerMigrationNoTarsplit(t *testing.T) {
t.Fatal(err)
}
- layer1b, err := ls.Register(bytes.NewReader(tar1), "", runtime.GOOS)
+ layer1b, err := ls.Register(bytes.NewReader(tar1), "")
if err != nil {
t.Fatal(err)
}
@@ -250,7 +246,7 @@ func TestLayerMigrationNoTarsplit(t *testing.T) {
assertReferences(t, layer1a, layer1b)
// Attempt register, should be same
- layer2a, err := ls.Register(bytes.NewReader(tar2), layer1a.ChainID(), runtime.GOOS)
+ layer2a, err := ls.Register(bytes.NewReader(tar2), layer1a.ChainID())
if err != nil {
t.Fatal(err)
}
@@ -312,7 +308,7 @@ func TestMountMigration(t *testing.T) {
t.Fatal(err)
}
- graph := ls.(*layerStore).drivers[runtime.GOOS]
+ graph := ls.(*layerStore).driver
layer1, err := createLayer(ls, "", initWithFiles(baseFiles...))
if err != nil {
@@ -338,7 +334,7 @@ func TestMountMigration(t *testing.T) {
t.Fatal(err)
}
- if err := ls.(*layerStore).CreateRWLayerByGraphID("migration-mount", containerID, runtime.GOOS, layer1.ChainID()); err != nil {
+ if err := ls.(*layerStore).CreateRWLayerByGraphID("migration-mount", containerID, layer1.ChainID()); err != nil {
t.Fatal(err)
}
@@ -384,7 +380,7 @@ func TestMountMigration(t *testing.T) {
Kind: archive.ChangeAdd,
})
- if _, err := ls.CreateRWLayer("migration-mount", layer1.ChainID(), runtime.GOOS, nil); err == nil {
+ if _, err := ls.CreateRWLayer("migration-mount", layer1.ChainID(), nil); err == nil {
t.Fatal("Expected error creating mount with same name")
} else if err != ErrMountNameConflict {
t.Fatal(err)
diff --git a/layer/mount_test.go b/layer/mount_test.go
index 399a34cbde..44d461f9b8 100644
--- a/layer/mount_test.go
+++ b/layer/mount_test.go
@@ -35,7 +35,7 @@ func TestMountInit(t *testing.T) {
rwLayerOpts := &CreateRWLayerOpts{
InitFunc: mountInit,
}
- m, err := ls.CreateRWLayer("fun-mount", layer.ChainID(), runtime.GOOS, rwLayerOpts)
+ m, err := ls.CreateRWLayer("fun-mount", layer.ChainID(), rwLayerOpts)
if err != nil {
t.Fatal(err)
}
@@ -95,7 +95,7 @@ func TestMountSize(t *testing.T) {
InitFunc: mountInit,
}
- m, err := ls.CreateRWLayer("mount-size", layer.ChainID(), runtime.GOOS, rwLayerOpts)
+ m, err := ls.CreateRWLayer("mount-size", layer.ChainID(), rwLayerOpts)
if err != nil {
t.Fatal(err)
}
@@ -147,7 +147,7 @@ func TestMountChanges(t *testing.T) {
InitFunc: mountInit,
}
- m, err := ls.CreateRWLayer("mount-changes", layer.ChainID(), runtime.GOOS, rwLayerOpts)
+ m, err := ls.CreateRWLayer("mount-changes", layer.ChainID(), rwLayerOpts)
if err != nil {
t.Fatal(err)
}
diff --git a/layer/mounted_layer.go b/layer/mounted_layer.go
index 80a4bda0a3..c7decca32e 100644
--- a/layer/mounted_layer.go
+++ b/layer/mounted_layer.go
@@ -2,7 +2,6 @@ package layer
import (
"io"
- "runtime"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/containerfs"
@@ -15,7 +14,6 @@ type mountedLayer struct {
parent *roLayer
path string
layerStore *layerStore
- os string
references map[RWLayer]*referencedRWLayer
}
@@ -31,7 +29,7 @@ func (ml *mountedLayer) cacheParent() string {
}
func (ml *mountedLayer) TarStream() (io.ReadCloser, error) {
- return ml.layerStore.drivers[ml.OS()].Diff(ml.mountID, ml.cacheParent())
+ return ml.layerStore.driver.Diff(ml.mountID, ml.cacheParent())
}
func (ml *mountedLayer) Name() string {
@@ -49,23 +47,19 @@ func (ml *mountedLayer) Parent() Layer {
}
func (ml *mountedLayer) OS() string {
- // For backwards compatibility, return the host OS if not set.
- if ml.os == "" {
- return runtime.GOOS
- }
- return ml.os
+ return ml.layerStore.os
}
func (ml *mountedLayer) Size() (int64, error) {
- return ml.layerStore.drivers[ml.OS()].DiffSize(ml.mountID, ml.cacheParent())
+ return ml.layerStore.driver.DiffSize(ml.mountID, ml.cacheParent())
}
func (ml *mountedLayer) Changes() ([]archive.Change, error) {
- return ml.layerStore.drivers[ml.OS()].Changes(ml.mountID, ml.cacheParent())
+ return ml.layerStore.driver.Changes(ml.mountID, ml.cacheParent())
}
func (ml *mountedLayer) Metadata() (map[string]string, error) {
- return ml.layerStore.drivers[ml.OS()].GetMetadata(ml.mountID)
+ return ml.layerStore.driver.GetMetadata(ml.mountID)
}
func (ml *mountedLayer) getReference() RWLayer {
@@ -100,11 +94,11 @@ type referencedRWLayer struct {
}
func (rl *referencedRWLayer) Mount(mountLabel string) (containerfs.ContainerFS, error) {
- return rl.layerStore.drivers[rl.OS()].Get(rl.mountedLayer.mountID, mountLabel)
+ return rl.layerStore.driver.Get(rl.mountedLayer.mountID, mountLabel)
}
// Unmount decrements the activity count and unmounts the underlying layer
// Callers should only call `Unmount` once per call to `Mount`, even on error.
func (rl *referencedRWLayer) Unmount() error {
- return rl.layerStore.drivers[rl.OS()].Put(rl.mountedLayer.mountID)
+ return rl.layerStore.driver.Put(rl.mountedLayer.mountID)
}
diff --git a/layer/ro_layer.go b/layer/ro_layer.go
index aca061efd4..74423874e3 100644
--- a/layer/ro_layer.go
+++ b/layer/ro_layer.go
@@ -16,7 +16,6 @@ type roLayer struct {
size int64
layerStore *layerStore
descriptor distribution.Descriptor
- os string
referenceCount int
references map[Layer]struct{}
@@ -52,7 +51,7 @@ func (rl *roLayer) TarStreamFrom(parent ChainID) (io.ReadCloser, error) {
if parent != ChainID("") && parentCacheID == "" {
return nil, fmt.Errorf("layer ID '%s' is not a parent of the specified layer: cannot provide diff to non-parent", parent)
}
- return rl.layerStore.drivers[rl.OS()].Diff(rl.cacheID, parentCacheID)
+ return rl.layerStore.driver.Diff(rl.cacheID, parentCacheID)
}
func (rl *roLayer) ChainID() ChainID {
@@ -70,6 +69,10 @@ func (rl *roLayer) Parent() Layer {
return rl.parent
}
+func (rl *roLayer) OS() string {
+ return rl.layerStore.os
+}
+
func (rl *roLayer) Size() (size int64, err error) {
if rl.parent != nil {
size, err = rl.parent.Size()
@@ -86,7 +89,7 @@ func (rl *roLayer) DiffSize() (size int64, err error) {
}
func (rl *roLayer) Metadata() (map[string]string, error) {
- return rl.layerStore.drivers[rl.OS()].GetMetadata(rl.cacheID)
+ return rl.layerStore.driver.GetMetadata(rl.cacheID)
}
type referencedCacheLayer struct {
@@ -143,7 +146,11 @@ func storeLayer(tx MetadataTransaction, layer *roLayer) error {
return err
}
}
- return tx.SetOS(layer.os)
+ if err := tx.SetOS(layer.layerStore.os); err != nil {
+ return err
+ }
+
+ return nil
}
func newVerifiedReadCloser(rc io.ReadCloser, dgst digest.Digest) (io.ReadCloser, error) {
diff --git a/layer/ro_layer_unix.go b/layer/ro_layer_unix.go
deleted file mode 100644
index 3f8e928ed2..0000000000
--- a/layer/ro_layer_unix.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build !windows
-
-package layer
-
-import "runtime"
-
-func (rl *roLayer) OS() string {
- return runtime.GOOS
-}
diff --git a/layer/ro_layer_windows.go b/layer/ro_layer_windows.go
index 4351a1fc52..32bd7182a3 100644
--- a/layer/ro_layer_windows.go
+++ b/layer/ro_layer_windows.go
@@ -7,10 +7,3 @@ var _ distribution.Describable = &roLayer{}
func (rl *roLayer) Descriptor() distribution.Descriptor {
return rl.descriptor
}
-
-func (rl *roLayer) OS() string {
- if rl.os == "" {
- return "windows"
- }
- return rl.os
-}