442 lines
15 KiB
Diff
442 lines
15 KiB
Diff
|
|
From b555ed1bb121b0740665fb0db9f7fea3b339f98c Mon Sep 17 00:00:00 2001
|
||
|
|
From: lujingxiao <lujingxiao@huawei.com>
|
||
|
|
Date: Sat, 19 Jan 2019 11:22:22 +0800
|
||
|
|
Subject: [PATCH 020/111] cleanup: remove redundant files in
|
||
|
|
graphdriver and mount dir
|
||
|
|
|
||
|
|
reason:remove redundant files in graphdriver and mount dir
|
||
|
|
|
||
|
|
Change-Id: Ie75b78ac1e288d2c909dcd446636d16b1dd60363
|
||
|
|
Signed-off-by: yangshukui <yangshukui@huawei.com>
|
||
|
|
Signed-off-by: zhangsong34 <zhangsong34@huawei.com>
|
||
|
|
Signed-off-by: lujingxiao <lujingxiao@huawei.com>
|
||
|
|
---
|
||
|
|
components/engine/daemon/daemon.go | 28 ++++++-
|
||
|
|
.../engine/daemon/graphdriver/aufs/aufs.go | 5 ++
|
||
|
|
.../engine/daemon/graphdriver/btrfs/btrfs.go | 5 ++
|
||
|
|
.../daemon/graphdriver/devmapper/driver.go | 5 ++
|
||
|
|
.../engine/daemon/graphdriver/driver.go | 2 +
|
||
|
|
.../daemon/graphdriver/overlay/overlay.go | 5 ++
|
||
|
|
.../daemon/graphdriver/overlay2/overlay.go | 19 +++++
|
||
|
|
components/engine/daemon/graphdriver/proxy.go | 5 ++
|
||
|
|
.../engine/daemon/graphdriver/vfs/driver.go | 5 ++
|
||
|
|
.../engine/daemon/graphdriver/zfs/zfs.go | 5 ++
|
||
|
|
components/engine/daemon/images/service.go | 4 +
|
||
|
|
.../engine/distribution/xfer/download_test.go | 4 +
|
||
|
|
components/engine/layer/layer.go | 1 +
|
||
|
|
components/engine/layer/layer_store.go | 73 +++++++++++++++++++
|
||
|
|
components/engine/pkg/ioutils/fswriters.go | 36 +++++++++
|
||
|
|
components/engine/reference/store.go | 1 +
|
||
|
|
16 files changed, 201 insertions(+), 2 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go
|
||
|
|
index f7635f27cc..4546587369 100644
|
||
|
|
--- a/components/engine/daemon/daemon.go
|
||
|
|
+++ b/components/engine/daemon/daemon.go
|
||
|
|
@@ -262,7 +262,15 @@ func (daemon *Daemon) restore() error {
|
||
|
|
id := v.Name()
|
||
|
|
container, err := daemon.load(id)
|
||
|
|
if err != nil {
|
||
|
|
- logrus.Errorf("Failed to load container %v: %v", id, err)
|
||
|
|
+ logrus.Errorf("Failed to load container %v: %v. Try to remove it", id, err)
|
||
|
|
+ cdir := filepath.Join(daemon.repository, id)
|
||
|
|
+ // to make sure we are not in fd exhausted state
|
||
|
|
+ if !strings.Contains(err.Error(), "too many open files") {
|
||
|
|
+ logrus.Warnf("remove invalid container data: %s", cdir)
|
||
|
|
+ if err := system.EnsureRemoveAll(cdir); err != nil {
|
||
|
|
+ logrus.Warnf("remove %s error: %v", cdir, err)
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
if !system.IsOSSupported(container.OS) {
|
||
|
|
@@ -274,7 +282,12 @@ func (daemon *Daemon) restore() error {
|
||
|
|
if (container.Driver == "" && currentDriverForContainerOS == "aufs") || container.Driver == currentDriverForContainerOS {
|
||
|
|
rwlayer, err := daemon.imageService.GetLayerByID(container.ID, container.OS)
|
||
|
|
if err != nil {
|
||
|
|
- logrus.Errorf("Failed to load container mount %v: %v", id, err)
|
||
|
|
+ logrus.Errorf("Failed to load container mount %v: %v. Try to remove it", id, err)
|
||
|
|
+ cdir := filepath.Join(daemon.repository, id)
|
||
|
|
+ logrus.Warnf("remove invalid container data: %s", cdir)
|
||
|
|
+ if err := system.EnsureRemoveAll(cdir); err != nil {
|
||
|
|
+ logrus.Warnf("remove %s error: %v", cdir, err)
|
||
|
|
+ }
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
container.RWLayer = rwlayer
|
||
|
|
@@ -472,6 +485,17 @@ func (daemon *Daemon) restore() error {
|
||
|
|
}(c)
|
||
|
|
}
|
||
|
|
wg.Wait()
|
||
|
|
+
|
||
|
|
+ containerIDs := make(map[string]struct{})
|
||
|
|
+ for cid, _ := range containers {
|
||
|
|
+ containerIDs[cid] = struct{}{}
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ err = daemon.imageService.LayerStoreForOS(runtime.GOOS).CleanupRedundant(containerIDs)
|
||
|
|
+ if err != nil {
|
||
|
|
+ logrus.Errorf("cleanup redundant IDs in layerStore failed %s", err)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
daemon.netController, err = daemon.initNetworkController(daemon.configStore, activeSandboxes)
|
||
|
|
if err != nil {
|
||
|
|
return fmt.Errorf("Error initializing network controller: %v", err)
|
||
|
|
diff --git a/components/engine/daemon/graphdriver/aufs/aufs.go b/components/engine/daemon/graphdriver/aufs/aufs.go
|
||
|
|
index 114aa9a615..303138d48a 100644
|
||
|
|
--- a/components/engine/daemon/graphdriver/aufs/aufs.go
|
||
|
|
+++ b/components/engine/daemon/graphdriver/aufs/aufs.go
|
||
|
|
@@ -230,6 +230,11 @@ func (a *Driver) Exists(id string) bool {
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
|
||
|
|
+// GetAll not implemented
|
||
|
|
+func (a *Driver) GetAll() []string {
|
||
|
|
+ return []string{}
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
// CreateReadWrite creates a layer that is writable for use as a container
|
||
|
|
// file system.
|
||
|
|
func (a *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
|
||
|
|
diff --git a/components/engine/daemon/graphdriver/btrfs/btrfs.go b/components/engine/daemon/graphdriver/btrfs/btrfs.go
|
||
|
|
index 7ce7edef36..d04ce10be9 100644
|
||
|
|
--- a/components/engine/daemon/graphdriver/btrfs/btrfs.go
|
||
|
|
+++ b/components/engine/daemon/graphdriver/btrfs/btrfs.go
|
||
|
|
@@ -167,6 +167,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) {
|
||
|
|
return nil, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
+// GetAll not implemented
|
||
|
|
+func (a *Driver) GetAll() []string {
|
||
|
|
+ return []string{}
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
// Cleanup unmounts the home directory.
|
||
|
|
func (d *Driver) Cleanup() error {
|
||
|
|
err := d.subvolDisableQuota()
|
||
|
|
diff --git a/components/engine/daemon/graphdriver/devmapper/driver.go b/components/engine/daemon/graphdriver/devmapper/driver.go
|
||
|
|
index 623843f852..a56b26bc8f 100644
|
||
|
|
--- a/components/engine/daemon/graphdriver/devmapper/driver.go
|
||
|
|
+++ b/components/engine/daemon/graphdriver/devmapper/driver.go
|
||
|
|
@@ -126,6 +126,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) {
|
||
|
|
return metadata, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
+// GetAll not implemented
|
||
|
|
+func (a *Driver) GetAll() []string {
|
||
|
|
+ return []string{}
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
// Cleanup unmounts a device.
|
||
|
|
func (d *Driver) Cleanup() error {
|
||
|
|
err := d.DeviceSet.Shutdown(d.home)
|
||
|
|
diff --git a/components/engine/daemon/graphdriver/driver.go b/components/engine/daemon/graphdriver/driver.go
|
||
|
|
index a9e1957393..672257a9b5 100644
|
||
|
|
--- a/components/engine/daemon/graphdriver/driver.go
|
||
|
|
+++ b/components/engine/daemon/graphdriver/driver.go
|
||
|
|
@@ -78,6 +78,8 @@ type ProtoDriver interface {
|
||
|
|
// held by the driver, e.g., unmounting all layered filesystems
|
||
|
|
// known to this driver.
|
||
|
|
Cleanup() error
|
||
|
|
+ // GetAll returns all the mountid exists in this driver
|
||
|
|
+ GetAll() []string
|
||
|
|
}
|
||
|
|
|
||
|
|
// DiffDriver is the interface to use to implement graph diffs
|
||
|
|
diff --git a/components/engine/daemon/graphdriver/overlay/overlay.go b/components/engine/daemon/graphdriver/overlay/overlay.go
|
||
|
|
index 08c05e192f..d59a6dfc83 100644
|
||
|
|
--- a/components/engine/daemon/graphdriver/overlay/overlay.go
|
||
|
|
+++ b/components/engine/daemon/graphdriver/overlay/overlay.go
|
||
|
|
@@ -264,6 +264,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) {
|
||
|
|
return metadata, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
+// GetAll not implemented
|
||
|
|
+func (a *Driver) GetAll() []string {
|
||
|
|
+ return []string{}
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
// Cleanup any state created by overlay which should be cleaned when daemon
|
||
|
|
// is being shutdown. For now, we just have to unmount the bind mounted
|
||
|
|
// we had created.
|
||
|
|
diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go
|
||
|
|
index b969582eb3..7290616bae 100644
|
||
|
|
--- a/components/engine/daemon/graphdriver/overlay2/overlay.go
|
||
|
|
+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go
|
||
|
|
@@ -507,6 +507,25 @@ func (d *Driver) dir(id string) string {
|
||
|
|
return path.Join(d.home, id)
|
||
|
|
}
|
||
|
|
|
||
|
|
+func (d *Driver) GetAll() []string {
|
||
|
|
+ var ids []string
|
||
|
|
+
|
||
|
|
+ fs, err := ioutil.ReadDir(d.home)
|
||
|
|
+ if err != nil {
|
||
|
|
+ logrus.Errorf("open directory(%s) failed: %s", d.home, err)
|
||
|
|
+ return ids
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for _, f := range fs {
|
||
|
|
+ if len(f.Name()) >= 64 {
|
||
|
|
+ ids = append(ids, f.Name())
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return ids
|
||
|
|
+
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
func (d *Driver) getLowerDirs(id string) ([]string, error) {
|
||
|
|
var lowersArray []string
|
||
|
|
lowers, err := ioutil.ReadFile(path.Join(d.dir(id), lowerFile))
|
||
|
|
diff --git a/components/engine/daemon/graphdriver/proxy.go b/components/engine/daemon/graphdriver/proxy.go
|
||
|
|
index cb350d8074..6c132d40a8 100644
|
||
|
|
--- a/components/engine/daemon/graphdriver/proxy.go
|
||
|
|
+++ b/components/engine/daemon/graphdriver/proxy.go
|
||
|
|
@@ -91,6 +91,11 @@ func (d *graphDriverProxy) Capabilities() Capabilities {
|
||
|
|
return d.caps
|
||
|
|
}
|
||
|
|
|
||
|
|
+// GetAll not implemented
|
||
|
|
+func (d *graphDriverProxy) GetAll() []string {
|
||
|
|
+ return []string{}
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error {
|
||
|
|
return d.create("GraphDriver.CreateReadWrite", id, parent, opts)
|
||
|
|
}
|
||
|
|
diff --git a/components/engine/daemon/graphdriver/vfs/driver.go b/components/engine/daemon/graphdriver/vfs/driver.go
|
||
|
|
index 33e6bf6cc9..8c2947d9ee 100644
|
||
|
|
--- a/components/engine/daemon/graphdriver/vfs/driver.go
|
||
|
|
+++ b/components/engine/daemon/graphdriver/vfs/driver.go
|
||
|
|
@@ -64,6 +64,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) {
|
||
|
|
return nil, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
+// GetAll not implemented
|
||
|
|
+func (a *Driver) GetAll() []string {
|
||
|
|
+ return []string{}
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
// Cleanup is used to implement graphdriver.ProtoDriver. There is no cleanup required for this driver.
|
||
|
|
func (d *Driver) Cleanup() error {
|
||
|
|
return nil
|
||
|
|
diff --git a/components/engine/daemon/graphdriver/zfs/zfs.go b/components/engine/daemon/graphdriver/zfs/zfs.go
|
||
|
|
index 8a798778d2..e1e2d0d823 100644
|
||
|
|
--- a/components/engine/daemon/graphdriver/zfs/zfs.go
|
||
|
|
+++ b/components/engine/daemon/graphdriver/zfs/zfs.go
|
||
|
|
@@ -227,6 +227,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) {
|
||
|
|
}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
+// GetAll not implemented
|
||
|
|
+func (a *Driver) GetAll() []string {
|
||
|
|
+ return []string{}
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
func (d *Driver) cloneFilesystem(name, parentName string) error {
|
||
|
|
snapshotName := fmt.Sprintf("%d", time.Now().Nanosecond())
|
||
|
|
parentDataset := zfs.Dataset{Name: parentName}
|
||
|
|
diff --git a/components/engine/daemon/images/service.go b/components/engine/daemon/images/service.go
|
||
|
|
index e8df5cb649..8d187e2603 100644
|
||
|
|
--- a/components/engine/daemon/images/service.go
|
||
|
|
+++ b/components/engine/daemon/images/service.go
|
||
|
|
@@ -177,6 +177,10 @@ func (i *ImageService) GraphDriverForOS(os string) string {
|
||
|
|
return i.layerStores[os].DriverName()
|
||
|
|
}
|
||
|
|
|
||
|
|
+func (i *ImageService) LayerStoreForOS(os string) layer.Store {
|
||
|
|
+ return i.layerStores[os]
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
// ReleaseLayer releases a layer allowing it to be removed
|
||
|
|
// called from delete.go Daemon.cleanupContainer(), and Daemon.containerExport()
|
||
|
|
func (i *ImageService) ReleaseLayer(rwlayer layer.RWLayer, containerOS string) error {
|
||
|
|
diff --git a/components/engine/distribution/xfer/download_test.go b/components/engine/distribution/xfer/download_test.go
|
||
|
|
index 4ab3705af6..91153591ed 100644
|
||
|
|
--- a/components/engine/distribution/xfer/download_test.go
|
||
|
|
+++ b/components/engine/distribution/xfer/download_test.go
|
||
|
|
@@ -150,6 +150,10 @@ func (ls *mockLayerStore) DriverStatus() [][2]string {
|
||
|
|
return [][2]string{}
|
||
|
|
}
|
||
|
|
|
||
|
|
+func (ls *mockLayerStore) CleanupRedundant(cids map[string]struct{}) error {
|
||
|
|
+ return nil
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
func (ls *mockLayerStore) DriverName() string {
|
||
|
|
return "mock"
|
||
|
|
}
|
||
|
|
diff --git a/components/engine/layer/layer.go b/components/engine/layer/layer.go
|
||
|
|
index d0c7fa8608..425006854d 100644
|
||
|
|
--- a/components/engine/layer/layer.go
|
||
|
|
+++ b/components/engine/layer/layer.go
|
||
|
|
@@ -193,6 +193,7 @@ type Store interface {
|
||
|
|
Cleanup() error
|
||
|
|
DriverStatus() [][2]string
|
||
|
|
DriverName() string
|
||
|
|
+ CleanupRedundant(map[string]struct{}) error
|
||
|
|
}
|
||
|
|
|
||
|
|
// DescribableStore represents a layer store capable of storing
|
||
|
|
diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go
|
||
|
|
index bc3e8719fc..6a568e9d9b 100644
|
||
|
|
--- a/components/engine/layer/layer_store.go
|
||
|
|
+++ b/components/engine/layer/layer_store.go
|
||
|
|
@@ -5,6 +5,7 @@ import (
|
||
|
|
"fmt"
|
||
|
|
"io"
|
||
|
|
"io/ioutil"
|
||
|
|
+ "strings"
|
||
|
|
"sync"
|
||
|
|
|
||
|
|
"github.com/docker/distribution"
|
||
|
|
@@ -460,6 +461,78 @@ func (ls *layerStore) releaseLayer(l *roLayer) ([]Metadata, error) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+// CleanupRedundant will cleanup useless dirs in image/mount and driver
|
||
|
|
+func (ls *layerStore) CleanupRedundant(cs map[string]struct{}) error {
|
||
|
|
+ cids, err := ls.getAndCleanCacheIDs(cs)
|
||
|
|
+ if err != nil {
|
||
|
|
+ return fmt.Errorf("get cacheIDs failed: %s", err)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ ids := ls.driver.GetAll()
|
||
|
|
+
|
||
|
|
+ for _, id := range ids {
|
||
|
|
+ if _, ok := cids[id]; !ok {
|
||
|
|
+ logrus.Warnf("remove redundant cacheID: %s", id)
|
||
|
|
+ ls.driver.Remove(id)
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ return nil
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+func (ls *layerStore) getAndCleanCacheIDs(cs map[string]struct{}) (map[string]struct{}, error) {
|
||
|
|
+ cids := make(map[string]struct{})
|
||
|
|
+
|
||
|
|
+ ids, mountids, err := ls.store.List()
|
||
|
|
+ if err != nil {
|
||
|
|
+ return cids, fmt.Errorf("failed to get mount list from store: %s", err)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for _, id := range ids {
|
||
|
|
+ cid, err := ls.store.GetCacheID(id)
|
||
|
|
+ if err != nil {
|
||
|
|
+ logrus.Errorf("failed to get cache id for %s: %s", id, err)
|
||
|
|
+ // just return if we are not in fd exhausted state
|
||
|
|
+ if strings.Contains(err.Error(), "too many open files") {
|
||
|
|
+ return cids, err
|
||
|
|
+ }
|
||
|
|
+ continue
|
||
|
|
+ }
|
||
|
|
+ cids[cid] = struct{}{}
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for _, mid := range mountids {
|
||
|
|
+ // if mid not exist in current container list, just remove it
|
||
|
|
+ if _, ok := cs[mid]; !ok {
|
||
|
|
+ logrus.Warnf("remove redundant mountID: %s", mid)
|
||
|
|
+ ls.store.RemoveMount(mid)
|
||
|
|
+ continue
|
||
|
|
+ }
|
||
|
|
+ mountID, err := ls.store.GetMountID(mid)
|
||
|
|
+ if err != nil {
|
||
|
|
+ logrus.Errorf("failed to get mount id for %s: %s", mid, err)
|
||
|
|
+ // just return if we are not in fd exhausted state
|
||
|
|
+ if strings.Contains(err.Error(), "too many open files") {
|
||
|
|
+ return cids, err
|
||
|
|
+ }
|
||
|
|
+ } else {
|
||
|
|
+ cids[mountID] = struct{}{}
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ initID, err := ls.store.GetInitID(mid)
|
||
|
|
+ if err != nil {
|
||
|
|
+ logrus.Errorf("failed to get init id for %s: %s", mid, err)
|
||
|
|
+ // just return if we are not in fd exhausted state
|
||
|
|
+ if strings.Contains(err.Error(), "too many open files") {
|
||
|
|
+ return cids, err
|
||
|
|
+ }
|
||
|
|
+ continue
|
||
|
|
+ }
|
||
|
|
+ cids[initID] = struct{}{}
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return cids, nil
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
func (ls *layerStore) Release(l Layer) ([]Metadata, error) {
|
||
|
|
ls.layerL.Lock()
|
||
|
|
defer ls.layerL.Unlock()
|
||
|
|
diff --git a/components/engine/pkg/ioutils/fswriters.go b/components/engine/pkg/ioutils/fswriters.go
|
||
|
|
index 534d66ac26..093f11ad8e 100644
|
||
|
|
--- a/components/engine/pkg/ioutils/fswriters.go
|
||
|
|
+++ b/components/engine/pkg/ioutils/fswriters.go
|
||
|
|
@@ -5,6 +5,9 @@ import (
|
||
|
|
"io/ioutil"
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
+ "strings"
|
||
|
|
+
|
||
|
|
+ "github.com/sirupsen/logrus"
|
||
|
|
)
|
||
|
|
|
||
|
|
// NewAtomicFileWriter returns WriteCloser so that writing to it writes to a
|
||
|
|
@@ -27,6 +30,39 @@ func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, err
|
||
|
|
}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
+func CleanupTmpFilesRecursive(rootDir string) {
|
||
|
|
+ var removals []string
|
||
|
|
+ filepath.Walk(rootDir, func(path string, f os.FileInfo, err error) error {
|
||
|
|
+ if strings.HasPrefix(f.Name(), ".tmp-") {
|
||
|
|
+ removals = append(removals, path)
|
||
|
|
+ }
|
||
|
|
+ return nil
|
||
|
|
+ })
|
||
|
|
+
|
||
|
|
+ for _, r := range removals {
|
||
|
|
+ os.RemoveAll(r)
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+// CleanupAtomicFile cleanup redundant atomic files
|
||
|
|
+func CleanupAtomicFile(filename string) error {
|
||
|
|
+ baseName := ".tmp-" + filepath.Base(filename)
|
||
|
|
+ dir := filepath.Dir(filename)
|
||
|
|
+ fs, err := ioutil.ReadDir(dir)
|
||
|
|
+ if err != nil {
|
||
|
|
+ logrus.Errorf("open directory(%s) failed: %s", dir, err)
|
||
|
|
+ return err
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for _, f := range fs {
|
||
|
|
+ if strings.Contains(f.Name(), baseName) {
|
||
|
|
+ logrus.Warnf("Remove temporary file: %s", filepath.Join(dir, f.Name()))
|
||
|
|
+ os.RemoveAll(filepath.Join(dir, f.Name()))
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ return nil
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
// AtomicWriteFile atomically writes data to a file named by filename.
|
||
|
|
func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
|
||
|
|
f, err := NewAtomicFileWriter(filename, perm)
|
||
|
|
diff --git a/components/engine/reference/store.go b/components/engine/reference/store.go
|
||
|
|
index b01051bf58..e54f772b5e 100644
|
||
|
|
--- a/components/engine/reference/store.go
|
||
|
|
+++ b/components/engine/reference/store.go
|
||
|
|
@@ -81,6 +81,7 @@ func NewReferenceStore(jsonPath string) (Store, error) {
|
||
|
|
Repositories: make(map[string]repository),
|
||
|
|
referencesByIDCache: make(map[digest.Digest]map[string]reference.Named),
|
||
|
|
}
|
||
|
|
+ ioutils.CleanupAtomicFile(abspath)
|
||
|
|
// Load the json file if it exists, otherwise create it.
|
||
|
|
if err := store.reload(); os.IsNotExist(err) {
|
||
|
|
if err := store.save(); err != nil {
|
||
|
|
--
|
||
|
|
2.17.1
|
||
|
|
|