mirror of
https://github.com/project-zot/zot.git
synced 2026-06-15 20:07:55 +08:00
gc: add a policy to skip garbage collecting new blobs
We perform inline garbage collection of orphan blobs. However, the dist-spec poses a problem because blobs begin their life as orphan blobs and then a manifest is add which refers to these blobs. We use umoci's GC() to perform garbage collection and policy support has been added recently which can control whether a blob can be skipped for GC. In this patch, we use a time-based policy to skip blobs.
This commit is contained in:
+1
-1
@@ -33,7 +33,7 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
timeout = "short",
|
||||
timeout = "moderate",
|
||||
srcs = ["controller_test.go"],
|
||||
data = [
|
||||
"//:exported_testdata",
|
||||
|
||||
@@ -11,10 +11,12 @@ go_library(
|
||||
deps = [
|
||||
"//errors:go_default_library",
|
||||
"//pkg/log:go_default_library",
|
||||
"@com_github_apex_log//:go_default_library",
|
||||
"@com_github_gofrs_uuid//:go_default_library",
|
||||
"@com_github_opencontainers_go_digest//:go_default_library",
|
||||
"@com_github_opencontainers_image_spec//specs-go/v1:go_default_library",
|
||||
"@com_github_opencontainers_umoci//:go_default_library",
|
||||
"@com_github_opencontainers_umoci//oci/casext:go_default_library",
|
||||
"@com_github_rs_zerolog//:go_default_library",
|
||||
"@io_etcd_go_bbolt//:go_default_library",
|
||||
],
|
||||
|
||||
+39
-2
@@ -11,13 +11,16 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/anuvu/zot/errors"
|
||||
zlog "github.com/anuvu/zot/pkg/log"
|
||||
apexlog "github.com/apex/log"
|
||||
guuid "github.com/gofrs/uuid"
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/opencontainers/umoci"
|
||||
"github.com/opencontainers/umoci/oci/casext"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
@@ -25,6 +28,7 @@ const (
|
||||
// BlobUploadDir defines the upload directory for blob uploads.
|
||||
BlobUploadDir = ".uploads"
|
||||
schemaVersion = 2
|
||||
gcDelay = 1 * time.Hour
|
||||
)
|
||||
|
||||
// BlobUpload models and upload request.
|
||||
@@ -66,6 +70,20 @@ func NewImageStore(rootDir string, gc bool, dedupe bool, log zlog.Logger) *Image
|
||||
is.cache = NewCache(rootDir, "cache", log)
|
||||
}
|
||||
|
||||
if gc {
|
||||
// we use umoci GC to perform garbage-collection, but it uses its own logger
|
||||
// - so capture those logs, could be useful
|
||||
apexlog.SetLevel(apexlog.DebugLevel)
|
||||
apexlog.SetHandler(apexlog.HandlerFunc(func(entry *apexlog.Entry) error {
|
||||
e := log.Debug()
|
||||
for k, v := range entry.Fields {
|
||||
e = e.Interface(k, v)
|
||||
}
|
||||
e.Msg(entry.Message)
|
||||
return nil
|
||||
}))
|
||||
}
|
||||
|
||||
return is
|
||||
}
|
||||
|
||||
@@ -492,7 +510,7 @@ func (is *ImageStore) PutImageManifest(repo string, reference string, mediaType
|
||||
}
|
||||
defer oci.Close()
|
||||
|
||||
if err := oci.GC(context.Background()); err != nil {
|
||||
if err := oci.GC(context.Background(), ifOlderThan(is, repo, gcDelay)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
@@ -568,7 +586,7 @@ func (is *ImageStore) DeleteImageManifest(repo string, reference string) error {
|
||||
}
|
||||
defer oci.Close()
|
||||
|
||||
if err := oci.GC(context.Background()); err != nil {
|
||||
if err := oci.GC(context.Background(), ifOlderThan(is, repo, gcDelay)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -1025,3 +1043,22 @@ func ensureDir(dir string, log zerolog.Logger) {
|
||||
log.Panic().Err(err).Str("dir", dir).Msg("unable to create dir")
|
||||
}
|
||||
}
|
||||
|
||||
func ifOlderThan(is *ImageStore, repo string, delay time.Duration) casext.GCPolicy {
|
||||
return func(ctx context.Context, digest godigest.Digest) (bool, error) {
|
||||
blobPath := is.BlobPath(repo, digest)
|
||||
fi, err := os.Stat(blobPath)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if fi.ModTime().Add(delay).After(time.Now()) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
is.log.Info().Str("digest", digest.String()).Str("blobPath", blobPath).Msg("perform GC on blob")
|
||||
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user