diff --git a/aufs/aufs.go b/aufs/aufs.go index 9ee6848210..4c14947a95 100644 --- a/aufs/aufs.go +++ b/aufs/aufs.go @@ -2,6 +2,7 @@ package aufs import ( "fmt" + "github.com/dotcloud/docker/archive" "github.com/dotcloud/docker/graphdriver" "log" "os" @@ -14,6 +15,7 @@ func init() { } type AufsDriver struct { + root string } // New returns a new AUFS driver. @@ -23,17 +25,54 @@ func Init(root string) (graphdriver.Driver, error) { if err := exec.Command("modprobe", "aufs").Run(); err != nil { return nil, err } - return &AufsDriver{}, nil + return &AufsDriver{root}, nil } -func (a *AufsDriver) Mount(img graphdriver.Image, root string) error { - layers, err := img.Layers() +func (a *AufsDriver) OnCreate(dir graphdriver.Dir, layer archive.Archive) error { + tmp := path.Join(os.TempDir(), dir.ID()) + if err := os.MkdirAll(tmp, 0755); err != nil { + return err + } + defer os.RemoveAll(tmp) + + layerRoot := path.Join(a.root, dir.ID()) + if err := os.MkdirAll(layerRoot, 0755); err != nil { + return err + } + + if layer != nil { + if err := archive.Untar(layer, tmp); err != nil { + return err + } + } + + if err := os.Rename(tmp, layerRoot); err != nil { + return err + } + return nil +} + +func (a *AufsDriver) OnRemove(dir graphdriver.Dir) error { + tmp := path.Join(os.TempDir(), dir.ID()) + + if err := os.MkdirAll(tmp, 0755); err != nil { + return err + } + + if err := os.Rename(path.Join(a.root, dir.ID()), tmp); err != nil { + return err + } + return os.RemoveAll(tmp) +} + +func (a *AufsDriver) OnMount(dir graphdriver.Dir, dest string) error { + layers, err := a.getLayers(dir) if err != nil { return err } - target := path.Join(root, "rootfs") - rw := path.Join(root, "rw") + target := path.Join(dest, "rootfs") + rw := path.Join(dest, "rw") // Create the target directories if they don't exist if err := os.Mkdir(target, 0755); err != nil && !os.IsExist(err) { @@ -48,8 +87,8 @@ func (a *AufsDriver) Mount(img graphdriver.Image, root string) error { return nil } -func (a *AufsDriver) Unmount(root string) error { - target := path.Join(root, "rootfs") +func (a *AufsDriver) OnUnmount(dest string) error { + target := path.Join(dest, "rootfs") if _, err := os.Stat(target); err != nil { if os.IsNotExist(err) { return nil @@ -59,8 +98,32 @@ func (a *AufsDriver) Unmount(root string) error { return Unmount(target) } -func (a *AufsDriver) Mounted(root string) (bool, error) { - return Mounted(path.Join(root, "rootfs")) +func (a *AufsDriver) Mounted(dest string) (bool, error) { + return Mounted(path.Join(dest, "rootfs")) +} + +func (a *AufsDriver) Layer(dir graphdriver.Dir, dest string) (archive.Archive, error) { + return nil, fmt.Errorf("not implemented") +} + +func (a *AufsDriver) Cleanup() error { + return nil +} + +func (a *AufsDriver) getLayers(dir graphdriver.Dir) ([]string, error) { + var ( + err error + layers = []string{} + current = dir + ) + + for current != nil { + layers = append(layers, current.Path()) + if current, err = current.Parent(); err != nil { + return nil, err + } + } + return layers, nil } func (a *AufsDriver) aufsMount(ro []string, rw, target string) error { diff --git a/graphdriver/driver.go b/graphdriver/driver.go index fe6fc56202..422be0296f 100644 --- a/graphdriver/driver.go +++ b/graphdriver/driver.go @@ -2,10 +2,30 @@ package graphdriver import ( "fmt" + "github.com/dotcloud/docker/archive" ) type InitFunc func(root string) (Driver, error) +type Dir interface { + ID() string + Path() string + Parent() (Dir, error) +} + +type Driver interface { + OnCreate(dir Dir, layer archive.Archive) error + OnRemove(dir Dir) error + + OnMount(dir Dir, dest string) error + OnUnmount(dest string) error + Mounted(dest string) (bool, error) + + Layer(dir Dir, dest string) (archive.Archive, error) + + Cleanup() error +} + var ( // All registred drivers drivers map[string]InitFunc @@ -49,18 +69,3 @@ func New(root string) (Driver, error) { } return nil, lastError } - -type Image interface { - Layers() ([]string, error) -} - -type Driver interface { - // Create(img *Image) error - // Delete(img *Image) error - Mount(img Image, root string) error - Unmount(root string) error - Mounted(root string) (bool, error) - // UnmountAll(img *Image) error - // Changes(img *Image, dest string) ([]Change, error) - // Layer(img *Image, dest string) (Archive, error) -} diff --git a/image.go b/image.go index dc3eb3c92a..5c672adb4b 100644 --- a/image.go +++ b/image.go @@ -183,43 +183,6 @@ func (img *Image) History() ([]*Image, error) { return parents, nil } -// layers returns all the filesystem layers needed to mount an image -// FIXME: @shykes refactor this function with the new error handling -// (I'll do it if I have time tonight, I focus on the rest) -func (img *Image) Layers() ([]string, error) { - if img.graph == nil { - - return nil, fmt.Errorf("Can't lookup dockerinit layer of unregistered image") - } - var list []string - var e error - if err := img.WalkHistory( - func(img *Image) (err error) { - if layer, err := img.layer(); err != nil { - e = err - } else if layer != "" { - list = append(list, layer) - } - return err - }, - ); err != nil { - return nil, err - } else if e != nil { // Did an error occur inside the handler? - return nil, e - } - if len(list) == 0 { - return nil, fmt.Errorf("No layer found for image %s\n", img.ID) - } - - // Inject the dockerinit layer (empty place-holder for mount-binding dockerinit) - if dockerinitLayer, err := img.graph.getDockerInitLayer(); err != nil { - return nil, err - } else { - list = append([]string{dockerinitLayer}, list...) - } - return list, nil -} - func (img *Image) WalkHistory(handler func(*Image) error) (err error) { currentImg := img for currentImg != nil {