Merge pull request #20525 from Microsoft/sjw/update-graphdriver-create

Adding readOnly parameter to graphdriver Create method
This commit is contained in:
John Howard 2016-04-08 20:44:03 -07:00
commit fec6cd2eb9
14 changed files with 104 additions and 21 deletions

View File

@ -194,6 +194,12 @@ func (a *Driver) Exists(id string) bool {
return true
}
// 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)
}
// Create three folders for each id
// mnt, layers, and diff
func (a *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {

View File

@ -320,7 +320,7 @@ func TestGetDiff(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)
if err := d.Create("1", "", "", nil); err != nil {
if err := d.CreateReadWrite("1", "", "", nil); err != nil {
t.Fatal(err)
}
@ -357,7 +357,7 @@ func TestChanges(t *testing.T) {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}
if err := d.Create("2", "1", "", nil); err != nil {
if err := d.CreateReadWrite("2", "1", "", nil); err != nil {
t.Fatal(err)
}
@ -403,7 +403,7 @@ func TestChanges(t *testing.T) {
t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
}
if err := d.Create("3", "2", "", nil); err != nil {
if err := d.CreateReadWrite("3", "2", "", nil); err != nil {
t.Fatal(err)
}
mntPoint, err = d.Get("3", "")
@ -448,7 +448,7 @@ func TestDiffSize(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)
if err := d.Create("1", "", "", nil); err != nil {
if err := d.CreateReadWrite("1", "", "", nil); err != nil {
t.Fatal(err)
}
@ -490,7 +490,7 @@ func TestChildDiffSize(t *testing.T) {
defer os.RemoveAll(tmp)
defer d.Cleanup()
if err := d.Create("1", "", "", nil); err != nil {
if err := d.CreateReadWrite("1", "", "", nil); err != nil {
t.Fatal(err)
}
@ -592,7 +592,7 @@ func TestApplyDiff(t *testing.T) {
defer os.RemoveAll(tmp)
defer d.Cleanup()
if err := d.Create("1", "", "", nil); err != nil {
if err := d.CreateReadWrite("1", "", "", nil); err != nil {
t.Fatal(err)
}
@ -671,7 +671,7 @@ func testMountMoreThan42Layers(t *testing.T, mountPath string) {
}
current = hash(current)
if err := d.Create(current, parent, "", nil); err != nil {
if err := d.CreateReadWrite(current, parent, "", nil); err != nil {
t.Logf("Current layer %d", i)
t.Error(err)
}

View File

@ -246,6 +246,12 @@ func (d *Driver) subvolumesDirID(id string) string {
return path.Join(d.subvolumesDir(), id)
}
// 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)
}
// Create the filesystem with given id.
func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {

View File

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

View File

@ -117,6 +117,12 @@ func (d *Driver) Cleanup() error {
return err
}
// 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)
}
// Create adds a device with a given id and the parent.
func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
if err := d.DeviceSet.AddDevice(id, parent, storageOpt); err != nil {

View File

@ -46,6 +46,9 @@ type InitFunc func(root string, options []string, uidMaps, gidMaps []idtools.IDM
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
// 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

View File

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

View File

@ -223,6 +223,12 @@ func (d *Driver) Cleanup() error {
return nil
}
// 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)
}
// 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) {

View File

@ -54,6 +54,22 @@ func (d *graphDriverProxy) String() string {
return d.name
}
func (d *graphDriverProxy) CreateReadWrite(id, parent, mountLabel string, storageOpt map[string]string) error {
args := &graphDriverRequest{
ID: id,
Parent: parent,
MountLabel: mountLabel,
}
var ret graphDriverResponse
if err := d.client.Call("GraphDriver.CreateReadWrite", args, &ret); err != nil {
return err
}
if ret.Err != "" {
return errors.New(ret.Err)
}
return nil
}
func (d *graphDriverProxy) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
args := &graphDriverRequest{
ID: id,

View File

@ -68,6 +68,12 @@ func (d *Driver) Cleanup() error {
return nil
}
// 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)
}
// 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 {

View File

@ -107,8 +107,18 @@ func (d *Driver) Exists(id string) bool {
return result
}
// Create creates a new layer with the given id.
// 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)
}
// 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, mountLabel string, readOnly bool, storageOpt map[string]string) error {
if len(storageOpt) != 0 {
return fmt.Errorf("--storage-opt is not supported for windows")
}
@ -125,27 +135,30 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
var layerChain []string
parentIsInit := strings.HasSuffix(rPId, "-init")
if !parentIsInit && rPId != "" {
if rPId != "" {
parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId)
if err != nil {
return err
}
layerChain = []string{parentPath}
if _, err := os.Stat(filepath.Join(parentPath, "Files")); err == nil {
// This is a legitimate parent layer (not the empty "-init" layer),
// so include it in the layer chain.
layerChain = []string{parentPath}
}
}
layerChain = append(layerChain, parentChain...)
if parentIsInit {
if len(layerChain) == 0 {
return fmt.Errorf("Cannot create a read/write layer without a parent layer.")
}
if err := hcsshim.CreateSandboxLayer(d.info, id, layerChain[0], layerChain); err != nil {
if readOnly {
if err := hcsshim.CreateLayer(d.info, id, rPId); err != nil {
return err
}
} else {
if err := hcsshim.CreateLayer(d.info, id, rPId); err != nil {
var parentPath string
if len(layerChain) != 0 {
parentPath = layerChain[0]
}
if err := hcsshim.CreateSandboxLayer(d.info, id, parentPath, layerChain); err != nil {
return err
}
}

View File

@ -240,6 +240,12 @@ func (d *Driver) mountPath(id string) string {
return path.Join(d.options.mountPath, "graph", getMountpoint(id))
}
// 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)
}
// 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 {
if len(storageOpt) != 0 {

View File

@ -67,6 +67,7 @@ func (s *DockerExternalGraphdriverSuite) SetUpSuite(c *check.C) {
ID string `json:",omitempty"`
Parent string `json:",omitempty"`
MountLabel string `json:",omitempty"`
ReadOnly bool `json:",omitempty"`
}
type graphDriverResponse struct {
@ -115,6 +116,20 @@ func (s *DockerExternalGraphdriverSuite) SetUpSuite(c *check.C) {
respond(w, "{}")
})
mux.HandleFunc("/GraphDriver.CreateReadWrite", func(w http.ResponseWriter, r *http.Request) {
s.ec.creations++
var req graphDriverRequest
if err := decReq(r.Body, &req, w); err != nil {
return
}
if err := driver.CreateReadWrite(req.ID, req.Parent, "", nil); err != nil {
respond(w, err)
return
}
respond(w, "{}")
})
mux.HandleFunc("/GraphDriver.Create", func(w http.ResponseWriter, r *http.Request) {
s.ec.creations++

View File

@ -461,7 +461,7 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, mountLabel stri
m.initID = pid
}
if err = ls.driver.Create(m.mountID, pid, "", storageOpt); err != nil {
if err = ls.driver.CreateReadWrite(m.mountID, pid, "", storageOpt); err != nil {
return nil, err
}