diff --git a/devmapper/driver.go b/devmapper/driver.go index 1eaa0ab76f..7a594db623 100644 --- a/devmapper/driver.go +++ b/devmapper/driver.go @@ -15,15 +15,6 @@ func init() { // Placeholder interfaces, to be replaced // at integration. -type Image interface { - ID() string - Parent() (Image, error) - Path() string -} - -type Change interface { -} - // End of placeholder interfaces. type Driver struct { @@ -46,54 +37,45 @@ func (d *Driver) Cleanup() error { return d.DeviceSet.Shutdown() } -func (d *Driver) OnCreate(img Image, layer archive.Archive) error { - // Determine the source of the snapshot (parent id or init device) - var parentID string - if parent, err := img.Parent(); err != nil { - return err - } else if parent != nil { - parentID = parent.ID() - } - // Create the device for this image by snapshotting source - if err := d.DeviceSet.AddDevice(img.ID(), parentID); err != nil { - return err - } - // Mount the device in rootfs - mp := d.mountpoint(img.ID()) - if err := os.MkdirAll(mp, 0700); err != nil { - return err - } - if err := d.DeviceSet.MountDevice(img.ID(), mp, false); err != nil { - return err - } - // Apply the layer as a diff - if layer != nil { - if err := archive.ApplyLayer(mp, layer); err != nil { - return err - } - } - return nil +func (d *Driver) Create(id string, parent string) error { + return d.DeviceSet.AddDevice(id, parent) } -func (d *Driver) OnRemove(img Image) error { - id := img.ID() - if err := d.DeviceSet.RemoveDevice(id); err != nil { - return fmt.Errorf("Unable to remove device for %v: %v", id, err) - } - return nil +func (d *Driver) Remove(id string) error { + return d.DeviceSet.RemoveDevice(id) } -func (d *Driver) mountpoint(id string) string { - if d.home == "" { - return "" +func (d *Driver) Get(id string) (string, error) { + mp := path.Join(d.home, "mnt", id) + if err := d.mount(id, mp); err != nil { + return "", err } - return path.Join(d.home, "mnt", id) + return mp, nil } -func (d *Driver) Changes(img *Image, dest string) ([]Change, error) { +func (d *Driver) Diff(id string) (archive.Archive, error) { return nil, fmt.Errorf("Not implemented") } -func (d *Driver) Layer(img *Image, dest string) (archive.Archive, error) { +func (d *Driver) DiffSize(id string) (int64, error) { + return -1, fmt.Errorf("Not implemented") +} + +func (d *Driver) Changes(id string) ([]graphdriver.Change, error) { return nil, fmt.Errorf("Not implemented") } + +func (d *Driver) mount(id, mp string) error { + // Create the target directories if they don't exist + if err := os.MkdirAll(mp, 0755); err != nil && !os.IsExist(err) { + return err + } + // If mountpoint is already mounted, do nothing + if mounted, err := Mounted(mp); err != nil { + return fmt.Errorf("Error checking mountpoint: %s", err) + } else if mounted { + return nil + } + // Mount the device + return d.DeviceSet.MountDevice(id, mp, false) +} diff --git a/devmapper/driver_test.go b/devmapper/driver_test.go index 5f80c1dab2..dadf2715ec 100644 --- a/devmapper/driver_test.go +++ b/devmapper/driver_test.go @@ -6,32 +6,6 @@ import ( "testing" ) -type TestImage struct { - id string - path string -} - -func (img *TestImage) ID() string { - return img.id -} - -func (img *TestImage) Path() string { - return img.path -} - -func (img *TestImage) Parent() (Image, error) { - return nil, nil -} - - - -func mkTestImage(t *testing.T) Image { - return &TestImage{ - path: mkTestDirectory(t), - id: "4242", - } -} - func mkTestDirectory(t *testing.T) string { dir, err := ioutil.TempDir("", "docker-test-devmapper-") if err != nil { @@ -43,19 +17,27 @@ func mkTestDirectory(t *testing.T) string { func TestInit(t *testing.T) { home := mkTestDirectory(t) defer os.RemoveAll(home) - plugin, err := Init(home) + driver, err := Init(home) if err != nil { t.Fatal(err) } defer func() { return - if err := plugin.Cleanup(); err != nil { + if err := driver.Cleanup(); err != nil { t.Fatal(err) } }() - img := mkTestImage(t) - defer os.RemoveAll(img.(*TestImage).path) - if err := plugin.OnCreate(img, nil); err != nil { + id := "foo" + if err := driver.Create(id, ""); err != nil { t.Fatal(err) } + dir, err := driver.Get(id) + if err != nil { + t.Fatal(err) + } + if st, err := os.Stat(dir); err != nil { + t.Fatal(err) + } else if !st.IsDir() { + t.Fatalf("Get(%V) did not return a directory", id) + } } diff --git a/devmapper/mount.go b/devmapper/mount.go new file mode 100644 index 0000000000..e3a303e507 --- /dev/null +++ b/devmapper/mount.go @@ -0,0 +1,27 @@ +package devmapper + +import ( + "os" + "path/filepath" + "syscall" +) + +// FIXME: this is copy-pasted from the aufs driver. +// It should be moved into the core. + +func Mounted(mountpoint string) (bool, error) { + mntpoint, err := os.Stat(mountpoint) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, err + } + parent, err := os.Stat(filepath.Join(mountpoint, "..")) + if err != nil { + return false, err + } + mntpointSt := mntpoint.Sys().(*syscall.Stat_t) + parentSt := parent.Sys().(*syscall.Stat_t) + return mntpointSt.Dev != parentSt.Dev, nil +} diff --git a/runtime.go b/runtime.go index 4d46d8fbab..80adf8330f 100644 --- a/runtime.go +++ b/runtime.go @@ -8,6 +8,7 @@ import ( "github.com/dotcloud/docker/gograph" "github.com/dotcloud/docker/utils" "github.com/dotcloud/docker/graphdriver" + _ "github.com/dotcloud/docker/devmapper" "io" "io/ioutil" "log"