Переглянути джерело

Migrate images with parent relationship

Michael Crosby 11 роки тому
батько
коміт
f88b760809
1 змінених файлів з 74 додано та 7 видалено
  1. 74 7
      graphdriver/aufs/migrate.go

+ 74 - 7
graphdriver/aufs/migrate.go

@@ -1,34 +1,83 @@
 package aufs
 
 import (
+	"encoding/json"
 	"fmt"
 	"io/ioutil"
 	"os"
 	"path"
+	"time"
 )
 
-func exists(pth string) bool {
+type imageMetadata struct {
+	ID            string    `json:"id"`
+	ParentID      string    `json:"parent,omitempty"`
+	Created       time.Time `json:"created"`
+	DockerVersion string    `json:"docker_version,omitempty"`
+	Architecture  string    `json:"architecture,omitempty"`
+
+	parent *imageMetadata
+}
+
+func pathExists(pth string) bool {
 	if _, err := os.Stat(pth); err != nil {
 		return false
 	}
 	return true
 }
 
+// Migrate existing images and containers from docker < 0.7.x
 func (a *AufsDriver) Migrate(pth string) error {
 	fis, err := ioutil.ReadDir(pth)
 	if err != nil {
 		return err
 	}
+	var (
+		metadata = make(map[string]*imageMetadata)
+		current  *imageMetadata
+		exists   bool
+	)
+
+	// Load metadata
 	for _, fi := range fis {
-		if fi.IsDir() && exists(path.Join(pth, fi.Name(), "layer")) && !a.Exists(fi.Name()) {
-			if err := tryRelocate(path.Join(pth, fi.Name(), "layer"), path.Join(a.rootPath(), "diff", fi.Name())); err != nil {
-				return err
-			}
-			if err := a.Create(fi.Name(), ""); err != nil {
-				return err
+		if id := fi.Name(); fi.IsDir() && pathExists(path.Join(pth, id, "layer")) && !a.Exists(id) {
+			if current, exists = metadata[id]; !exists {
+				current, err = loadMetadata(pth, id)
+				if err != nil {
+					return err
+				}
+				metadata[id] = current
 			}
 		}
 	}
+
+	// Recreate tree
+	for _, v := range metadata {
+		v.parent = metadata[v.ParentID]
+	}
+
+	// Perform image migration
+	for _, v := range metadata {
+		if err := migrateImage(v, a, pth); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func migrateImage(m *imageMetadata, a *AufsDriver, pth string) error {
+	if !pathExists(path.Join(a.rootPath(), "diff", m.ID)) {
+		if m.parent != nil {
+			migrateImage(m.parent, a, pth)
+		}
+		if err := tryRelocate(path.Join(pth, m.ID, "layer"), path.Join(a.rootPath(), "diff", m.ID)); err != nil {
+			return err
+		}
+
+		if err := a.Create(m.ID, m.ParentID); err != nil {
+			return err
+		}
+	}
 	return nil
 }
 
@@ -42,3 +91,21 @@ func tryRelocate(oldPath, newPath string) error {
 	}
 	return nil
 }
+
+func loadMetadata(pth, id string) (*imageMetadata, error) {
+	f, err := os.Open(path.Join(pth, id, "json"))
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	var (
+		out = &imageMetadata{}
+		dec = json.NewDecoder(f)
+	)
+
+	if err := dec.Decode(out); err != nil {
+		return nil, err
+	}
+	return out, nil
+}