Bläddra i källkod

Merge pull request #11999 from vbatts/vbatts-decide_storage

graphdriver: prefer prior driver state
Jessie Frazelle 10 år sedan
förälder
incheckning
74f4a88305
1 ändrade filer med 49 tillägg och 6 borttagningar
  1. 49 6
      daemon/graphdriver/driver.go

+ 49 - 6
daemon/graphdriver/driver.go

@@ -146,10 +146,40 @@ func GetDriver(name, home string, options []string) (Driver, error) {
 func New(root string, options []string) (driver Driver, err error) {
 	for _, name := range []string{os.Getenv("DOCKER_DRIVER"), DefaultDriver} {
 		if name != "" {
+			logrus.Infof("[graphdriver] trying provided driver %q", name) // so the logs show specified driver
 			return GetDriver(name, root, options)
 		}
 	}
 
+	// Guess for prior driver
+	priorDrivers := scanPriorDrivers(root)
+	for _, name := range priority {
+		if name == "vfs" {
+			// don't use vfs even if there is state present.
+			continue
+		}
+		for _, prior := range priorDrivers {
+			// of the state found from prior drivers, check in order of our priority
+			// which we would prefer
+			if prior == name {
+				driver, err = GetDriver(name, root, options)
+				if err != nil {
+					// unlike below, we will return error here, because there is prior
+					// state, and now it is no longer supported/prereq/compatible, so
+					// something changed and needs attention. Otherwise the daemon's
+					// images would just "disappear".
+					logrus.Errorf("[graphdriver] prior storage driver %q failed: %s", name, err)
+					return nil, err
+				}
+				if err := checkPriorDriver(name, root); err != nil {
+					return nil, err
+				}
+				logrus.Infof("[graphdriver] using prior storage driver %q", name)
+				return driver, nil
+			}
+		}
+	}
+
 	// Check for priority drivers first
 	for _, name := range priority {
 		driver, err = GetDriver(name, root, options)
@@ -159,34 +189,47 @@ func New(root string, options []string) (driver Driver, err error) {
 			}
 			return nil, err
 		}
-		checkPriorDriver(name, root)
 		return driver, nil
 	}
 
 	// Check all registered drivers if no priority driver is found
-	for name, initFunc := range drivers {
+	for _, initFunc := range drivers {
 		if driver, err = initFunc(root, options); err != nil {
 			if err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS {
 				continue
 			}
 			return nil, err
 		}
-		checkPriorDriver(name, root)
 		return driver, nil
 	}
 	return nil, fmt.Errorf("No supported storage backend found")
 }
 
-func checkPriorDriver(name, root string) {
+// scanPriorDrivers returns an un-ordered scan of directories of prior storage drivers
+func scanPriorDrivers(root string) []string {
+	priorDrivers := []string{}
+	for driver := range drivers {
+		p := path.Join(root, driver)
+		if _, err := os.Stat(p); err == nil {
+			priorDrivers = append(priorDrivers, driver)
+		}
+	}
+	return priorDrivers
+}
+
+func checkPriorDriver(name, root string) error {
 	priorDrivers := []string{}
-	for prior := range drivers {
+	for _, prior := range scanPriorDrivers(root) {
 		if prior != name && prior != "vfs" {
 			if _, err := os.Stat(path.Join(root, prior)); err == nil {
 				priorDrivers = append(priorDrivers, prior)
 			}
 		}
 	}
+
 	if len(priorDrivers) > 0 {
-		logrus.Warnf("Graphdriver %s selected. Your graphdriver directory %s already contains data managed by other graphdrivers: %s", name, root, strings.Join(priorDrivers, ","))
+
+		return errors.New(fmt.Sprintf("%q contains other graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", root, strings.Join(priorDrivers, ",")))
 	}
+	return nil
 }