diff options
author | John Howard <jhoward@microsoft.com> | 2017-09-19 12:14:46 -0700 |
---|---|---|
committer | John Howard <jhoward@microsoft.com> | 2018-01-18 08:31:05 -0800 |
commit | afd305c4b5682fbc297e1685e2b7a49628b7c7f0 (patch) | |
tree | 03158e6d34824d13482af4a40276291c949f5f08 /layer | |
parent | ce8e529e182bde057cdfafded62c210b7293b8ba (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.go | 9 | ||||
-rw-r--r-- | layer/layer.go | 11 | ||||
-rw-r--r-- | layer/layer_store.go | 158 | ||||
-rw-r--r-- | layer/layer_store_windows.go | 4 | ||||
-rw-r--r-- | layer/layer_test.go | 32 | ||||
-rw-r--r-- | layer/layer_unix_test.go | 3 | ||||
-rw-r--r-- | layer/layer_windows.go | 6 | ||||
-rw-r--r-- | layer/migration.go | 22 | ||||
-rw-r--r-- | layer/migration_test.go | 22 | ||||
-rw-r--r-- | layer/mount_test.go | 6 | ||||
-rw-r--r-- | layer/mounted_layer.go | 20 | ||||
-rw-r--r-- | layer/ro_layer.go | 15 | ||||
-rw-r--r-- | layer/ro_layer_unix.go | 9 | ||||
-rw-r--r-- | layer/ro_layer_windows.go | 7 |
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 -} |