Browse code

LCOW: Store integrity checks

Signed-off-by: John Howard <jhoward@microsoft.com>

John Howard authored on 2017/05/20 02:38:47
Showing 5 changed files
... ...
@@ -654,6 +654,7 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
654 654
 			IDMappings:                idMappings,
655 655
 			PluginGetter:              d.PluginStore,
656 656
 			ExperimentalEnabled:       config.Experimental,
657
+			Platform:                  platform,
657 658
 		})
658 659
 		if err != nil {
659 660
 			return nil, err
... ...
@@ -3,11 +3,14 @@ package image
3 3
 import (
4 4
 	"encoding/json"
5 5
 	"fmt"
6
+	"runtime"
7
+	"strings"
6 8
 	"sync"
7 9
 
8 10
 	"github.com/Sirupsen/logrus"
9 11
 	"github.com/docker/distribution/digestset"
10 12
 	"github.com/docker/docker/layer"
13
+	"github.com/docker/docker/pkg/system"
11 14
 	"github.com/opencontainers/go-digest"
12 15
 	"github.com/pkg/errors"
13 16
 )
... ...
@@ -113,6 +116,13 @@ func (is *store) Create(config []byte) (ID, error) {
113 113
 		return "", err
114 114
 	}
115 115
 
116
+	// Integrity check - ensure we are creating something for the correct platform
117
+	if runtime.GOOS == "windows" && system.LCOWSupported() {
118
+		if strings.ToLower(img.Platform()) != strings.ToLower(is.platform) {
119
+			return "", fmt.Errorf("cannot create entry for platform %q in image store for platform %q", img.Platform(), is.platform)
120
+		}
121
+	}
122
+
116 123
 	// Must reject any config that references diffIDs from the history
117 124
 	// which aren't among the rootfs layers.
118 125
 	rootFSLayers := make(map[layer.DiffID]struct{})
... ...
@@ -5,6 +5,8 @@ import (
5 5
 	"fmt"
6 6
 	"io"
7 7
 	"io/ioutil"
8
+	"runtime"
9
+	"strings"
8 10
 	"sync"
9 11
 
10 12
 	"github.com/Sirupsen/logrus"
... ...
@@ -13,6 +15,7 @@ import (
13 13
 	"github.com/docker/docker/pkg/idtools"
14 14
 	"github.com/docker/docker/pkg/plugingetter"
15 15
 	"github.com/docker/docker/pkg/stringid"
16
+	"github.com/docker/docker/pkg/system"
16 17
 	"github.com/opencontainers/go-digest"
17 18
 	"github.com/vbatts/tar-split/tar/asm"
18 19
 	"github.com/vbatts/tar-split/tar/storage"
... ...
@@ -36,6 +39,8 @@ type layerStore struct {
36 36
 	mountL sync.Mutex
37 37
 
38 38
 	useTarSplit bool
39
+
40
+	platform string
39 41
 }
40 42
 
41 43
 // StoreOptions are the options used to create a new Store instance
... ...
@@ -47,6 +52,7 @@ type StoreOptions struct {
47 47
 	IDMappings                *idtools.IDMappings
48 48
 	PluginGetter              plugingetter.PluginGetter
49 49
 	ExperimentalEnabled       bool
50
+	Platform                  string
50 51
 }
51 52
 
52 53
 // NewStoreFromOptions creates a new Store instance
... ...
@@ -68,13 +74,13 @@ func NewStoreFromOptions(options StoreOptions) (Store, error) {
68 68
 		return nil, err
69 69
 	}
70 70
 
71
-	return NewStoreFromGraphDriver(fms, driver)
71
+	return NewStoreFromGraphDriver(fms, driver, options.Platform)
72 72
 }
73 73
 
74 74
 // NewStoreFromGraphDriver creates a new Store instance using the provided
75 75
 // metadata store and graph driver. The metadata store will be used to restore
76 76
 // the Store.
77
-func NewStoreFromGraphDriver(store MetadataStore, driver graphdriver.Driver) (Store, error) {
77
+func NewStoreFromGraphDriver(store MetadataStore, driver graphdriver.Driver, platform string) (Store, error) {
78 78
 	caps := graphdriver.Capabilities{}
79 79
 	if capDriver, ok := driver.(graphdriver.CapabilityDriver); ok {
80 80
 		caps = capDriver.Capabilities()
... ...
@@ -86,6 +92,7 @@ func NewStoreFromGraphDriver(store MetadataStore, driver graphdriver.Driver) (St
86 86
 		layerMap:    map[ChainID]*roLayer{},
87 87
 		mounts:      map[string]*mountedLayer{},
88 88
 		useTarSplit: !caps.ReproducesExactDiffs,
89
+		platform:    platform,
89 90
 	}
90 91
 
91 92
 	ids, mounts, err := store.List()
... ...
@@ -264,6 +271,14 @@ func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, platf
264 264
 	var err error
265 265
 	var pid string
266 266
 	var p *roLayer
267
+
268
+	// Integrity check - ensure we are creating something for the correct platform
269
+	if runtime.GOOS == "windows" && system.LCOWSupported() {
270
+		if strings.ToLower(ls.platform) != strings.ToLower(string(platform)) {
271
+			return nil, fmt.Errorf("cannot create entry for platform %q in layer store for platform %q", platform, ls.platform)
272
+		}
273
+	}
274
+
267 275
 	if string(parent) != "" {
268 276
 		p = ls.get(parent)
269 277
 		if p == nil {
... ...
@@ -71,7 +71,7 @@ func newTestStore(t *testing.T) (Store, string, func()) {
71 71
 	if err != nil {
72 72
 		t.Fatal(err)
73 73
 	}
74
-	ls, err := NewStoreFromGraphDriver(fms, graph)
74
+	ls, err := NewStoreFromGraphDriver(fms, graph, runtime.GOOS)
75 75
 	if err != nil {
76 76
 		t.Fatal(err)
77 77
 	}
... ...
@@ -404,7 +404,7 @@ func TestStoreRestore(t *testing.T) {
404 404
 		t.Fatal(err)
405 405
 	}
406 406
 
407
-	ls2, err := NewStoreFromGraphDriver(ls.(*layerStore).store, ls.(*layerStore).driver)
407
+	ls2, err := NewStoreFromGraphDriver(ls.(*layerStore).store, ls.(*layerStore).driver, runtime.GOOS)
408 408
 	if err != nil {
409 409
 		t.Fatal(err)
410 410
 	}
... ...
@@ -94,7 +94,7 @@ func TestLayerMigration(t *testing.T) {
94 94
 	if err != nil {
95 95
 		t.Fatal(err)
96 96
 	}
97
-	ls, err := NewStoreFromGraphDriver(fms, graph)
97
+	ls, err := NewStoreFromGraphDriver(fms, graph, runtime.GOOS)
98 98
 	if err != nil {
99 99
 		t.Fatal(err)
100 100
 	}
... ...
@@ -222,7 +222,7 @@ func TestLayerMigrationNoTarsplit(t *testing.T) {
222 222
 	if err != nil {
223 223
 		t.Fatal(err)
224 224
 	}
225
-	ls, err := NewStoreFromGraphDriver(fms, graph)
225
+	ls, err := NewStoreFromGraphDriver(fms, graph, runtime.GOOS)
226 226
 	if err != nil {
227 227
 		t.Fatal(err)
228 228
 	}