summaryrefslogtreecommitdiff
path: root/layer
diff options
context:
space:
mode:
authorJohn Howard <jhoward@microsoft.com>2017-04-25 09:37:29 -0700
committerJohn Howard <jhoward@microsoft.com>2017-06-20 09:00:32 -0700
commitfc21bf280bac39377d3a236efa87f5c8cbadfb9f (patch)
treea8ffbf8dbf0ee52cba10b14168d4a87cfe4c60d4 /layer
parent55f8828eec1ff6c70628a0b6f22bea175ce36159 (diff)
downloaddocker-fc21bf280bac39377d3a236efa87f5c8cbadfb9f.tar.gz
LCOW: Adds platform to the layer store
Signed-off-by: John Howard <jhoward@microsoft.com>
Diffstat (limited to 'layer')
-rw-r--r--layer/empty.go4
-rw-r--r--layer/filestore_unix.go13
-rw-r--r--layer/filestore_windows.go35
-rw-r--r--layer/layer.go13
-rw-r--r--layer/layer_store.go6
-rw-r--r--layer/ro_layer.go4
-rw-r--r--layer/ro_layer_unix.go7
-rw-r--r--layer/ro_layer_windows.go7
8 files changed, 89 insertions, 0 deletions
diff --git a/layer/empty.go b/layer/empty.go
index 80f2c12439..cf04aa12fe 100644
--- a/layer/empty.go
+++ b/layer/empty.go
@@ -55,6 +55,10 @@ func (el *emptyLayer) Metadata() (map[string]string, error) {
return make(map[string]string), nil
}
+func (el *emptyLayer) Platform() Platform {
+ return ""
+}
+
// IsEmpty returns true if the layer is an EmptyLayer
func IsEmpty(diffID DiffID) bool {
return diffID == DigestSHA256EmptyTar
diff --git a/layer/filestore_unix.go b/layer/filestore_unix.go
new file mode 100644
index 0000000000..fe8a4f8b2a
--- /dev/null
+++ b/layer/filestore_unix.go
@@ -0,0 +1,13 @@
+// +build !windows
+
+package layer
+
+// SetPlatform writes the "platform" file to the layer filestore
+func (fm *fileMetadataTransaction) SetPlatform(platform Platform) error {
+ return nil
+}
+
+// GetPlatform reads the "platform" file from the layer filestore
+func (fms *fileMetadataStore) GetPlatform(layer ChainID) (Platform, error) {
+ return "", nil
+}
diff --git a/layer/filestore_windows.go b/layer/filestore_windows.go
new file mode 100644
index 0000000000..066456d8d2
--- /dev/null
+++ b/layer/filestore_windows.go
@@ -0,0 +1,35 @@
+package layer
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+)
+
+// SetPlatform writes the "platform" file to the layer filestore
+func (fm *fileMetadataTransaction) SetPlatform(platform Platform) error {
+ if platform == "" {
+ return nil
+ }
+ return fm.ws.WriteFile("platform", []byte(platform), 0644)
+}
+
+// GetPlatform reads the "platform" file from the layer filestore
+func (fms *fileMetadataStore) GetPlatform(layer ChainID) (Platform, error) {
+ contentBytes, err := ioutil.ReadFile(fms.getLayerFilename(layer, "platform"))
+ if err != nil {
+ // For backwards compatibility, the platform file may not exist. Default to "windows" if missing.
+ if os.IsNotExist(err) {
+ return "windows", nil
+ }
+ return "", err
+ }
+ content := strings.TrimSpace(string(contentBytes))
+
+ if content != "windows" && content != "linux" {
+ return "", fmt.Errorf("invalid platform value: %s", content)
+ }
+
+ return Platform(content), nil
+}
diff --git a/layer/layer.go b/layer/layer.go
index 7b993ee4ad..2e5dcf9c85 100644
--- a/layer/layer.go
+++ b/layer/layer.go
@@ -64,6 +64,14 @@ func (id ChainID) String() string {
return string(id)
}
+// Platform is the platform of a layer
+type Platform string
+
+// String returns a string rendition of layers target platform
+func (id Platform) String() string {
+ return string(id)
+}
+
// DiffID is the hash of an individual layer tar.
type DiffID digest.Digest
@@ -99,6 +107,9 @@ type Layer interface {
// Parent returns the next layer in the layer chain.
Parent() Layer
+ // Platform returns the platform of the layer
+ Platform() Platform
+
// Size returns the size of the entire layer chain. The size
// is calculated from the total size of all files in the layers.
Size() (int64, error)
@@ -208,6 +219,7 @@ type MetadataTransaction interface {
SetDiffID(DiffID) error
SetCacheID(string) error
SetDescriptor(distribution.Descriptor) error
+ SetPlatform(Platform) error
TarSplitWriter(compressInput bool) (io.WriteCloser, error)
Commit(ChainID) error
@@ -228,6 +240,7 @@ type MetadataStore interface {
GetDiffID(ChainID) (DiffID, error)
GetCacheID(ChainID) (string, error)
GetDescriptor(ChainID) (distribution.Descriptor, error)
+ GetPlatform(ChainID) (Platform, error)
TarSplitReader(ChainID) (io.ReadCloser, error)
SetMountID(string, string) error
diff --git a/layer/layer_store.go b/layer/layer_store.go
index 25861c6669..4e3594ed60 100644
--- a/layer/layer_store.go
+++ b/layer/layer_store.go
@@ -144,6 +144,11 @@ func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) {
return nil, fmt.Errorf("failed to get descriptor for %s: %s", layer, err)
}
+ platform, err := ls.store.GetPlatform(layer)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get platform for %s: %s", layer, err)
+ }
+
cl = &roLayer{
chainID: layer,
diffID: diff,
@@ -152,6 +157,7 @@ func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) {
layerStore: ls,
references: map[Layer]struct{}{},
descriptor: descriptor,
+ platform: platform,
}
if parent != "" {
diff --git a/layer/ro_layer.go b/layer/ro_layer.go
index 8b4cf8f0de..e03d78b4db 100644
--- a/layer/ro_layer.go
+++ b/layer/ro_layer.go
@@ -16,6 +16,7 @@ type roLayer struct {
size int64
layerStore *layerStore
descriptor distribution.Descriptor
+ platform Platform
referenceCount int
references map[Layer]struct{}
@@ -142,6 +143,9 @@ func storeLayer(tx MetadataTransaction, layer *roLayer) error {
return err
}
}
+ if err := tx.SetPlatform(layer.platform); err != nil {
+ return err
+ }
return nil
}
diff --git a/layer/ro_layer_unix.go b/layer/ro_layer_unix.go
new file mode 100644
index 0000000000..1b36856f9e
--- /dev/null
+++ b/layer/ro_layer_unix.go
@@ -0,0 +1,7 @@
+// +build !windows
+
+package layer
+
+func (rl *roLayer) Platform() Platform {
+ return ""
+}
diff --git a/layer/ro_layer_windows.go b/layer/ro_layer_windows.go
index 32bd7182a3..6679bdfe8f 100644
--- a/layer/ro_layer_windows.go
+++ b/layer/ro_layer_windows.go
@@ -7,3 +7,10 @@ var _ distribution.Describable = &roLayer{}
func (rl *roLayer) Descriptor() distribution.Descriptor {
return rl.descriptor
}
+
+func (rl *roLayer) Platform() Platform {
+ if rl.platform == "" {
+ return "windows"
+ }
+ return rl.platform
+}