Skip to content

Commit 6397ad4

Browse files
committed
Prototype temporary directory
Signed-off-by: Jan Rodák <[email protected]>
1 parent 78f4258 commit 6397ad4

File tree

6 files changed

+434
-11
lines changed

6 files changed

+434
-11
lines changed

drivers/overlay/overlay.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/containers/storage/pkg/mount"
3535
"github.com/containers/storage/pkg/parsers"
3636
"github.com/containers/storage/pkg/system"
37+
"github.com/containers/storage/pkg/tempdir"
3738
"github.com/containers/storage/pkg/unshare"
3839
units "github.com/docker/go-units"
3940
digest "github.com/opencontainers/go-digest"
@@ -136,6 +137,9 @@ type Driver struct {
136137
stagingDirsLocks map[string]*lockfile.LockFile
137138

138139
supportsIDMappedMounts *bool
140+
141+
// This fled is read-only. Should be save to access without any locking.
142+
tempDirectory *tempdir.TempDir
139143
}
140144

141145
type additionalLayerStore struct {
@@ -458,6 +462,12 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
458462
return nil, fmt.Errorf("storage option overlay.size and overlay.inodes only supported for backingFS XFS. Found %v", backingFs)
459463
}
460464

465+
t, err := tempdir.NewTempDir(filepath.Join(d.homeDirForImageStore(), stagingDir))
466+
if err != nil {
467+
return nil, err
468+
}
469+
d.tempDirectory = t
470+
461471
logrus.Debugf("backingFs=%s, projectQuotaSupported=%v, useNativeDiff=%v, usingMetacopy=%v", backingFs, projectQuotaSupported, !d.useNaiveDiff(), d.usingMetacopy)
462472

463473
return d, nil
@@ -862,6 +872,9 @@ func (d *Driver) Metadata(id string) (map[string]string, error) {
862872
// the storage is being shutdown. The only state created by the driver
863873
// is the bind mount on the home directory.
864874
func (d *Driver) Cleanup() error {
875+
if err := d.tempDirectory.Cleanup(); err != nil {
876+
return err
877+
}
865878
anyPresent := d.pruneStagingDirectories()
866879
if anyPresent {
867880
return nil
@@ -1313,16 +1326,17 @@ func (d *Driver) Remove(id string) error {
13131326
dir := d.dir(id)
13141327
lid, err := os.ReadFile(path.Join(dir, "link"))
13151328
if err == nil {
1316-
if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil {
1317-
logrus.Debugf("Failed to remove link: %v", err)
1329+
if err := d.tempDirectory.Add(path.Join(d.home, linkDir, string(lid))); err != nil {
1330+
logrus.Debugf("Failed to Add to stage Directory link: %v", err)
13181331
}
13191332
}
13201333

13211334
d.releaseAdditionalLayerByID(id)
13221335

1323-
if err := system.EnsureRemoveAll(dir); err != nil && !os.IsNotExist(err) {
1324-
return err
1336+
if err := d.tempDirectory.Add(dir); err != nil {
1337+
return fmt.Errorf("failed to add to stage directory: %w", err)
13251338
}
1339+
13261340
if d.quotaCtl != nil {
13271341
d.quotaCtl.ClearQuota(dir)
13281342
if d.imageStore != "" {
@@ -1358,8 +1372,8 @@ func (d *Driver) recreateSymlinks() error {
13581372
// Check that for each layer, there's a link in "l" with the name in
13591373
// the layer's "link" file that points to the layer's "diff" directory.
13601374
for _, dir := range dirs {
1361-
// Skip over the linkDir and anything that is not a directory
1362-
if dir.Name() == linkDir || !dir.IsDir() {
1375+
// Skip over the linkDir and anything that is not a directory or tempDir
1376+
if dir.Name() == linkDir || !dir.IsDir() || dir.Name() == stagingDir { // Note for review: Not sure if skipping stagingDir is correct
13631377
continue
13641378
}
13651379
// Read the "link" file under each layer to get the name of the symlink

drivers/vfs/driver.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/containers/storage/pkg/idtools"
1818
"github.com/containers/storage/pkg/parsers"
1919
"github.com/containers/storage/pkg/system"
20+
"github.com/containers/storage/pkg/tempdir"
2021
"github.com/opencontainers/selinux/go-selinux/label"
2122
"github.com/sirupsen/logrus"
2223
"github.com/vbatts/tar-split/tar/storage"
@@ -67,6 +68,12 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
6768
d.updater = graphdriver.NewNaiveLayerIDMapUpdater(d)
6869
d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, d.updater)
6970

71+
t, err := tempdir.NewTempDir(d.home)
72+
if err != nil {
73+
return nil, err
74+
}
75+
d.tempDirectory = t
76+
7077
return d, nil
7178
}
7279

@@ -82,6 +89,9 @@ type Driver struct {
8289
naiveDiff graphdriver.DiffDriver
8390
updater graphdriver.LayerIDMapUpdater
8491
imageStore string
92+
93+
// This fled is read-only. Should be save to access without any locking.
94+
tempDirectory *tempdir.TempDir
8595
}
8696

8797
func (d *Driver) String() string {
@@ -100,7 +110,8 @@ func (d *Driver) Metadata(id string) (map[string]string, error) {
100110

101111
// Cleanup is used to implement graphdriver.ProtoDriver. There is no cleanup required for this driver.
102112
func (d *Driver) Cleanup() error {
103-
return nil
113+
// TODO: UPDATE comment
114+
return d.tempDirectory.Cleanup()
104115
}
105116

106117
type fileGetNilCloser struct {
@@ -241,7 +252,7 @@ func (d *Driver) dir(id string) string {
241252

242253
// Remove deletes the content from the directory for a given id.
243254
func (d *Driver) Remove(id string) error {
244-
return system.EnsureRemoveAll(d.dir(id))
255+
return d.tempDirectory.Add(d.dir(id))
245256
}
246257

247258
// Get returns the directory for the given id.

layers.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/containers/storage/pkg/stringid"
2727
"github.com/containers/storage/pkg/system"
2828
"github.com/containers/storage/pkg/tarlog"
29+
"github.com/containers/storage/pkg/tempdir"
2930
"github.com/containers/storage/pkg/truncindex"
3031
"github.com/klauspost/pgzip"
3132
digest "github.com/opencontainers/go-digest"
@@ -345,6 +346,8 @@ type rwLayerStore interface {
345346

346347
// Dedup deduplicates layers in the store.
347348
dedup(drivers.DedupArgs) (drivers.DedupResult, error)
349+
350+
CleanupTemporaryDirectories() error
348351
}
349352

350353
type multipleLockFile struct {
@@ -435,6 +438,9 @@ type layerStore struct {
435438
// FIXME: This field is only set when constructing layerStore, but locking rules of the driver
436439
// interface itself are not documented here.
437440
driver drivers.Driver
441+
442+
// This fled is read-only. Should be save to access without any locking.
443+
tempDirectory *tempdir.TempDir
438444
}
439445

440446
func copyLayer(l *Layer) *Layer {
@@ -794,6 +800,12 @@ func (r *layerStore) load(lockedForWriting bool) (bool, error) {
794800
layers := []*Layer{}
795801
ids := make(map[string]*Layer)
796802

803+
if r.lockfile.IsReadWrite() {
804+
if err := tempdir.RecoverStaleDirs(r.tempDirectory.RootDir); err != nil {
805+
return false, err
806+
}
807+
}
808+
797809
for locationIndex := range numLayerLocationIndex {
798810
location := layerLocationFromIndex(locationIndex)
799811
rpath := r.jsonPath[locationIndex]
@@ -936,6 +948,11 @@ func (r *layerStore) load(lockedForWriting bool) (bool, error) {
936948
for _, layer := range layersToDelete {
937949
logrus.Warnf("Found incomplete layer %q, deleting it", layer.ID)
938950
err := r.deleteInternal(layer.ID)
951+
defer func() {
952+
if err := r.CleanupTemporaryDirectories(); err != nil {
953+
logrus.Errorf("Error cleaning up temporary directories: %v", err)
954+
}
955+
}()
939956
if err != nil {
940957
// Don't return the error immediately, because deleteInternal does not saveLayers();
941958
// Even if deleting one incomplete layer fails, call saveLayers() so that other possible successfully
@@ -1164,7 +1181,8 @@ func (s *store) newLayerStore(rundir, layerdir, imagedir string, driver drivers.
11641181
byname: make(map[string]*Layer),
11651182
bymount: make(map[string]*Layer),
11661183

1167-
driver: driver,
1184+
driver: driver,
1185+
tempDirectory: s.tempDirectory,
11681186
}
11691187
if err := rlstore.startWritingWithReload(false); err != nil {
11701188
return nil, err
@@ -1919,7 +1937,17 @@ func layerHasIncompleteFlag(layer *Layer) bool {
19191937
return false
19201938
}
19211939

1940+
func (r *layerStore) CleanupTemporaryDirectories() error {
1941+
err := r.tempDirectory.Cleanup()
1942+
if errDriver := r.driver.Cleanup(); errDriver != nil {
1943+
return errors.Join(err, errDriver)
1944+
}
1945+
return err
1946+
}
1947+
19221948
// Requires startWriting.
1949+
// Caller MUST run CleanupTemporaryDirectories() after this. Ideally outside of
1950+
// the startWriting.
19231951
func (r *layerStore) deleteInternal(id string) error {
19241952
if !r.lockfile.IsReadWrite() {
19251953
return fmt.Errorf("not allowed to delete layers at %q: %w", r.layerdir, ErrStoreIsReadOnly)
@@ -1943,8 +1971,10 @@ func (r *layerStore) deleteInternal(id string) error {
19431971
if err := r.driver.Remove(id); err != nil && !errors.Is(err, os.ErrNotExist) {
19441972
return err
19451973
}
1946-
os.Remove(r.tspath(id))
1947-
os.RemoveAll(r.datadir(id))
1974+
_ = r.tempDirectory.Add(r.tspath(id))
1975+
// os.Remove(r.tspath(id))
1976+
_ = r.tempDirectory.Add(r.datadir(id))
1977+
// os.RemoveAll(r.datadir(id))
19481978
delete(r.byid, id)
19491979
for _, name := range layer.Names {
19501980
delete(r.byname, name)
@@ -1988,6 +2018,8 @@ func (r *layerStore) deleteInDigestMap(id string) {
19882018
}
19892019

19902020
// Requires startWriting.
2021+
// Caller MUST run CleanupTemporaryDirectories() after this. Ideally outside of
2022+
// the startWriting.
19912023
func (r *layerStore) Delete(id string) error {
19922024
layer, ok := r.lookup(id)
19932025
if !ok {

0 commit comments

Comments
 (0)