Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/content/about/garbage-collection.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ This type of garbage collection is known as stop-the-world garbage collection.

Garbage collection can be run as follows

`bin/registry garbage-collect [--dry-run] /path/to/config.yml`
`bin/registry garbage-collect [--dry-run] [--delete-untagged] [--quiet] /path/to/config.yml`

The garbage-collect command accepts a `--dry-run` parameter, which prints the progress
of the mark and sweep phases without removing any data. Running with a log level of `info`
Expand Down Expand Up @@ -122,3 +122,8 @@ blob eligible for deletion: sha256:87192bdbe00f8f2a62527f36bb4c7c7f4eaf9307e4b87
blob eligible for deletion: sha256:b549a9959a664038fc35c155a95742cf12297672ca0ae35735ec027d55bf4e97
blob eligible for deletion: sha256:f251d679a7c61455f06d793e43c06786d7766c88b8c24edf242b2c08e3c3f599
```

The `--delete-untagged` option can be used to delete manifests that are not currently referenced by a tag.

The `--quiet` option suppresses any output from being printed.

3 changes: 3 additions & 0 deletions registry/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func init() {
RootCmd.AddCommand(GCCmd)
GCCmd.Flags().BoolVarP(&dryRun, "dry-run", "d", false, "do everything except remove the blobs")
GCCmd.Flags().BoolVarP(&removeUntagged, "delete-untagged", "m", false, "delete manifests that are not currently referenced via tag")
GCCmd.Flags().BoolVarP(&quiet, "quiet", "q", false, "silence output")
RootCmd.Flags().BoolVarP(&showVersion, "version", "v", false, "show the version and exit")
}

Expand All @@ -39,6 +40,7 @@ var RootCmd = &cobra.Command{
var (
dryRun bool
removeUntagged bool
quiet bool
)

// GCCmd is the cobra command that corresponds to the garbage-collect subcommand
Expand Down Expand Up @@ -77,6 +79,7 @@ var GCCmd = &cobra.Command{
err = storage.MarkAndSweep(ctx, driver, registry, storage.GCOpts{
DryRun: dryRun,
RemoveUntagged: removeUntagged,
Quiet: quiet,
})
if err != nil {
fmt.Fprintf(os.Stderr, "failed to garbage collect: %v", err)
Expand Down
38 changes: 28 additions & 10 deletions registry/storage/garbagecollect.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func emit(format string, a ...interface{}) {
type GCOpts struct {
DryRun bool
RemoveUntagged bool
Quiet bool
}

// ManifestDel contains manifest structure which will be deleted
Expand All @@ -41,7 +42,9 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
deleteLayerSet := make(map[string][]digest.Digest)
manifestArr := make([]ManifestDel, 0)
err := repositoryEnumerator.Enumerate(ctx, func(repoName string) error {
emit(repoName)
if !opts.Quiet {
emit(repoName)
}

var err error
named, err := reference.WithName(repoName)
Expand Down Expand Up @@ -77,7 +80,9 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
allTags, err := repository.Tags(ctx).All(ctx)
if err != nil {
if _, ok := err.(distribution.ErrRepositoryUnknown); ok {
emit("manifest tags path of repository %s does not exist", repoName)
if !opts.Quiet {
emit("manifest tags path of repository %s does not exist", repoName)
}
return nil
}
return fmt.Errorf("failed to retrieve tags %v", err)
Expand All @@ -87,14 +92,18 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
}
}
// Mark the manifest's blob
emit("%s: marking manifest %s ", repoName, dgst)
if !opts.Quiet {
emit("%s: marking manifest %s ", repoName, dgst)
}
markSet[dgst] = struct{}{}

return markManifestReferences(dgst, manifestService, ctx, func(d digest.Digest) bool {
_, marked := markSet[d]
if !marked {
markSet[d] = struct{}{}
emit("%s: marking blob %s", repoName, d)
if !opts.Quiet {
emit("%s: marking blob %s", repoName, d)
}
}
return marked
})
Expand Down Expand Up @@ -132,7 +141,7 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
return fmt.Errorf("failed to mark: %v", err)
}

manifestArr = unmarkReferencedManifest(manifestArr, markSet)
manifestArr = unmarkReferencedManifest(manifestArr, markSet, opts.Quiet)

// sweep
vacuum := NewVacuum(ctx, storageDriver)
Expand All @@ -156,9 +165,13 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
if err != nil {
return fmt.Errorf("error enumerating blobs: %v", err)
}
emit("\n%d blobs marked, %d blobs and %d manifests eligible for deletion", len(markSet), len(deleteSet), len(manifestArr))
if !opts.Quiet {
emit("\n%d blobs marked, %d blobs and %d manifests eligible for deletion", len(markSet), len(deleteSet), len(manifestArr))
}
for dgst := range deleteSet {
emit("blob eligible for deletion: %s", dgst)
if !opts.Quiet {
emit("blob eligible for deletion: %s", dgst)
}
if opts.DryRun {
continue
}
Expand All @@ -170,7 +183,9 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis

for repo, dgsts := range deleteLayerSet {
for _, dgst := range dgsts {
emit("%s: layer link eligible for deletion: %s", repo, dgst)
if !opts.Quiet {
emit("%s: layer link eligible for deletion: %s", repo, dgst)
}
if opts.DryRun {
continue
}
Expand All @@ -185,11 +200,14 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
}

// unmarkReferencedManifest filters out manifest present in markSet
func unmarkReferencedManifest(manifestArr []ManifestDel, markSet map[digest.Digest]struct{}) []ManifestDel {
func unmarkReferencedManifest(manifestArr []ManifestDel, markSet map[digest.Digest]struct{}, quietOutput bool) []ManifestDel {
filtered := make([]ManifestDel, 0)
for _, obj := range manifestArr {
if _, ok := markSet[obj.Digest]; !ok {
emit("manifest eligible for deletion: %s", obj)
if !quietOutput {
emit("manifest eligible for deletion: %s", obj)
}

filtered = append(filtered, obj)
}
}
Expand Down
Loading