driver.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package graphdriver
  2. import (
  3. "fmt"
  4. "github.com/dotcloud/docker/archive"
  5. "github.com/dotcloud/docker/utils"
  6. "os"
  7. )
  8. type InitFunc func(root string) (Driver, error)
  9. type Driver interface {
  10. Create(id, parent string) error
  11. Remove(id string) error
  12. Get(id string) (dir string, err error)
  13. Diff(id string) (archive.Archive, error)
  14. DiffSize(id string) (bytes int64, err error)
  15. Changes(id string) ([]archive.Change, error)
  16. Cleanup() error
  17. }
  18. var (
  19. // All registred drivers
  20. drivers map[string]InitFunc
  21. // Slice of drivers that should be used in an order
  22. priority = []string{
  23. "aufs",
  24. "devicemapper",
  25. "dummy",
  26. }
  27. )
  28. func init() {
  29. drivers = make(map[string]InitFunc)
  30. }
  31. func Register(name string, initFunc InitFunc) error {
  32. if _, exists := drivers[name]; exists {
  33. return fmt.Errorf("Name already registered %s", name)
  34. }
  35. drivers[name] = initFunc
  36. return nil
  37. }
  38. func getDriver(name, home string) (Driver, error) {
  39. if initFunc, exists := drivers[name]; exists {
  40. return initFunc(home)
  41. }
  42. return nil, fmt.Errorf("No such driver: %s", name)
  43. }
  44. func New(root string) (Driver, error) {
  45. var driver Driver
  46. var lastError error
  47. // Use environment variable DOCKER_DRIVER to force a choice of driver
  48. if name := os.Getenv("DOCKER_DRIVER"); name != "" {
  49. return getDriver(name, root)
  50. }
  51. // Check for priority drivers first
  52. for _, name := range priority {
  53. driver, lastError = getDriver(name, root)
  54. if lastError != nil {
  55. utils.Debugf("Error loading driver %s: %s", name, lastError)
  56. continue
  57. }
  58. return driver, nil
  59. }
  60. // Check all registered drivers if no priority driver is found
  61. for _, initFunc := range drivers {
  62. driver, lastError = initFunc(root)
  63. if lastError != nil {
  64. continue
  65. }
  66. return driver, nil
  67. }
  68. return nil, lastError
  69. }