فهرست منبع

graphdriver: prefer prior driver state

Before this, a storage driver would be defaulted to based on the
priority list, and only print a warning if there is state from other
drivers.

This meant a reordering of priority list would "break" users in an
upgrade of docker, such that there images in the prior driver's state
were now invisible.

With this change, prior state is scanned, and if present that driver is
preferred.

As such, we can reorder the priority list, and after an upgrade,
existing installs with prior drivers can have a contiguous experience,
while fresh installs may default to a driver in the new priority list.

Ref: https://github.com/docker/docker/pull/11962#issuecomment-88274858

Signed-off-by: Vincent Batts <vbatts@redhat.com>
Vincent Batts 10 سال پیش
والد
کامیت
b68e161e5b
1فایلهای تغییر یافته به همراه49 افزوده شده و 6 حذف شده
  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
 }