diff --git a/image_recover_tool/image-check/daemon/commands/check/check.go b/image_recover_tool/image-check/daemon/commands/check/check.go index 707b490f042e04c295eb6a315f0e5b25ea196027..384bdb9418741bf76eca0b6b79dda2d9b71d5d4d 100644 --- a/image_recover_tool/image-check/daemon/commands/check/check.go +++ b/image_recover_tool/image-check/daemon/commands/check/check.go @@ -35,12 +35,17 @@ var overlay2Command = cli.Command{ Name: "quiet, q", Usage: "Only show numeric IDs", }, + cli.BoolFlag{ + Name: "remove, rm", + Usage: "remove isolated chain metadata directory", + }, }, Action: func(context *cli.Context) error { var ( long = context.Bool("long") fast = context.Bool("fast") quiet = context.Bool("quiet") + remove = context.Bool("remove") ) client, err := commands.NewDaemon(context) if err != nil { @@ -62,6 +67,20 @@ var overlay2Command = cli.Command{ return fmt.Errorf("failed to check storage file: %v", err) } imageList := imageStore.GetErrImageList(chainIDList) + isolateChainList := imageStore.GetNoImageIDLayer(chainIDList) + if len(isolateChainList) != 0 { + if remove { + if err = layerStore.RemoveLoneChainID(isolateChainList, quiet); err != nil { + return fmt.Errorf("failed to remove chainID: %v", err) + } + } else { + fmt.Println("can't find cacheid and imageid by chainid as follows:") + for _, loseid := range isolateChainList { + fmt.Println(loseid[7:]) + } + } + } + if !quiet { fmt.Println("ERROR IMAGE") } diff --git a/image_recover_tool/image-check/daemon/config/config.go b/image_recover_tool/image-check/daemon/config/config.go index 6e18fa81acbeac14025ffd7fe0e131d7a2bb0f14..a9437990b36d43ef07e908f4d617a0453e418db0 100644 --- a/image_recover_tool/image-check/daemon/config/config.go +++ b/image_recover_tool/image-check/daemon/config/config.go @@ -35,7 +35,8 @@ func GetDockerRoot(dockerdConfigPath, root, driver string, storageIsolate string if exist { fileConfig, err := dc.getConfiguration(dockerdConfigPath) if err != nil { - logrus.Warnf("Failed to get docker configuration file: %v", err) + logrus.Errorf("Failed to get docker configuration file: %v", err) + return nil, err } if fileConfig.Root != "" { dc.Root = fileConfig.Root diff --git a/image_recover_tool/image-check/image/image.go b/image_recover_tool/image-check/image/image.go index deaeb9296e0fc2c226c2482af83993606acf3a74..2760f5534c08737dc1ff51a4631a0b6a9022613e 100644 --- a/image_recover_tool/image-check/image/image.go +++ b/image_recover_tool/image-check/image/image.go @@ -12,9 +12,11 @@ import ( "github.com/sirupsen/logrus" ) + type Store interface { GetImageChainID(id string) ([]digest.Digest, error) GetRelationImageList(id string) ([]string, error) + GetNoImageIDLayer(id []layer.ChainID) []layer.ChainID GetErrImageList(id []layer.ChainID) []string GetAllErrImageList(id []layer.ChainID) []string RemoveErrImage(id string) error @@ -93,6 +95,18 @@ func (is *store) getRelationImage(id string, chainID digest.Digest, imagesMap ma return relationImages } +// 考虑镜像的overlay2层有损坏,但无法获取对应镜像ID的情况 +func (is *store) GetNoImageIDLayer(chainID []layer.ChainID) []layer.ChainID { + var badchainid []layer.ChainID + for _, chain_id := range chainID { + _, ok := is.chainMap[digest.Digest(chain_id)] + if !ok { + badchainid = append(badchainid, chain_id) + } + } + return badchainid +} + // 根据chainID找到的错误镜像 func (is *store) GetErrImageList(chainID []layer.ChainID) []string { var badimageid []string diff --git a/image_recover_tool/image-check/layer/check_overlay2.go b/image_recover_tool/image-check/layer/check_overlay2.go index b2a31af34453923a22fb269177f19e8a480476a3..7764b5d6386905d367160c3a3723d4dc9e25c67d 100644 --- a/image_recover_tool/image-check/layer/check_overlay2.go +++ b/image_recover_tool/image-check/layer/check_overlay2.go @@ -149,6 +149,11 @@ func (d *Driver) Remove(id string, quiet bool) error { } dir := d.dir(id) + if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) { + logrus.Warnf("Layer not exist: %v", err) + return nil + } + lid, err := ioutil.ReadFile(path.Clean(path.Join(dir, "link"))) if err == nil { if len(lid) == 0 { diff --git a/image_recover_tool/image-check/layer/layer_store.go b/image_recover_tool/image-check/layer/layer_store.go index 3da6ee332bfd581f03db48a9aa2bc889030c6b50..86ddfb625d90ddd72c11494d64a1691f799a9feb 100644 --- a/image_recover_tool/image-check/layer/layer_store.go +++ b/image_recover_tool/image-check/layer/layer_store.go @@ -19,6 +19,7 @@ type DiffID digest.Digest type Store interface { CheckStorageFile() ([]ChainID, error) CheckStorageData([]digest.Digest) ([]ChainID, error) + RemoveLoneChainID([]ChainID, bool) error RemoveErrChainID(flag bool) error RemoveErrCacheID(flag bool) error GerErrLayerID() []ChainID @@ -283,6 +284,35 @@ func (ls *layerStore) GerErrCacheID() { } } } +//deleted the isolate image layer which's data is correlated +func (ls *layerStore) RemoveLoneChainID(chain_ids []ChainID, quiet bool) error { + if len(chain_ids) == 0 { + return nil + } + + for _, chain_ID := range chain_ids { + cache_ID, ok := ls.storageMap[chain_ID] + dir := ls.store.getLayerDirectory(ChainID(chain_ID)) + // removed metadate localed in layerdb directory + if err := os.RemoveAll(dir); err != nil && !os.IsNotExist(err) { + logrus.Errorf("Failed to remove %s: %v", dir, err) + return err + } + logrus.Infof("Deleted useless metadata directory: %s", dir) + if !quiet { + fmt.Println("Deleted useless metadata directory: ", dir) + } + //removed bad layer date localed in overlay2 directory + if ok { + if err := ls.driver.Remove(cache_ID, quiet); err != nil { + logrus.Errorf("Failed to remove layer %s", cache_ID) + return err + } + } + } + + return nil +} func (ls *layerStore) RemoveErrChainID(quiet bool) error { if len(ls.errChainID) == 0 {