Ver código fonte

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

Pass all graphdriver create() parameters in a struct
Sebastiaan van Stijn 8 anos atrás
pai
commit
f11ac963af

+ 4 - 4
daemon/graphdriver/aufs/aufs.go

@@ -205,15 +205,15 @@ func (a *Driver) Exists(id string) bool {
 
 // CreateReadWrite creates a layer that is writable for use as a container
 // file system.
-func (a *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
-	return a.Create(id, parent, mountLabel, storageOpt)
+func (a *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
+	return a.Create(id, parent, opts)
 }
 
 // Create three folders for each id
 // mnt, layers, and diff
-func (a *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
+func (a *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
 
-	if len(storageOpt) != 0 {
+	if opts != nil && len(opts.StorageOpt) != 0 {
 		return fmt.Errorf("--storage-opt is not supported for aufs")
 	}
 

+ 30 - 29
daemon/graphdriver/aufs/aufs_test.go

@@ -101,7 +101,7 @@ func TestCreateNewDir(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -110,7 +110,7 @@ func TestCreateNewDirStructure(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -131,7 +131,7 @@ func TestRemoveImage(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -156,7 +156,7 @@ func TestGetWithoutParent(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -183,7 +183,7 @@ func TestCleanupWithDir(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -196,7 +196,7 @@ func TestMountedFalseResponse(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -215,10 +215,10 @@ func TestMountedTrueReponse(t *testing.T) {
 	defer os.RemoveAll(tmp)
 	defer d.Cleanup()
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
-	if err := d.Create("2", "1", "", nil); err != nil {
+	if err := d.Create("2", "1", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -241,10 +241,10 @@ func TestMountWithParent(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
-	if err := d.Create("2", "1", "", nil); err != nil {
+	if err := d.Create("2", "1", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -272,10 +272,10 @@ func TestRemoveMountedDir(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
-	if err := d.Create("2", "1", "", nil); err != nil {
+	if err := d.Create("2", "1", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -311,7 +311,7 @@ func TestCreateWithInvalidParent(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "docker", "", nil); err == nil {
+	if err := d.Create("1", "docker", nil); err == nil {
 		t.Fatalf("Error should not be nil with parent does not exist")
 	}
 }
@@ -320,7 +320,7 @@ func TestGetDiff(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.CreateReadWrite("1", "", "", nil); err != nil {
+	if err := d.CreateReadWrite("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -354,10 +354,11 @@ func TestChanges(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
-	if err := d.CreateReadWrite("2", "1", "", nil); err != nil {
+
+	if err := d.CreateReadWrite("2", "1", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -403,7 +404,7 @@ func TestChanges(t *testing.T) {
 		t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
 	}
 
-	if err := d.CreateReadWrite("3", "2", "", nil); err != nil {
+	if err := d.CreateReadWrite("3", "2", nil); err != nil {
 		t.Fatal(err)
 	}
 	mntPoint, err = d.Get("3", "")
@@ -448,7 +449,7 @@ func TestDiffSize(t *testing.T) {
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.CreateReadWrite("1", "", "", nil); err != nil {
+	if err := d.CreateReadWrite("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -490,7 +491,7 @@ func TestChildDiffSize(t *testing.T) {
 	defer os.RemoveAll(tmp)
 	defer d.Cleanup()
 
-	if err := d.CreateReadWrite("1", "", "", nil); err != nil {
+	if err := d.CreateReadWrite("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -526,7 +527,7 @@ func TestChildDiffSize(t *testing.T) {
 		t.Fatalf("Expected size to be %d got %d", size, diffSize)
 	}
 
-	if err := d.Create("2", "1", "", nil); err != nil {
+	if err := d.Create("2", "1", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -545,7 +546,7 @@ func TestExists(t *testing.T) {
 	defer os.RemoveAll(tmp)
 	defer d.Cleanup()
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -563,7 +564,7 @@ func TestStatus(t *testing.T) {
 	defer os.RemoveAll(tmp)
 	defer d.Cleanup()
 
-	if err := d.Create("1", "", "", nil); err != nil {
+	if err := d.Create("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -592,7 +593,7 @@ func TestApplyDiff(t *testing.T) {
 	defer os.RemoveAll(tmp)
 	defer d.Cleanup()
 
-	if err := d.CreateReadWrite("1", "", "", nil); err != nil {
+	if err := d.CreateReadWrite("1", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -618,10 +619,10 @@ func TestApplyDiff(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if err := d.Create("2", "", "", nil); err != nil {
+	if err := d.Create("2", "", nil); err != nil {
 		t.Fatal(err)
 	}
-	if err := d.Create("3", "2", "", nil); err != nil {
+	if err := d.Create("3", "2", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -671,7 +672,7 @@ func testMountMoreThan42Layers(t *testing.T, mountPath string) {
 		}
 		current = hash(current)
 
-		if err := d.CreateReadWrite(current, parent, "", nil); err != nil {
+		if err := d.CreateReadWrite(current, parent, nil); err != nil {
 			t.Logf("Current layer %d", i)
 			t.Error(err)
 		}
@@ -750,11 +751,11 @@ func BenchmarkConcurrentAccess(b *testing.B) {
 		ids = append(ids, stringid.GenerateNonCryptoID())
 	}
 
-	if err := d.Create(ids[0], "", "", nil); err != nil {
+	if err := d.Create(ids[0], "", nil); err != nil {
 		b.Fatal(err)
 	}
 
-	if err := d.Create(ids[1], ids[0], "", nil); err != nil {
+	if err := d.Create(ids[1], ids[0], nil); err != nil {
 		b.Fatal(err)
 	}
 
@@ -770,7 +771,7 @@ func BenchmarkConcurrentAccess(b *testing.B) {
 	for _, id := range ids {
 		go func(id string) {
 			defer outerGroup.Done()
-			if err := d.Create(id, parent, "", nil); err != nil {
+			if err := d.Create(id, parent, nil); err != nil {
 				b.Logf("Create %s failed", id)
 				chErr <- err
 				return

+ 13 - 3
daemon/graphdriver/btrfs/btrfs.go

@@ -376,12 +376,12 @@ func (d *Driver) subvolumesDirID(id string) string {
 
 // CreateReadWrite creates a layer that is writable for use as a container
 // file system.
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
-	return d.Create(id, parent, mountLabel, storageOpt)
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
+	return d.Create(id, parent, opts)
 }
 
 // Create the filesystem with given id.
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
 	subvolumes := path.Join(d.home, "subvolumes")
 	rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
 	if err != nil {
@@ -408,6 +408,11 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
 		}
 	}
 
+	var storageOpt map[string]string
+	if opts != nil {
+		storageOpt = opts.StorageOpt
+	}
+
 	if _, ok := storageOpt["size"]; ok {
 		driver := &Driver{}
 		if err := d.parseStorageOpt(storageOpt, driver); err != nil {
@@ -426,6 +431,11 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
 		}
 	}
 
+	mountLabel := ""
+	if opts != nil {
+		mountLabel = opts.MountLabel
+	}
+
 	return label.Relabel(path.Join(subvolumes, id), mountLabel, false)
 }
 

+ 1 - 1
daemon/graphdriver/btrfs/btrfs_test.go

@@ -30,7 +30,7 @@ func TestBtrfsCreateSnap(t *testing.T) {
 
 func TestBtrfsSubvolDelete(t *testing.T) {
 	d := graphtest.GetDriver(t, "btrfs")
-	if err := d.CreateReadWrite("test", "", "", nil); err != nil {
+	if err := d.CreateReadWrite("test", "", nil); err != nil {
 		t.Fatal(err)
 	}
 	defer graphtest.PutDriver(t)

+ 8 - 3
daemon/graphdriver/devmapper/driver.go

@@ -122,12 +122,17 @@ func (d *Driver) Cleanup() error {
 
 // CreateReadWrite creates a layer that is writable for use as a container
 // file system.
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
-	return d.Create(id, parent, mountLabel, storageOpt)
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
+	return d.Create(id, parent, opts)
 }
 
 // Create adds a device with a given id and the parent.
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
+	var storageOpt map[string]string
+	if opts != nil {
+		storageOpt = opts.StorageOpt
+	}
+
 	if err := d.DeviceSet.AddDevice(id, parent, storageOpt); err != nil {
 		return err
 	}

+ 13 - 4
daemon/graphdriver/driver.go

@@ -36,6 +36,13 @@ var (
 	ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
 )
 
+//CreateOpts contains optional arguments for Create() and CreateReadWrite()
+// methods.
+type CreateOpts struct {
+	MountLabel string
+	StorageOpt map[string]string
+}
+
 // InitFunc initializes the storage driver.
 type InitFunc func(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (Driver, error)
 
@@ -49,11 +56,13 @@ type ProtoDriver interface {
 	// String returns a string representation of this driver.
 	String() string
 	// CreateReadWrite creates a new, empty filesystem layer that is ready
-	// to be used as the storage for a container.
-	CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error
+	// to be used as the storage for a container. Additional options can
+	// be passed in opts. parent may be "" and opts may be nil.
+	CreateReadWrite(id, parent string, opts *CreateOpts) error
 	// Create creates a new, empty, filesystem layer with the
-	// specified id and parent and mountLabel. Parent and mountLabel may be "".
-	Create(id, parent, mountLabel string, storageOpt map[string]string) error
+	// specified id and parent and options passed in opts. Parent
+	// may be "" and opts may be nil.
+	Create(id, parent string, opts *CreateOpts) error
 	// Remove attempts to remove the filesystem layer with this id.
 	Remove(id string) error
 	// Get returns the mountpoint for the layered filesystem referred

+ 10 - 15
daemon/graphdriver/graphtest/graphbench_unix.go

@@ -19,7 +19,7 @@ func DriverBenchExists(b *testing.B, drivername string, driveroptions ...string)
 
 	base := stringid.GenerateRandomID()
 
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		b.Fatal(err)
 	}
 
@@ -38,7 +38,7 @@ func DriverBenchGetEmpty(b *testing.B, drivername string, driveroptions ...strin
 
 	base := stringid.GenerateRandomID()
 
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		b.Fatal(err)
 	}
 
@@ -62,8 +62,7 @@ func DriverBenchDiffBase(b *testing.B, drivername string, driveroptions ...strin
 	defer PutDriver(b)
 
 	base := stringid.GenerateRandomID()
-
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		b.Fatal(err)
 	}
 
@@ -92,8 +91,7 @@ func DriverBenchDiffN(b *testing.B, bottom, top int, drivername string, driverop
 	defer PutDriver(b)
 	base := stringid.GenerateRandomID()
 	upper := stringid.GenerateRandomID()
-
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		b.Fatal(err)
 	}
 
@@ -101,7 +99,7 @@ func DriverBenchDiffN(b *testing.B, bottom, top int, drivername string, driverop
 		b.Fatal(err)
 	}
 
-	if err := driver.Create(upper, base, "", nil); err != nil {
+	if err := driver.Create(upper, base, nil); err != nil {
 		b.Fatal(err)
 	}
 
@@ -128,8 +126,7 @@ func DriverBenchDiffApplyN(b *testing.B, fileCount int, drivername string, drive
 	defer PutDriver(b)
 	base := stringid.GenerateRandomID()
 	upper := stringid.GenerateRandomID()
-
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		b.Fatal(err)
 	}
 
@@ -137,7 +134,7 @@ func DriverBenchDiffApplyN(b *testing.B, fileCount int, drivername string, drive
 		b.Fatal(err)
 	}
 
-	if err := driver.Create(upper, base, "", nil); err != nil {
+	if err := driver.Create(upper, base, nil); err != nil {
 		b.Fatal(err)
 	}
 
@@ -152,7 +149,7 @@ func DriverBenchDiffApplyN(b *testing.B, fileCount int, drivername string, drive
 	b.StopTimer()
 	for i := 0; i < b.N; i++ {
 		diff := stringid.GenerateRandomID()
-		if err := driver.Create(diff, base, "", nil); err != nil {
+		if err := driver.Create(diff, base, nil); err != nil {
 			b.Fatal(err)
 		}
 
@@ -191,8 +188,7 @@ func DriverBenchDeepLayerDiff(b *testing.B, layerCount int, drivername string, d
 	defer PutDriver(b)
 
 	base := stringid.GenerateRandomID()
-
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		b.Fatal(err)
 	}
 
@@ -225,8 +221,7 @@ func DriverBenchDeepLayerRead(b *testing.B, layerCount int, drivername string, d
 	defer PutDriver(b)
 
 	base := stringid.GenerateRandomID()
-
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		b.Fatal(err)
 	}
 

+ 12 - 13
daemon/graphdriver/graphtest/graphtest_unix.go

@@ -86,7 +86,7 @@ func DriverTestCreateEmpty(t testing.TB, drivername string, driverOptions ...str
 	driver := GetDriver(t, drivername, driverOptions...)
 	defer PutDriver(t)
 
-	if err := driver.Create("empty", "", "", nil); err != nil {
+	if err := driver.Create("empty", "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -147,7 +147,7 @@ func DriverTestCreateSnap(t testing.TB, drivername string, driverOptions ...stri
 		}
 	}()
 
-	if err := driver.Create("Snap", "Base", "", nil); err != nil {
+	if err := driver.Create("Snap", "Base", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -166,8 +166,7 @@ func DriverTestDeepLayerRead(t testing.TB, layerCount int, drivername string, dr
 	defer PutDriver(t)
 
 	base := stringid.GenerateRandomID()
-
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -201,7 +200,7 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
 	deleteFileContent := []byte("This file should get removed in upper!")
 	deleteDir := "var/lib"
 
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -217,7 +216,7 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
 		t.Fatal(err)
 	}
 
-	if err := driver.Create(upper, base, "", nil); err != nil {
+	if err := driver.Create(upper, base, nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -235,7 +234,7 @@ func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverO
 	}
 
 	diff := stringid.GenerateRandomID()
-	if err := driver.Create(diff, base, "", nil); err != nil {
+	if err := driver.Create(diff, base, nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -288,8 +287,7 @@ func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string)
 	defer PutDriver(t)
 	base := stringid.GenerateRandomID()
 	upper := stringid.GenerateRandomID()
-
-	if err := driver.Create(base, "", "", nil); err != nil {
+	if err := driver.Create(base, "", nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -297,7 +295,7 @@ func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string)
 		t.Fatal(err)
 	}
 
-	if err := driver.Create(upper, base, "", nil); err != nil {
+	if err := driver.Create(upper, base, nil); err != nil {
 		t.Fatal(err)
 	}
 
@@ -339,9 +337,10 @@ func DriverTestSetQuota(t *testing.T, drivername string) {
 	defer PutDriver(t)
 
 	createBase(t, driver, "Base")
-	storageOpt := make(map[string]string, 1)
-	storageOpt["size"] = "50M"
-	if err := driver.Create("zfsTest", "Base", "", storageOpt); err != nil {
+	createOpts := &graphdriver.CreateOpts{}
+	createOpts.StorageOpt = make(map[string]string, 1)
+	createOpts.StorageOpt["size"] = "50M"
+	if err := driver.Create("zfsTest", "Base", createOpts); err != nil {
 		t.Fatal(err)
 	}
 

+ 1 - 1
daemon/graphdriver/graphtest/testutil.go

@@ -275,7 +275,7 @@ func addManyLayers(drv graphdriver.Driver, baseLayer string, count int) (string,
 	lastLayer := baseLayer
 	for i := 1; i <= count; i++ {
 		nextLayer := stringid.GenerateRandomID()
-		if err := drv.Create(nextLayer, lastLayer, "", nil); err != nil {
+		if err := drv.Create(nextLayer, lastLayer, nil); err != nil {
 			return "", err
 		}
 		if err := addLayerFiles(drv, nextLayer, lastLayer, i); err != nil {

+ 1 - 1
daemon/graphdriver/graphtest/testutil_unix.go

@@ -94,7 +94,7 @@ func createBase(t testing.TB, driver graphdriver.Driver, name string) {
 	oldmask := syscall.Umask(0)
 	defer syscall.Umask(oldmask)
 
-	if err := driver.CreateReadWrite(name, "", "", nil); err != nil {
+	if err := driver.CreateReadWrite(name, "", nil); err != nil {
 		t.Fatal(err)
 	}
 

+ 4 - 4
daemon/graphdriver/overlay/overlay.go

@@ -231,15 +231,15 @@ func (d *Driver) Cleanup() error {
 
 // CreateReadWrite creates a layer that is writable for use as a container
 // file system.
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
-	return d.Create(id, parent, mountLabel, storageOpt)
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
+	return d.Create(id, parent, opts)
 }
 
 // Create is used to create the upper, lower, and merge directories required for overlay fs for a given id.
 // The parent filesystem is used to configure these directories for the overlay.
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) (retErr error) {
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) {
 
-	if len(storageOpt) != 0 {
+	if opts != nil && len(opts.StorageOpt) != 0 {
 		return fmt.Errorf("--storage-opt is not supported for overlay")
 	}
 

+ 6 - 6
daemon/graphdriver/overlay2/overlay.go

@@ -282,15 +282,15 @@ func (d *Driver) Cleanup() error {
 
 // CreateReadWrite creates a layer that is writable for use as a container
 // file system.
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
-	return d.Create(id, parent, mountLabel, storageOpt)
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
+	return d.Create(id, parent, opts)
 }
 
 // Create is used to create the upper, lower, and merge directories required for overlay fs for a given id.
 // The parent filesystem is used to configure these directories for the overlay.
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) (retErr error) {
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) {
 
-	if len(storageOpt) != 0 && !projectQuotaSupported {
+	if opts != nil && len(opts.StorageOpt) != 0 && !projectQuotaSupported {
 		return fmt.Errorf("--storage-opt is supported only for overlay over xfs with 'pquota' mount option")
 	}
 
@@ -314,9 +314,9 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
 		}
 	}()
 
-	if len(storageOpt) > 0 {
+	if opts != nil && len(opts.StorageOpt) > 0 {
 		driver := &Driver{}
-		if err := d.parseStorageOpt(storageOpt, driver); err != nil {
+		if err := d.parseStorageOpt(opts.StorageOpt, driver); err != nil {
 			return err
 		}
 

+ 11 - 2
daemon/graphdriver/proxy.go

@@ -53,7 +53,12 @@ func (d *graphDriverProxy) String() string {
 	return d.name
 }
 
-func (d *graphDriverProxy) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
+func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error {
+	mountLabel := ""
+	if opts != nil {
+		mountLabel = opts.MountLabel
+	}
+
 	args := &graphDriverRequest{
 		ID:         id,
 		Parent:     parent,
@@ -69,7 +74,11 @@ func (d *graphDriverProxy) CreateReadWrite(id, parent, mountLabel string, storag
 	return nil
 }
 
-func (d *graphDriverProxy) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
+func (d *graphDriverProxy) Create(id, parent string, opts *CreateOpts) error {
+	mountLabel := ""
+	if opts != nil {
+		mountLabel = opts.MountLabel
+	}
 	args := &graphDriverRequest{
 		ID:         id,
 		Parent:     parent,

+ 6 - 6
daemon/graphdriver/vfs/driver.go

@@ -70,13 +70,13 @@ func (d *Driver) Cleanup() error {
 
 // CreateReadWrite creates a layer that is writable for use as a container
 // file system.
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
-	return d.Create(id, parent, mountLabel, storageOpt)
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
+	return d.Create(id, parent, opts)
 }
 
 // Create prepares the filesystem for the VFS driver and copies the directory for the given id under the parent.
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
-	if len(storageOpt) != 0 {
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
+	if opts != nil && len(opts.StorageOpt) != 0 {
 		return fmt.Errorf("--storage-opt is not supported for vfs")
 	}
 
@@ -91,8 +91,8 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
 	if err := idtools.MkdirAs(dir, 0755, rootUID, rootGID); err != nil {
 		return err
 	}
-	opts := []string{"level:s0"}
-	if _, mountLabel, err := label.InitLabels(opts); err == nil {
+	labelOpts := []string{"level:s0"}
+	if _, mountLabel, err := label.InitLabels(labelOpts); err == nil {
 		label.SetFileLabel(dir, mountLabel)
 	}
 	if parent == "" {

+ 12 - 4
daemon/graphdriver/windows/windows.go

@@ -161,13 +161,21 @@ func (d *Driver) Exists(id string) bool {
 
 // CreateReadWrite creates a layer that is writable for use as a container
 // file system.
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
-	return d.create(id, parent, mountLabel, false, storageOpt)
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
+	if opts != nil {
+		return d.create(id, parent, opts.MountLabel, false, opts.StorageOpt)
+	} else {
+		return d.create(id, parent, "", false, nil)
+	}
 }
 
 // Create creates a new read-only layer with the given id.
-func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
-	return d.create(id, parent, mountLabel, true, storageOpt)
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
+	if opts != nil {
+		return d.create(id, parent, opts.MountLabel, true, opts.StorageOpt)
+	} else {
+		return d.create(id, parent, "", true, nil)
+	}
 }
 
 func (d *Driver) create(id, parent, mountLabel string, readOnly bool, storageOpt map[string]string) error {

+ 8 - 3
daemon/graphdriver/zfs/zfs.go

@@ -255,12 +255,17 @@ func (d *Driver) mountPath(id string) string {
 
 // CreateReadWrite creates a layer that is writable for use as a container
 // file system.
-func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
-	return d.Create(id, parent, mountLabel, storageOpt)
+func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
+	return d.Create(id, parent, opts)
 }
 
 // Create prepares the dataset and filesystem for the ZFS driver for the given id under the parent.
-func (d *Driver) Create(id string, parent string, mountLabel string, storageOpt map[string]string) error {
+func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
+	var storageOpt map[string]string
+	if opts != nil {
+		storageOpt = opts.StorageOpt
+	}
+
 	err := d.create(id, parent, storageOpt)
 	if err == nil {
 		return nil

+ 2 - 2
integration-cli/docker_cli_external_graphdriver_unix_test.go

@@ -145,7 +145,7 @@ func (s *DockerExternalGraphdriverSuite) setUpPlugin(c *check.C, name string, ex
 		if err := decReq(r.Body, &req, w); err != nil {
 			return
 		}
-		if err := driver.CreateReadWrite(req.ID, req.Parent, "", nil); err != nil {
+		if err := driver.CreateReadWrite(req.ID, req.Parent, nil); err != nil {
 			respond(w, err)
 			return
 		}
@@ -159,7 +159,7 @@ func (s *DockerExternalGraphdriverSuite) setUpPlugin(c *check.C, name string, ex
 		if err := decReq(r.Body, &req, w); err != nil {
 			return
 		}
-		if err := driver.Create(req.ID, req.Parent, "", nil); err != nil {
+		if err := driver.Create(req.ID, req.Parent, nil); err != nil {
 			respond(w, err)
 			return
 		}

+ 12 - 3
layer/layer_store.go

@@ -277,7 +277,7 @@ func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, descr
 		descriptor:     descriptor,
 	}
 
-	if err = ls.driver.Create(layer.cacheID, pid, "", nil); err != nil {
+	if err = ls.driver.Create(layer.cacheID, pid, nil); err != nil {
 		return nil, err
 	}
 
@@ -488,7 +488,11 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, mountLabel stri
 		m.initID = pid
 	}
 
-	if err = ls.driver.CreateReadWrite(m.mountID, pid, "", storageOpt); err != nil {
+	createOpts := &graphdriver.CreateOpts{
+		StorageOpt: storageOpt,
+	}
+
+	if err = ls.driver.CreateReadWrite(m.mountID, pid, createOpts); err != nil {
 		return nil, err
 	}
 
@@ -598,7 +602,12 @@ func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc Mou
 	// then the initID should be randomly generated.
 	initID := fmt.Sprintf("%s-init", graphID)
 
-	if err := ls.driver.CreateReadWrite(initID, parent, mountLabel, storageOpt); err != nil {
+	createOpts := &graphdriver.CreateOpts{
+		MountLabel: mountLabel,
+		StorageOpt: storageOpt,
+	}
+
+	if err := ls.driver.CreateReadWrite(initID, parent, createOpts); err != nil {
 		return "", err
 	}
 	p, err := ls.driver.Get(initID, "")

+ 5 - 5
layer/migration_test.go

@@ -78,7 +78,7 @@ func TestLayerMigration(t *testing.T) {
 	}
 
 	graphID1 := stringid.GenerateRandomID()
-	if err := graph.Create(graphID1, "", "", nil); err != nil {
+	if err := graph.Create(graphID1, "", nil); err != nil {
 		t.Fatal(err)
 	}
 	if _, err := graph.ApplyDiff(graphID1, "", bytes.NewReader(tar1)); err != nil {
@@ -123,7 +123,7 @@ func TestLayerMigration(t *testing.T) {
 	}
 
 	graphID2 := stringid.GenerateRandomID()
-	if err := graph.Create(graphID2, graphID1, "", nil); err != nil {
+	if err := graph.Create(graphID2, graphID1, nil); err != nil {
 		t.Fatal(err)
 	}
 	if _, err := graph.ApplyDiff(graphID2, graphID1, bytes.NewReader(tar2)); err != nil {
@@ -165,7 +165,7 @@ func tarFromFilesInGraph(graph graphdriver.Driver, graphID, parentID string, fil
 		return nil, err
 	}
 
-	if err := graph.Create(graphID, parentID, "", nil); err != nil {
+	if err := graph.Create(graphID, parentID, nil); err != nil {
 		return nil, err
 	}
 	if _, err := graph.ApplyDiff(graphID, parentID, bytes.NewReader(t)); err != nil {
@@ -320,14 +320,14 @@ func TestMountMigration(t *testing.T) {
 	containerID := stringid.GenerateRandomID()
 	containerInit := fmt.Sprintf("%s-init", containerID)
 
-	if err := graph.Create(containerInit, graphID1, "", nil); err != nil {
+	if err := graph.Create(containerInit, graphID1, nil); err != nil {
 		t.Fatal(err)
 	}
 	if _, err := graph.ApplyDiff(containerInit, graphID1, bytes.NewReader(initTar)); err != nil {
 		t.Fatal(err)
 	}
 
-	if err := graph.Create(containerID, containerInit, "", nil); err != nil {
+	if err := graph.Create(containerID, containerInit, nil); err != nil {
 		t.Fatal(err)
 	}
 	if _, err := graph.ApplyDiff(containerID, containerInit, bytes.NewReader(mountTar)); err != nil {