Browse code

Merge pull request #27915 from rhvgoyal/graph-create-opts

Pass all graphdriver create() parameters in a struct

Sebastiaan van Stijn authored on 2016/11/10 09:07:41
Showing 19 changed files
... ...
@@ -205,15 +205,15 @@ func (a *Driver) Exists(id string) bool {
205 205
 
206 206
 // CreateReadWrite creates a layer that is writable for use as a container
207 207
 // file system.
208
-func (a *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
209
-	return a.Create(id, parent, mountLabel, storageOpt)
208
+func (a *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
209
+	return a.Create(id, parent, opts)
210 210
 }
211 211
 
212 212
 // Create three folders for each id
213 213
 // mnt, layers, and diff
214
-func (a *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
214
+func (a *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
215 215
 
216
-	if len(storageOpt) != 0 {
216
+	if opts != nil && len(opts.StorageOpt) != 0 {
217 217
 		return fmt.Errorf("--storage-opt is not supported for aufs")
218 218
 	}
219 219
 
... ...
@@ -101,7 +101,7 @@ func TestCreateNewDir(t *testing.T) {
101 101
 	d := newDriver(t)
102 102
 	defer os.RemoveAll(tmp)
103 103
 
104
-	if err := d.Create("1", "", "", nil); err != nil {
104
+	if err := d.Create("1", "", nil); err != nil {
105 105
 		t.Fatal(err)
106 106
 	}
107 107
 }
... ...
@@ -110,7 +110,7 @@ func TestCreateNewDirStructure(t *testing.T) {
110 110
 	d := newDriver(t)
111 111
 	defer os.RemoveAll(tmp)
112 112
 
113
-	if err := d.Create("1", "", "", nil); err != nil {
113
+	if err := d.Create("1", "", nil); err != nil {
114 114
 		t.Fatal(err)
115 115
 	}
116 116
 
... ...
@@ -131,7 +131,7 @@ func TestRemoveImage(t *testing.T) {
131 131
 	d := newDriver(t)
132 132
 	defer os.RemoveAll(tmp)
133 133
 
134
-	if err := d.Create("1", "", "", nil); err != nil {
134
+	if err := d.Create("1", "", nil); err != nil {
135 135
 		t.Fatal(err)
136 136
 	}
137 137
 
... ...
@@ -156,7 +156,7 @@ func TestGetWithoutParent(t *testing.T) {
156 156
 	d := newDriver(t)
157 157
 	defer os.RemoveAll(tmp)
158 158
 
159
-	if err := d.Create("1", "", "", nil); err != nil {
159
+	if err := d.Create("1", "", nil); err != nil {
160 160
 		t.Fatal(err)
161 161
 	}
162 162
 
... ...
@@ -183,7 +183,7 @@ func TestCleanupWithDir(t *testing.T) {
183 183
 	d := newDriver(t)
184 184
 	defer os.RemoveAll(tmp)
185 185
 
186
-	if err := d.Create("1", "", "", nil); err != nil {
186
+	if err := d.Create("1", "", nil); err != nil {
187 187
 		t.Fatal(err)
188 188
 	}
189 189
 
... ...
@@ -196,7 +196,7 @@ func TestMountedFalseResponse(t *testing.T) {
196 196
 	d := newDriver(t)
197 197
 	defer os.RemoveAll(tmp)
198 198
 
199
-	if err := d.Create("1", "", "", nil); err != nil {
199
+	if err := d.Create("1", "", nil); err != nil {
200 200
 		t.Fatal(err)
201 201
 	}
202 202
 
... ...
@@ -215,10 +215,10 @@ func TestMountedTrueReponse(t *testing.T) {
215 215
 	defer os.RemoveAll(tmp)
216 216
 	defer d.Cleanup()
217 217
 
218
-	if err := d.Create("1", "", "", nil); err != nil {
218
+	if err := d.Create("1", "", nil); err != nil {
219 219
 		t.Fatal(err)
220 220
 	}
221
-	if err := d.Create("2", "1", "", nil); err != nil {
221
+	if err := d.Create("2", "1", nil); err != nil {
222 222
 		t.Fatal(err)
223 223
 	}
224 224
 
... ...
@@ -241,10 +241,10 @@ func TestMountWithParent(t *testing.T) {
241 241
 	d := newDriver(t)
242 242
 	defer os.RemoveAll(tmp)
243 243
 
244
-	if err := d.Create("1", "", "", nil); err != nil {
244
+	if err := d.Create("1", "", nil); err != nil {
245 245
 		t.Fatal(err)
246 246
 	}
247
-	if err := d.Create("2", "1", "", nil); err != nil {
247
+	if err := d.Create("2", "1", nil); err != nil {
248 248
 		t.Fatal(err)
249 249
 	}
250 250
 
... ...
@@ -272,10 +272,10 @@ func TestRemoveMountedDir(t *testing.T) {
272 272
 	d := newDriver(t)
273 273
 	defer os.RemoveAll(tmp)
274 274
 
275
-	if err := d.Create("1", "", "", nil); err != nil {
275
+	if err := d.Create("1", "", nil); err != nil {
276 276
 		t.Fatal(err)
277 277
 	}
278
-	if err := d.Create("2", "1", "", nil); err != nil {
278
+	if err := d.Create("2", "1", nil); err != nil {
279 279
 		t.Fatal(err)
280 280
 	}
281 281
 
... ...
@@ -311,7 +311,7 @@ func TestCreateWithInvalidParent(t *testing.T) {
311 311
 	d := newDriver(t)
312 312
 	defer os.RemoveAll(tmp)
313 313
 
314
-	if err := d.Create("1", "docker", "", nil); err == nil {
314
+	if err := d.Create("1", "docker", nil); err == nil {
315 315
 		t.Fatalf("Error should not be nil with parent does not exist")
316 316
 	}
317 317
 }
... ...
@@ -320,7 +320,7 @@ func TestGetDiff(t *testing.T) {
320 320
 	d := newDriver(t)
321 321
 	defer os.RemoveAll(tmp)
322 322
 
323
-	if err := d.CreateReadWrite("1", "", "", nil); err != nil {
323
+	if err := d.CreateReadWrite("1", "", nil); err != nil {
324 324
 		t.Fatal(err)
325 325
 	}
326 326
 
... ...
@@ -354,10 +354,11 @@ func TestChanges(t *testing.T) {
354 354
 	d := newDriver(t)
355 355
 	defer os.RemoveAll(tmp)
356 356
 
357
-	if err := d.Create("1", "", "", nil); err != nil {
357
+	if err := d.Create("1", "", nil); err != nil {
358 358
 		t.Fatal(err)
359 359
 	}
360
-	if err := d.CreateReadWrite("2", "1", "", nil); err != nil {
360
+
361
+	if err := d.CreateReadWrite("2", "1", nil); err != nil {
361 362
 		t.Fatal(err)
362 363
 	}
363 364
 
... ...
@@ -403,7 +404,7 @@ func TestChanges(t *testing.T) {
403 403
 		t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
404 404
 	}
405 405
 
406
-	if err := d.CreateReadWrite("3", "2", "", nil); err != nil {
406
+	if err := d.CreateReadWrite("3", "2", nil); err != nil {
407 407
 		t.Fatal(err)
408 408
 	}
409 409
 	mntPoint, err = d.Get("3", "")
... ...
@@ -448,7 +449,7 @@ func TestDiffSize(t *testing.T) {
448 448
 	d := newDriver(t)
449 449
 	defer os.RemoveAll(tmp)
450 450
 
451
-	if err := d.CreateReadWrite("1", "", "", nil); err != nil {
451
+	if err := d.CreateReadWrite("1", "", nil); err != nil {
452 452
 		t.Fatal(err)
453 453
 	}
454 454
 
... ...
@@ -490,7 +491,7 @@ func TestChildDiffSize(t *testing.T) {
490 490
 	defer os.RemoveAll(tmp)
491 491
 	defer d.Cleanup()
492 492
 
493
-	if err := d.CreateReadWrite("1", "", "", nil); err != nil {
493
+	if err := d.CreateReadWrite("1", "", nil); err != nil {
494 494
 		t.Fatal(err)
495 495
 	}
496 496
 
... ...
@@ -526,7 +527,7 @@ func TestChildDiffSize(t *testing.T) {
526 526
 		t.Fatalf("Expected size to be %d got %d", size, diffSize)
527 527
 	}
528 528
 
529
-	if err := d.Create("2", "1", "", nil); err != nil {
529
+	if err := d.Create("2", "1", nil); err != nil {
530 530
 		t.Fatal(err)
531 531
 	}
532 532
 
... ...
@@ -545,7 +546,7 @@ func TestExists(t *testing.T) {
545 545
 	defer os.RemoveAll(tmp)
546 546
 	defer d.Cleanup()
547 547
 
548
-	if err := d.Create("1", "", "", nil); err != nil {
548
+	if err := d.Create("1", "", nil); err != nil {
549 549
 		t.Fatal(err)
550 550
 	}
551 551
 
... ...
@@ -563,7 +564,7 @@ func TestStatus(t *testing.T) {
563 563
 	defer os.RemoveAll(tmp)
564 564
 	defer d.Cleanup()
565 565
 
566
-	if err := d.Create("1", "", "", nil); err != nil {
566
+	if err := d.Create("1", "", nil); err != nil {
567 567
 		t.Fatal(err)
568 568
 	}
569 569
 
... ...
@@ -592,7 +593,7 @@ func TestApplyDiff(t *testing.T) {
592 592
 	defer os.RemoveAll(tmp)
593 593
 	defer d.Cleanup()
594 594
 
595
-	if err := d.CreateReadWrite("1", "", "", nil); err != nil {
595
+	if err := d.CreateReadWrite("1", "", nil); err != nil {
596 596
 		t.Fatal(err)
597 597
 	}
598 598
 
... ...
@@ -618,10 +619,10 @@ func TestApplyDiff(t *testing.T) {
618 618
 		t.Fatal(err)
619 619
 	}
620 620
 
621
-	if err := d.Create("2", "", "", nil); err != nil {
621
+	if err := d.Create("2", "", nil); err != nil {
622 622
 		t.Fatal(err)
623 623
 	}
624
-	if err := d.Create("3", "2", "", nil); err != nil {
624
+	if err := d.Create("3", "2", nil); err != nil {
625 625
 		t.Fatal(err)
626 626
 	}
627 627
 
... ...
@@ -671,7 +672,7 @@ func testMountMoreThan42Layers(t *testing.T, mountPath string) {
671 671
 		}
672 672
 		current = hash(current)
673 673
 
674
-		if err := d.CreateReadWrite(current, parent, "", nil); err != nil {
674
+		if err := d.CreateReadWrite(current, parent, nil); err != nil {
675 675
 			t.Logf("Current layer %d", i)
676 676
 			t.Error(err)
677 677
 		}
... ...
@@ -750,11 +751,11 @@ func BenchmarkConcurrentAccess(b *testing.B) {
750 750
 		ids = append(ids, stringid.GenerateNonCryptoID())
751 751
 	}
752 752
 
753
-	if err := d.Create(ids[0], "", "", nil); err != nil {
753
+	if err := d.Create(ids[0], "", nil); err != nil {
754 754
 		b.Fatal(err)
755 755
 	}
756 756
 
757
-	if err := d.Create(ids[1], ids[0], "", nil); err != nil {
757
+	if err := d.Create(ids[1], ids[0], nil); err != nil {
758 758
 		b.Fatal(err)
759 759
 	}
760 760
 
... ...
@@ -770,7 +771,7 @@ func BenchmarkConcurrentAccess(b *testing.B) {
770 770
 	for _, id := range ids {
771 771
 		go func(id string) {
772 772
 			defer outerGroup.Done()
773
-			if err := d.Create(id, parent, "", nil); err != nil {
773
+			if err := d.Create(id, parent, nil); err != nil {
774 774
 				b.Logf("Create %s failed", id)
775 775
 				chErr <- err
776 776
 				return
... ...
@@ -376,12 +376,12 @@ func (d *Driver) subvolumesDirID(id string) string {
376 376
 
377 377
 // CreateReadWrite creates a layer that is writable for use as a container
378 378
 // file system.
379
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
380
-	return d.Create(id, parent, mountLabel, storageOpt)
379
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
380
+	return d.Create(id, parent, opts)
381 381
 }
382 382
 
383 383
 // Create the filesystem with given id.
384
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
384
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
385 385
 	subvolumes := path.Join(d.home, "subvolumes")
386 386
 	rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
387 387
 	if err != nil {
... ...
@@ -408,6 +408,11 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
408 408
 		}
409 409
 	}
410 410
 
411
+	var storageOpt map[string]string
412
+	if opts != nil {
413
+		storageOpt = opts.StorageOpt
414
+	}
415
+
411 416
 	if _, ok := storageOpt["size"]; ok {
412 417
 		driver := &Driver{}
413 418
 		if err := d.parseStorageOpt(storageOpt, driver); err != nil {
... ...
@@ -426,6 +431,11 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
426 426
 		}
427 427
 	}
428 428
 
429
+	mountLabel := ""
430
+	if opts != nil {
431
+		mountLabel = opts.MountLabel
432
+	}
433
+
429 434
 	return label.Relabel(path.Join(subvolumes, id), mountLabel, false)
430 435
 }
431 436
 
... ...
@@ -30,7 +30,7 @@ func TestBtrfsCreateSnap(t *testing.T) {
30 30
 
31 31
 func TestBtrfsSubvolDelete(t *testing.T) {
32 32
 	d := graphtest.GetDriver(t, "btrfs")
33
-	if err := d.CreateReadWrite("test", "", "", nil); err != nil {
33
+	if err := d.CreateReadWrite("test", "", nil); err != nil {
34 34
 		t.Fatal(err)
35 35
 	}
36 36
 	defer graphtest.PutDriver(t)
... ...
@@ -122,12 +122,17 @@ func (d *Driver) Cleanup() error {
122 122
 
123 123
 // CreateReadWrite creates a layer that is writable for use as a container
124 124
 // file system.
125
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
126
-	return d.Create(id, parent, mountLabel, storageOpt)
125
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
126
+	return d.Create(id, parent, opts)
127 127
 }
128 128
 
129 129
 // Create adds a device with a given id and the parent.
130
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
130
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
131
+	var storageOpt map[string]string
132
+	if opts != nil {
133
+		storageOpt = opts.StorageOpt
134
+	}
135
+
131 136
 	if err := d.DeviceSet.AddDevice(id, parent, storageOpt); err != nil {
132 137
 		return err
133 138
 	}
... ...
@@ -36,6 +36,13 @@ var (
36 36
 	ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
37 37
 )
38 38
 
39
+//CreateOpts contains optional arguments for Create() and CreateReadWrite()
40
+// methods.
41
+type CreateOpts struct {
42
+	MountLabel string
43
+	StorageOpt map[string]string
44
+}
45
+
39 46
 // InitFunc initializes the storage driver.
40 47
 type InitFunc func(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (Driver, error)
41 48
 
... ...
@@ -49,11 +56,13 @@ type ProtoDriver interface {
49 49
 	// String returns a string representation of this driver.
50 50
 	String() string
51 51
 	// CreateReadWrite creates a new, empty filesystem layer that is ready
52
-	// to be used as the storage for a container.
53
-	CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error
52
+	// to be used as the storage for a container. Additional options can
53
+	// be passed in opts. parent may be "" and opts may be nil.
54
+	CreateReadWrite(id, parent string, opts *CreateOpts) error
54 55
 	// Create creates a new, empty, filesystem layer with the
55
-	// specified id and parent and mountLabel. Parent and mountLabel may be "".
56
-	Create(id, parent, mountLabel string, storageOpt map[string]string) error
56
+	// specified id and parent and options passed in opts. Parent
57
+	// may be "" and opts may be nil.
58
+	Create(id, parent string, opts *CreateOpts) error
57 59
 	// Remove attempts to remove the filesystem layer with this id.
58 60
 	Remove(id string) error
59 61
 	// Get returns the mountpoint for the layered filesystem referred
... ...
@@ -19,7 +19,7 @@ func DriverBenchExists(b *testing.B, drivername string, driveroptions ...string)
19 19
 
20 20
 	base := stringid.GenerateRandomID()
21 21
 
22
-	if err := driver.Create(base, "", "", nil); err != nil {
22
+	if err := driver.Create(base, "", nil); err != nil {
23 23
 		b.Fatal(err)
24 24
 	}
25 25
 
... ...
@@ -38,7 +38,7 @@ func DriverBenchGetEmpty(b *testing.B, drivername string, driveroptions ...strin
38 38
 
39 39
 	base := stringid.GenerateRandomID()
40 40
 
41
-	if err := driver.Create(base, "", "", nil); err != nil {
41
+	if err := driver.Create(base, "", nil); err != nil {
42 42
 		b.Fatal(err)
43 43
 	}
44 44
 
... ...
@@ -62,8 +62,7 @@ func DriverBenchDiffBase(b *testing.B, drivername string, driveroptions ...strin
62 62
 	defer PutDriver(b)
63 63
 
64 64
 	base := stringid.GenerateRandomID()
65
-
66
-	if err := driver.Create(base, "", "", nil); err != nil {
65
+	if err := driver.Create(base, "", nil); err != nil {
67 66
 		b.Fatal(err)
68 67
 	}
69 68
 
... ...
@@ -92,8 +91,7 @@ func DriverBenchDiffN(b *testing.B, bottom, top int, drivername string, driverop
92 92
 	defer PutDriver(b)
93 93
 	base := stringid.GenerateRandomID()
94 94
 	upper := stringid.GenerateRandomID()
95
-
96
-	if err := driver.Create(base, "", "", nil); err != nil {
95
+	if err := driver.Create(base, "", nil); err != nil {
97 96
 		b.Fatal(err)
98 97
 	}
99 98
 
... ...
@@ -101,7 +99,7 @@ func DriverBenchDiffN(b *testing.B, bottom, top int, drivername string, driverop
101 101
 		b.Fatal(err)
102 102
 	}
103 103
 
104
-	if err := driver.Create(upper, base, "", nil); err != nil {
104
+	if err := driver.Create(upper, base, nil); err != nil {
105 105
 		b.Fatal(err)
106 106
 	}
107 107
 
... ...
@@ -128,8 +126,7 @@ func DriverBenchDiffApplyN(b *testing.B, fileCount int, drivername string, drive
128 128
 	defer PutDriver(b)
129 129
 	base := stringid.GenerateRandomID()
130 130
 	upper := stringid.GenerateRandomID()
131
-
132
-	if err := driver.Create(base, "", "", nil); err != nil {
131
+	if err := driver.Create(base, "", nil); err != nil {
133 132
 		b.Fatal(err)
134 133
 	}
135 134
 
... ...
@@ -137,7 +134,7 @@ func DriverBenchDiffApplyN(b *testing.B, fileCount int, drivername string, drive
137 137
 		b.Fatal(err)
138 138
 	}
139 139
 
140
-	if err := driver.Create(upper, base, "", nil); err != nil {
140
+	if err := driver.Create(upper, base, nil); err != nil {
141 141
 		b.Fatal(err)
142 142
 	}
143 143
 
... ...
@@ -152,7 +149,7 @@ func DriverBenchDiffApplyN(b *testing.B, fileCount int, drivername string, drive
152 152
 	b.StopTimer()
153 153
 	for i := 0; i < b.N; i++ {
154 154
 		diff := stringid.GenerateRandomID()
155
-		if err := driver.Create(diff, base, "", nil); err != nil {
155
+		if err := driver.Create(diff, base, nil); err != nil {
156 156
 			b.Fatal(err)
157 157
 		}
158 158
 
... ...
@@ -191,8 +188,7 @@ func DriverBenchDeepLayerDiff(b *testing.B, layerCount int, drivername string, d
191 191
 	defer PutDriver(b)
192 192
 
193 193
 	base := stringid.GenerateRandomID()
194
-
195
-	if err := driver.Create(base, "", "", nil); err != nil {
194
+	if err := driver.Create(base, "", nil); err != nil {
196 195
 		b.Fatal(err)
197 196
 	}
198 197
 
... ...
@@ -225,8 +221,7 @@ func DriverBenchDeepLayerRead(b *testing.B, layerCount int, drivername string, d
225 225
 	defer PutDriver(b)
226 226
 
227 227
 	base := stringid.GenerateRandomID()
228
-
229
-	if err := driver.Create(base, "", "", nil); err != nil {
228
+	if err := driver.Create(base, "", nil); err != nil {
230 229
 		b.Fatal(err)
231 230
 	}
232 231
 
... ...
@@ -86,7 +86,7 @@ func DriverTestCreateEmpty(t testing.TB, drivername string, driverOptions ...str
86 86
 	driver := GetDriver(t, drivername, driverOptions...)
87 87
 	defer PutDriver(t)
88 88
 
89
-	if err := driver.Create("empty", "", "", nil); err != nil {
89
+	if err := driver.Create("empty", "", nil); err != nil {
90 90
 		t.Fatal(err)
91 91
 	}
92 92
 
... ...
@@ -147,7 +147,7 @@ func DriverTestCreateSnap(t testing.TB, drivername string, driverOptions ...stri
147 147
 		}
148 148
 	}()
149 149
 
150
-	if err := driver.Create("Snap", "Base", "", nil); err != nil {
150
+	if err := driver.Create("Snap", "Base", nil); err != nil {
151 151
 		t.Fatal(err)
152 152
 	}
153 153
 
... ...
@@ -166,8 +166,7 @@ func DriverTestDeepLayerRead(t testing.TB, layerCount int, drivername string, dr
166 166
 	defer PutDriver(t)
167 167
 
168 168
 	base := stringid.GenerateRandomID()
169
-
170
-	if err := driver.Create(base, "", "", nil); err != nil {
169
+	if err := driver.Create(base, "", nil); err != nil {
171 170
 		t.Fatal(err)
172 171
 	}
173 172
 
... ...
@@ -201,7 +200,7 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
201 201
 	deleteFileContent := []byte("This file should get removed in upper!")
202 202
 	deleteDir := "var/lib"
203 203
 
204
-	if err := driver.Create(base, "", "", nil); err != nil {
204
+	if err := driver.Create(base, "", nil); err != nil {
205 205
 		t.Fatal(err)
206 206
 	}
207 207
 
... ...
@@ -217,7 +216,7 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
217 217
 		t.Fatal(err)
218 218
 	}
219 219
 
220
-	if err := driver.Create(upper, base, "", nil); err != nil {
220
+	if err := driver.Create(upper, base, nil); err != nil {
221 221
 		t.Fatal(err)
222 222
 	}
223 223
 
... ...
@@ -235,7 +234,7 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
235 235
 	}
236 236
 
237 237
 	diff := stringid.GenerateRandomID()
238
-	if err := driver.Create(diff, base, "", nil); err != nil {
238
+	if err := driver.Create(diff, base, nil); err != nil {
239 239
 		t.Fatal(err)
240 240
 	}
241 241
 
... ...
@@ -288,8 +287,7 @@ func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string)
288 288
 	defer PutDriver(t)
289 289
 	base := stringid.GenerateRandomID()
290 290
 	upper := stringid.GenerateRandomID()
291
-
292
-	if err := driver.Create(base, "", "", nil); err != nil {
291
+	if err := driver.Create(base, "", nil); err != nil {
293 292
 		t.Fatal(err)
294 293
 	}
295 294
 
... ...
@@ -297,7 +295,7 @@ func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string)
297 297
 		t.Fatal(err)
298 298
 	}
299 299
 
300
-	if err := driver.Create(upper, base, "", nil); err != nil {
300
+	if err := driver.Create(upper, base, nil); err != nil {
301 301
 		t.Fatal(err)
302 302
 	}
303 303
 
... ...
@@ -339,9 +337,10 @@ func DriverTestSetQuota(t *testing.T, drivername string) {
339 339
 	defer PutDriver(t)
340 340
 
341 341
 	createBase(t, driver, "Base")
342
-	storageOpt := make(map[string]string, 1)
343
-	storageOpt["size"] = "50M"
344
-	if err := driver.Create("zfsTest", "Base", "", storageOpt); err != nil {
342
+	createOpts := &graphdriver.CreateOpts{}
343
+	createOpts.StorageOpt = make(map[string]string, 1)
344
+	createOpts.StorageOpt["size"] = "50M"
345
+	if err := driver.Create("zfsTest", "Base", createOpts); err != nil {
345 346
 		t.Fatal(err)
346 347
 	}
347 348
 
... ...
@@ -275,7 +275,7 @@ func addManyLayers(drv graphdriver.Driver, baseLayer string, count int) (string,
275 275
 	lastLayer := baseLayer
276 276
 	for i := 1; i <= count; i++ {
277 277
 		nextLayer := stringid.GenerateRandomID()
278
-		if err := drv.Create(nextLayer, lastLayer, "", nil); err != nil {
278
+		if err := drv.Create(nextLayer, lastLayer, nil); err != nil {
279 279
 			return "", err
280 280
 		}
281 281
 		if err := addLayerFiles(drv, nextLayer, lastLayer, i); err != nil {
... ...
@@ -94,7 +94,7 @@ func createBase(t testing.TB, driver graphdriver.Driver, name string) {
94 94
 	oldmask := syscall.Umask(0)
95 95
 	defer syscall.Umask(oldmask)
96 96
 
97
-	if err := driver.CreateReadWrite(name, "", "", nil); err != nil {
97
+	if err := driver.CreateReadWrite(name, "", nil); err != nil {
98 98
 		t.Fatal(err)
99 99
 	}
100 100
 
... ...
@@ -231,15 +231,15 @@ func (d *Driver) Cleanup() error {
231 231
 
232 232
 // CreateReadWrite creates a layer that is writable for use as a container
233 233
 // file system.
234
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
235
-	return d.Create(id, parent, mountLabel, storageOpt)
234
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
235
+	return d.Create(id, parent, opts)
236 236
 }
237 237
 
238 238
 // Create is used to create the upper, lower, and merge directories required for overlay fs for a given id.
239 239
 // The parent filesystem is used to configure these directories for the overlay.
240
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) (retErr error) {
240
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) {
241 241
 
242
-	if len(storageOpt) != 0 {
242
+	if opts != nil && len(opts.StorageOpt) != 0 {
243 243
 		return fmt.Errorf("--storage-opt is not supported for overlay")
244 244
 	}
245 245
 
... ...
@@ -282,15 +282,15 @@ func (d *Driver) Cleanup() error {
282 282
 
283 283
 // CreateReadWrite creates a layer that is writable for use as a container
284 284
 // file system.
285
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
286
-	return d.Create(id, parent, mountLabel, storageOpt)
285
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
286
+	return d.Create(id, parent, opts)
287 287
 }
288 288
 
289 289
 // Create is used to create the upper, lower, and merge directories required for overlay fs for a given id.
290 290
 // The parent filesystem is used to configure these directories for the overlay.
291
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) (retErr error) {
291
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) {
292 292
 
293
-	if len(storageOpt) != 0 && !projectQuotaSupported {
293
+	if opts != nil && len(opts.StorageOpt) != 0 && !projectQuotaSupported {
294 294
 		return fmt.Errorf("--storage-opt is supported only for overlay over xfs with 'pquota' mount option")
295 295
 	}
296 296
 
... ...
@@ -314,9 +314,9 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
314 314
 		}
315 315
 	}()
316 316
 
317
-	if len(storageOpt) > 0 {
317
+	if opts != nil && len(opts.StorageOpt) > 0 {
318 318
 		driver := &Driver{}
319
-		if err := d.parseStorageOpt(storageOpt, driver); err != nil {
319
+		if err := d.parseStorageOpt(opts.StorageOpt, driver); err != nil {
320 320
 			return err
321 321
 		}
322 322
 
... ...
@@ -53,7 +53,12 @@ func (d *graphDriverProxy) String() string {
53 53
 	return d.name
54 54
 }
55 55
 
56
-func (d *graphDriverProxy) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
56
+func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error {
57
+	mountLabel := ""
58
+	if opts != nil {
59
+		mountLabel = opts.MountLabel
60
+	}
61
+
57 62
 	args := &graphDriverRequest{
58 63
 		ID:         id,
59 64
 		Parent:     parent,
... ...
@@ -69,7 +74,11 @@ func (d *graphDriverProxy) CreateReadWrite(id, parent, mountLabel string, storag
69 69
 	return nil
70 70
 }
71 71
 
72
-func (d *graphDriverProxy) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
72
+func (d *graphDriverProxy) Create(id, parent string, opts *CreateOpts) error {
73
+	mountLabel := ""
74
+	if opts != nil {
75
+		mountLabel = opts.MountLabel
76
+	}
73 77
 	args := &graphDriverRequest{
74 78
 		ID:         id,
75 79
 		Parent:     parent,
... ...
@@ -70,13 +70,13 @@ func (d *Driver) Cleanup() error {
70 70
 
71 71
 // CreateReadWrite creates a layer that is writable for use as a container
72 72
 // file system.
73
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
74
-	return d.Create(id, parent, mountLabel, storageOpt)
73
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
74
+	return d.Create(id, parent, opts)
75 75
 }
76 76
 
77 77
 // Create prepares the filesystem for the VFS driver and copies the directory for the given id under the parent.
78
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
79
-	if len(storageOpt) != 0 {
78
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
79
+	if opts != nil && len(opts.StorageOpt) != 0 {
80 80
 		return fmt.Errorf("--storage-opt is not supported for vfs")
81 81
 	}
82 82
 
... ...
@@ -91,8 +91,8 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
91 91
 	if err := idtools.MkdirAs(dir, 0755, rootUID, rootGID); err != nil {
92 92
 		return err
93 93
 	}
94
-	opts := []string{"level:s0"}
95
-	if _, mountLabel, err := label.InitLabels(opts); err == nil {
94
+	labelOpts := []string{"level:s0"}
95
+	if _, mountLabel, err := label.InitLabels(labelOpts); err == nil {
96 96
 		label.SetFileLabel(dir, mountLabel)
97 97
 	}
98 98
 	if parent == "" {
... ...
@@ -161,13 +161,21 @@ func (d *Driver) Exists(id string) bool {
161 161
 
162 162
 // CreateReadWrite creates a layer that is writable for use as a container
163 163
 // file system.
164
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
165
-	return d.create(id, parent, mountLabel, false, storageOpt)
164
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
165
+	if opts != nil {
166
+		return d.create(id, parent, opts.MountLabel, false, opts.StorageOpt)
167
+	} else {
168
+		return d.create(id, parent, "", false, nil)
169
+	}
166 170
 }
167 171
 
168 172
 // Create creates a new read-only layer with the given id.
169
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
170
-	return d.create(id, parent, mountLabel, true, storageOpt)
173
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
174
+	if opts != nil {
175
+		return d.create(id, parent, opts.MountLabel, true, opts.StorageOpt)
176
+	} else {
177
+		return d.create(id, parent, "", true, nil)
178
+	}
171 179
 }
172 180
 
173 181
 func (d *Driver) create(id, parent, mountLabel string, readOnly bool, storageOpt map[string]string) error {
... ...
@@ -255,12 +255,17 @@ func (d *Driver) mountPath(id string) string {
255 255
 
256 256
 // CreateReadWrite creates a layer that is writable for use as a container
257 257
 // file system.
258
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
259
-	return d.Create(id, parent, mountLabel, storageOpt)
258
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
259
+	return d.Create(id, parent, opts)
260 260
 }
261 261
 
262 262
 // Create prepares the dataset and filesystem for the ZFS driver for the given id under the parent.
263
-func (d *Driver) Create(id string, parent string, mountLabel string, storageOpt map[string]string) error {
263
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
264
+	var storageOpt map[string]string
265
+	if opts != nil {
266
+		storageOpt = opts.StorageOpt
267
+	}
268
+
264 269
 	err := d.create(id, parent, storageOpt)
265 270
 	if err == nil {
266 271
 		return nil
... ...
@@ -145,7 +145,7 @@ func (s *DockerExternalGraphdriverSuite) setUpPlugin(c *check.C, name string, ex
145 145
 		if err := decReq(r.Body, &req, w); err != nil {
146 146
 			return
147 147
 		}
148
-		if err := driver.CreateReadWrite(req.ID, req.Parent, "", nil); err != nil {
148
+		if err := driver.CreateReadWrite(req.ID, req.Parent, nil); err != nil {
149 149
 			respond(w, err)
150 150
 			return
151 151
 		}
... ...
@@ -159,7 +159,7 @@ func (s *DockerExternalGraphdriverSuite) setUpPlugin(c *check.C, name string, ex
159 159
 		if err := decReq(r.Body, &req, w); err != nil {
160 160
 			return
161 161
 		}
162
-		if err := driver.Create(req.ID, req.Parent, "", nil); err != nil {
162
+		if err := driver.Create(req.ID, req.Parent, nil); err != nil {
163 163
 			respond(w, err)
164 164
 			return
165 165
 		}
... ...
@@ -277,7 +277,7 @@ func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, descr
277 277
 		descriptor:     descriptor,
278 278
 	}
279 279
 
280
-	if err = ls.driver.Create(layer.cacheID, pid, "", nil); err != nil {
280
+	if err = ls.driver.Create(layer.cacheID, pid, nil); err != nil {
281 281
 		return nil, err
282 282
 	}
283 283
 
... ...
@@ -488,7 +488,11 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, mountLabel stri
488 488
 		m.initID = pid
489 489
 	}
490 490
 
491
-	if err = ls.driver.CreateReadWrite(m.mountID, pid, "", storageOpt); err != nil {
491
+	createOpts := &graphdriver.CreateOpts{
492
+		StorageOpt: storageOpt,
493
+	}
494
+
495
+	if err = ls.driver.CreateReadWrite(m.mountID, pid, createOpts); err != nil {
492 496
 		return nil, err
493 497
 	}
494 498
 
... ...
@@ -598,7 +602,12 @@ func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc Mou
598 598
 	// then the initID should be randomly generated.
599 599
 	initID := fmt.Sprintf("%s-init", graphID)
600 600
 
601
-	if err := ls.driver.CreateReadWrite(initID, parent, mountLabel, storageOpt); err != nil {
601
+	createOpts := &graphdriver.CreateOpts{
602
+		MountLabel: mountLabel,
603
+		StorageOpt: storageOpt,
604
+	}
605
+
606
+	if err := ls.driver.CreateReadWrite(initID, parent, createOpts); err != nil {
602 607
 		return "", err
603 608
 	}
604 609
 	p, err := ls.driver.Get(initID, "")
... ...
@@ -78,7 +78,7 @@ func TestLayerMigration(t *testing.T) {
78 78
 	}
79 79
 
80 80
 	graphID1 := stringid.GenerateRandomID()
81
-	if err := graph.Create(graphID1, "", "", nil); err != nil {
81
+	if err := graph.Create(graphID1, "", nil); err != nil {
82 82
 		t.Fatal(err)
83 83
 	}
84 84
 	if _, err := graph.ApplyDiff(graphID1, "", bytes.NewReader(tar1)); err != nil {
... ...
@@ -123,7 +123,7 @@ func TestLayerMigration(t *testing.T) {
123 123
 	}
124 124
 
125 125
 	graphID2 := stringid.GenerateRandomID()
126
-	if err := graph.Create(graphID2, graphID1, "", nil); err != nil {
126
+	if err := graph.Create(graphID2, graphID1, nil); err != nil {
127 127
 		t.Fatal(err)
128 128
 	}
129 129
 	if _, err := graph.ApplyDiff(graphID2, graphID1, bytes.NewReader(tar2)); err != nil {
... ...
@@ -165,7 +165,7 @@ func tarFromFilesInGraph(graph graphdriver.Driver, graphID, parentID string, fil
165 165
 		return nil, err
166 166
 	}
167 167
 
168
-	if err := graph.Create(graphID, parentID, "", nil); err != nil {
168
+	if err := graph.Create(graphID, parentID, nil); err != nil {
169 169
 		return nil, err
170 170
 	}
171 171
 	if _, err := graph.ApplyDiff(graphID, parentID, bytes.NewReader(t)); err != nil {
... ...
@@ -320,14 +320,14 @@ func TestMountMigration(t *testing.T) {
320 320
 	containerID := stringid.GenerateRandomID()
321 321
 	containerInit := fmt.Sprintf("%s-init", containerID)
322 322
 
323
-	if err := graph.Create(containerInit, graphID1, "", nil); err != nil {
323
+	if err := graph.Create(containerInit, graphID1, nil); err != nil {
324 324
 		t.Fatal(err)
325 325
 	}
326 326
 	if _, err := graph.ApplyDiff(containerInit, graphID1, bytes.NewReader(initTar)); err != nil {
327 327
 		t.Fatal(err)
328 328
 	}
329 329
 
330
-	if err := graph.Create(containerID, containerInit, "", nil); err != nil {
330
+	if err := graph.Create(containerID, containerInit, nil); err != nil {
331 331
 		t.Fatal(err)
332 332
 	}
333 333
 	if _, err := graph.ApplyDiff(containerID, containerInit, bytes.NewReader(mountTar)); err != nil {