Browse Source

Add graph driver registration

Michael Crosby 11 years ago
parent
commit
752bfba2c5
5 changed files with 82 additions and 19 deletions
  1. 9 1
      aufs/aufs.go
  2. 9 7
      devmapper/driver.go
  3. 12 4
      graph.go
  4. 50 0
      graphdriver/driver.go
  5. 2 7
      runtime.go

+ 9 - 1
aufs/aufs.go

@@ -9,12 +9,20 @@ import (
 	"path"
 )
 
+func init() {
+	graphdriver.Register("aufs", Init)
+}
+
 type AufsDriver struct {
 }
 
 // New returns a new AUFS driver.
 // An error is returned if AUFS is not supported.
-func New() (*AufsDriver, error) {
+func Init(root string) (graphdriver.Driver, error) {
+	// Try to load the aufs kernel module
+	if err := exec.Command("modprobe", "aufs").Run(); err != nil {
+		return nil, err
+	}
 	return &AufsDriver{}, nil
 }
 

+ 9 - 7
devmapper/driver.go

@@ -2,11 +2,16 @@ package devmapper
 
 import (
 	"fmt"
+	"github.com/dotcloud/docker/archive"
+	"github.com/dotcloud/docker/graphdriver"
 	"os"
 	"path"
-	"github.com/dotcloud/docker/archive"
 )
 
+func init() {
+	graphdriver.Register("devicemapper", Init)
+}
+
 // Placeholder interfaces, to be replaced
 // at integration.
 
@@ -17,22 +22,19 @@ type Image interface {
 }
 
 type Change interface {
-
 }
 
 // End of placeholder interfaces.
 
-
-
 type Driver struct {
 	*DeviceSet
 	home string
 }
 
-func Init(home string) (*Driver, error) {
+func Init(home string) (graphdriver.Driver, error) {
 	d := &Driver{
 		DeviceSet: NewDeviceSet(home),
-		home: home,
+		home:      home,
 	}
 	if err := d.DeviceSet.ensureInit(); err != nil {
 		return nil, err
@@ -64,7 +66,7 @@ func (d *Driver) OnCreate(img Image, layer archive.Archive) error {
 	if err := d.DeviceSet.MountDevice(img.ID(), mp, false); err != nil {
 		return err
 	}
-	// Apply the layer as a diff 
+	// Apply the layer as a diff
 	if layer != nil {
 		if err := archive.ApplyLayer(mp, layer); err != nil {
 			return err

+ 12 - 4
graph.go

@@ -3,6 +3,8 @@ package docker
 import (
 	"fmt"
 	"github.com/dotcloud/docker/archive"
+	_ "github.com/dotcloud/docker/aufs"
+	_ "github.com/dotcloud/docker/devmapper"
 	"github.com/dotcloud/docker/graphdriver"
 	"github.com/dotcloud/docker/utils"
 	"io"
@@ -18,12 +20,12 @@ import (
 type Graph struct {
 	Root    string
 	idIndex *utils.TruncIndex
-	driver graphdriver.Driver
+	driver  graphdriver.Driver
 }
 
 // NewGraph instantiates a new graph at the given root path in the filesystem.
 // `root` will be created if it doesn't exist.
-func NewGraph(root string, driver graphdriver.Driver) (*Graph, error) {
+func NewGraph(root string) (*Graph, error) {
 	abspath, err := filepath.Abs(root)
 	if err != nil {
 		return nil, err
@@ -32,10 +34,16 @@ func NewGraph(root string, driver graphdriver.Driver) (*Graph, error) {
 	if err := os.MkdirAll(root, 0700); err != nil && !os.IsExist(err) {
 		return nil, err
 	}
+
+	driver, err := graphdriver.New(root)
+	if err != nil {
+		return nil, err
+	}
+
 	graph := &Graph{
 		Root:    abspath,
 		idIndex: utils.NewTruncIndex(),
-		driver: driver,
+		driver:  driver,
 	}
 	if err := graph.restore(); err != nil {
 		return nil, err
@@ -242,7 +250,7 @@ func (graph *Graph) getDockerInitLayer() (string, error) {
 
 func (graph *Graph) tmp() (*Graph, error) {
 	// Changed to _tmp from :tmp:, because it messed with ":" separators in aufs branch syntax...
-	return NewGraph(path.Join(graph.Root, "_tmp"), graph.driver)
+	return NewGraph(path.Join(graph.Root, "_tmp"))
 }
 
 // Check if given error is "not empty".

+ 50 - 0
graphdriver/driver.go

@@ -1,5 +1,55 @@
 package graphdriver
 
+import (
+	"fmt"
+)
+
+type InitFunc func(root string) (Driver, error)
+
+var (
+	// All registred drivers
+	drivers map[string]InitFunc
+	// Slice of drivers that should be used in an order
+	priority = []string{
+		"aufs",
+		"devicemapper",
+	}
+)
+
+func Register(name string, initFunc InitFunc) error {
+	if _, exists := drivers[name]; exists {
+		return fmt.Errorf("Name already registered %s", name)
+	}
+	drivers[name] = initFunc
+
+	return nil
+}
+
+func New(root string) (Driver, error) {
+	var driver Driver
+	var lastError error
+	// Check for priority drivers first
+	for _, name := range priority {
+		if initFunc, exists := drivers[name]; exists {
+			driver, lastError = initFunc(root)
+			if lastError != nil {
+				continue
+			}
+			return driver, nil
+		}
+	}
+
+	// Check all registered drivers if no priority driver is found
+	for _, initFunc := range drivers {
+		driver, lastError = initFunc(root)
+		if lastError != nil {
+			continue
+		}
+		return driver, nil
+	}
+	return nil, lastError
+}
+
 type Image interface {
 	Layers() ([]string, error)
 }

+ 2 - 7
runtime.go

@@ -5,7 +5,6 @@ import (
 	"container/list"
 	"database/sql"
 	"fmt"
-	"github.com/dotcloud/docker/aufs"
 	"github.com/dotcloud/docker/gograph"
 	"github.com/dotcloud/docker/utils"
 	"io"
@@ -574,16 +573,12 @@ func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) {
 	if err := os.MkdirAll(runtimeRepo, 0700); err != nil && !os.IsExist(err) {
 		return nil, err
 	}
-	driver, err := aufs.New()
-	if err != nil {
-		return nil, err
-	}
 
-	g, err := NewGraph(path.Join(config.Root, "graph"), driver)
+	g, err := NewGraph(path.Join(config.Root, "graph"))
 	if err != nil {
 		return nil, err
 	}
-	volumes, err := NewGraph(path.Join(config.Root, "volumes"), driver)
+	volumes, err := NewGraph(path.Join(config.Root, "volumes"))
 	if err != nil {
 		return nil, err
 	}