func migrateImage(id, root string, ls graphIDRegistrar, is image.Store, ms metadata.Store, mappings map[string]image.ID) (err error) { defer func() { if err != nil { logrus.Errorf("migration failed for %v, err: %v", id, err) } }() parent, err := getParent(filepath.Join(root, graphDirName, id)) if err != nil { return err } var parentID image.ID if parent != "" { var exists bool if parentID, exists = mappings[parent]; !exists { if err := migrateImage(parent, root, ls, is, ms, mappings); err != nil { // todo: fail or allow broken chains? return err } parentID = mappings[parent] } } rootFS := image.NewRootFS() var history []image.History if parentID != "" { parentImg, err := is.Get(parentID) if err != nil { return err } rootFS = parentImg.RootFS history = parentImg.History } diffIDData, err := ioutil.ReadFile(filepath.Join(root, graphDirName, id, migrationDiffIDFileName)) if err != nil { return err } diffID, err := digest.ParseDigest(string(diffIDData)) if err != nil { return err } sizeStr, err := ioutil.ReadFile(filepath.Join(root, graphDirName, id, migrationSizeFileName)) if err != nil { return err } size, err := strconv.ParseInt(string(sizeStr), 10, 64) if err != nil { return err } layer, err := ls.RegisterByGraphID(id, rootFS.ChainID(), layer.DiffID(diffID), filepath.Join(root, graphDirName, id, migrationTarDataFileName), size) if err != nil { return err } logrus.Infof("migrated layer %s to %s", id, layer.DiffID()) jsonFile := filepath.Join(root, graphDirName, id, "json") imageJSON, err := ioutil.ReadFile(jsonFile) if err != nil { return err } h, err := imagev1.HistoryFromConfig(imageJSON, false) if err != nil { return err } history = append(history, h) rootFS.Append(layer.DiffID()) config, err := imagev1.MakeConfigFromV1Config(imageJSON, rootFS, history) if err != nil { return err } strongID, err := is.Create(config) if err != nil { return err } logrus.Infof("migrated image %s to %s", id, strongID) if parentID != "" { if err := is.SetParent(strongID, parentID); err != nil { return err } } checksum, err := ioutil.ReadFile(filepath.Join(root, graphDirName, id, "checksum")) if err == nil { // best effort dgst, err := digest.ParseDigest(string(checksum)) if err == nil { V2MetadataService := metadata.NewV2MetadataService(ms) V2MetadataService.Add(layer.DiffID(), metadata.V2Metadata{Digest: dgst}) } } _, err = ls.Release(layer) if err != nil { return err } mappings[id] = strongID return }
func migrateImage(id, root string, ls graphIDRegistrar, is image.Store, ms metadata.Store, mappings map[string]image.ID) (err error) { defer func() { if err != nil { logrus.Errorf("migration failed for %v, err: %v", id, err) } }() jsonFile := filepath.Join(root, graphDirName, id, "json") imageJSON, err := ioutil.ReadFile(jsonFile) if err != nil { return err } var parent struct { Parent string ParentID digest.Digest `json:"parent_id"` } if err := json.Unmarshal(imageJSON, &parent); err != nil { return err } if parent.Parent == "" && parent.ParentID != "" { // v1.9 parent.Parent = parent.ParentID.Hex() } // compatibilityID for parent parentCompatibilityID, err := ioutil.ReadFile(filepath.Join(root, graphDirName, id, "parent")) if err == nil && len(parentCompatibilityID) > 0 { parent.Parent = string(parentCompatibilityID) } var parentID image.ID if parent.Parent != "" { var exists bool if parentID, exists = mappings[parent.Parent]; !exists { if err := migrateImage(parent.Parent, root, ls, is, ms, mappings); err != nil { // todo: fail or allow broken chains? return err } parentID = mappings[parent.Parent] } } rootFS := image.NewRootFS() var history []image.History if parentID != "" { parentImg, err := is.Get(parentID) if err != nil { return err } rootFS = parentImg.RootFS history = parentImg.History } layer, err := ls.RegisterByGraphID(id, rootFS.ChainID(), filepath.Join(filepath.Join(root, graphDirName, id, tarDataFileName))) if err != nil { return err } logrus.Infof("migrated layer %s to %s", id, layer.DiffID()) h, err := imagev1.HistoryFromConfig(imageJSON, false) if err != nil { return err } history = append(history, h) rootFS.Append(layer.DiffID()) config, err := imagev1.MakeConfigFromV1Config(imageJSON, rootFS, history) if err != nil { return err } strongID, err := is.Create(config) if err != nil { return err } logrus.Infof("migrated image %s to %s", id, strongID) if parentID != "" { if err := is.SetParent(strongID, parentID); err != nil { return err } } checksum, err := ioutil.ReadFile(filepath.Join(root, graphDirName, id, "checksum")) if err == nil { // best effort dgst, err := digest.ParseDigest(string(checksum)) if err == nil { blobSumService := metadata.NewBlobSumService(ms) blobSumService.Add(layer.DiffID(), dgst) } } _, err = ls.Release(layer) if err != nil { return err } mappings[id] = strongID return }