package graphdriver import ( "fmt" "github.com/dotcloud/docker/archive" "github.com/dotcloud/docker/utils" "os" "path" ) type InitFunc func(root string) (Driver, error) type Driver interface { String() string Create(id, parent string) error Remove(id string) error Get(id string) (dir string, err error) Put(id string) Exists(id string) bool Status() [][2]string Cleanup() error } type Differ interface { Diff(id string) (archive.Archive, error) Changes(id string) ([]archive.Change, error) ApplyDiff(id string, diff archive.Archive) error DiffSize(id string) (bytes int64, err error) } var ( DefaultDriver string // All registred drivers drivers map[string]InitFunc // Slice of drivers that should be used in an order priority = []string{ "aufs", "devicemapper", "vfs", // experimental, has to be enabled manually for now "btrfs", } ) func init() { drivers = make(map[string]InitFunc) } 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 GetDriver(name, home string) (Driver, error) { if initFunc, exists := drivers[name]; exists { return initFunc(path.Join(home, name)) } return nil, fmt.Errorf("No such driver: %s", name) } func New(root string) (driver Driver, err error) { for _, name := range []string{os.Getenv("DOCKER_DRIVER"), DefaultDriver} { if name != "" { return GetDriver(name, root) } } // Check for priority drivers first for _, name := range priority { if driver, err = GetDriver(name, root); err != nil { utils.Debugf("Error loading driver %s: %s", name, err) continue } return driver, nil } // Check all registered drivers if no priority driver is found for _, initFunc := range drivers { if driver, err = initFunc(root); err != nil { continue } return driver, nil } return nil, err }