瀏覽代碼

Verbose migration add warning for running container

Conflicts:
	hack/make.sh
	runtime.go
	runtime_test.go
Michael Crosby 11 年之前
父節點
當前提交
562e4f1e23
共有 3 個文件被更改,包括 73 次插入46 次删除
  1. 1 1
      hack/make.sh
  2. 71 44
      runtime.go
  3. 1 1
      runtime_test.go

+ 1 - 1
hack/make.sh

@@ -44,7 +44,7 @@ if [ -n "$(git status --porcelain)" ]; then
 fi
 
 # Use these flags when compiling the tests and final binary
-LDFLAGS='-X main.GITCOMMIT "'$GITCOMMIT'" -X main.VERSION "'$VERSION'" -w -linkmode external -extldflags "-lpthread -static -Wl,--unresolved-symbols=ignore-all"'
+LDFLAGS='-X main.GITCOMMIT "'$GITCOMMIT'" -X main.VERSION "'$VERSION'" -w -linkmode external -extldflags "-static -Wl,--unresolved-symbols=ignore-in-shared-libs"'
 BUILDFLAGS='-tags netgo'
 
 bundle() {

+ 71 - 44
runtime.go

@@ -287,7 +287,10 @@ func (runtime *Runtime) restore() error {
 		return err
 	}
 
+	deviceSet := runtime.deviceSet
 	containers := []*Container{}
+	containersToMigrate := []*Container{}
+
 	for i, v := range dir {
 		id := v.Name()
 		container, err := runtime.load(id)
@@ -300,68 +303,92 @@ func (runtime *Runtime) restore() error {
 		}
 		utils.Debugf("Loaded container %v", container.ID)
 		containers = append(containers, container)
+
+		if !deviceSet.HasDevice(container.ID) {
+			containersToMigrate = append(containersToMigrate, container)
+		}
 	}
 
-	deviceSet := runtime.deviceSet
-	for _, container := range containers {
+	// Migrate AUFS containers to device mapper
+	if len(containersToMigrate) > 0 {
+		if err := migrateToDeviceMapper(runtime, containersToMigrate); err != nil {
+			return err
+		}
+	}
 
-		// Perform a migration for aufs containers
-		if !deviceSet.HasDevice(container.ID) {
-			contents, err := ioutil.ReadDir(container.rwPath())
-			if err != nil {
-				if !os.IsNotExist(err) {
-					utils.Debugf("[migration] Error reading rw dir %s", err)
-				}
-				continue
-			}
+	for _, container := range containers {
+		if err := runtime.Register(container); err != nil {
+			utils.Debugf("Failed to register container %s: %s", container.ID, err)
+			continue
+		}
+	}
+	if os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" {
+		fmt.Printf("\bdone.\n")
+	}
 
-			if len(contents) > 0 {
-				utils.Debugf("[migration] Begin migration of %s", container.ID)
+	return nil
+}
 
-				image, err := runtime.graph.Get(container.Image)
-				if err != nil {
-					utils.Debugf("[migratoin] Failed to get image %s", err)
-					continue
-				}
+func migrateToDeviceMapper(runtime *Runtime, containers []*Container) error {
+	var (
+		image    *Image
+		contents []os.FileInfo
+		err      error
+	)
 
-				unmount := func() {
-					if err := image.Unmount(runtime, container.RootfsPath(), container.ID); err != nil {
-						utils.Debugf("[migraton] Failed to unmount image %s", err)
-					}
-				}
+	fmt.Printf("Migrating %d containers to new storage backend\n", len(containers))
+	for _, container := range containers {
+		if container.State.Running {
+			fmt.Printf("WARNING - Cannot migrate %s because the container is running.  Please stop the container and relaunch the daemon!")
+			continue
+		}
 
-				if err := image.Mount(runtime, container.RootfsPath(), container.rwPath(), container.ID); err != nil {
-					utils.Debugf("[migratoin] Failed to mount image %s", err)
-					continue
-				}
+		fmt.Printf("Migrating %s\n", container.ID)
 
-				if err := image.applyLayer(container.rwPath(), container.RootfsPath()); err != nil {
-					utils.Debugf("[migration] Failed to apply layer %s", err)
-					unmount()
-					continue
-				}
+		if contents, err = ioutil.ReadDir(container.rwPath()); err != nil {
+			if !os.IsNotExist(err) {
+				fmt.Printf("Error reading rw dir %s\n", err)
+			}
+			continue
+		}
 
-				unmount()
+		if len(contents) == 0 {
+			fmt.Printf("Skipping migration of %s because rw layer contains no changes\n")
+			continue
+		}
 
-				if err := os.RemoveAll(container.rwPath()); err != nil {
-					utils.Debugf("[migration] Failed to remove rw dir %s", err)
-				}
+		if image, err = runtime.graph.Get(container.Image); err != nil {
+			fmt.Printf("Failed to fetch image %s\n", err)
+			continue
+		}
 
-				utils.Debugf("[migration] End migration of %s", container.ID)
+		unmount := func() {
+			if err = image.Unmount(runtime, container.RootfsPath(), container.ID); err != nil {
+				fmt.Printf("Failed to unmount image %s\n", err)
 			}
 		}
 
-	}
+		if err = image.Mount(runtime, container.RootfsPath(), container.rwPath(), container.ID); err != nil {
+			fmt.Printf("Failed to mount image %s\n", err)
+			continue
+		}
 
-	for _, container := range containers {
-		if err := runtime.Register(container); err != nil {
-			utils.Debugf("Failed to register container %s: %s", container.ID, err)
+		if err = image.applyLayer(container.rwPath(), container.RootfsPath()); err != nil {
+			fmt.Printf("Failed to apply layer in storage backend %s\n", err)
+			unmount()
+			continue
 		}
-	}
 
-	if os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" {
-		fmt.Printf("\bdone.\n")
+		unmount()
+
+		if err = os.RemoveAll(container.rwPath()); err != nil {
+			fmt.Printf("Failed to remove rw layer %s\n", err)
+		}
+
+		fmt.Printf("Successful migration for %s\n", container.ID)
 	}
+	fmt.Printf("Migration complete\n")
+
 	return nil
 }
 

+ 1 - 1
runtime_test.go

@@ -151,7 +151,7 @@ func init() {
 	deviceset := devmapper.NewDeviceSetDM(unitTestStoreDevicesBase)
 	// Create a device, which triggers the initiation of the base FS
 	// This avoids other tests doing this and timing out
-	deviceset.AddDevice("init","")
+	deviceset.AddDevice("init", "")
 
 	// Make it our Store root
 	if runtime, err := NewRuntimeFromDirectory(unitTestStoreBase, deviceset, false); err != nil {