mirror of
https://github.com/distribution/distribution.git
synced 2025-07-19 09:46:41 +00:00
registry/storage: add option to quiet GC output.
Consumers might not want GC output to be displayed (e.g, if you have your own logging system). Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com>
This commit is contained in:
parent
7271d882c0
commit
a032989bf9
@ -18,6 +18,7 @@ func init() {
|
|||||||
RootCmd.AddCommand(GCCmd)
|
RootCmd.AddCommand(GCCmd)
|
||||||
GCCmd.Flags().BoolVarP(&dryRun, "dry-run", "d", false, "do everything except remove the blobs")
|
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(&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")
|
RootCmd.Flags().BoolVarP(&showVersion, "version", "v", false, "show the version and exit")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ var RootCmd = &cobra.Command{
|
|||||||
var (
|
var (
|
||||||
dryRun bool
|
dryRun bool
|
||||||
removeUntagged bool
|
removeUntagged bool
|
||||||
|
quiet bool
|
||||||
)
|
)
|
||||||
|
|
||||||
// GCCmd is the cobra command that corresponds to the garbage-collect subcommand
|
// GCCmd is the cobra command that corresponds to the garbage-collect subcommand
|
||||||
@ -77,6 +79,7 @@ var GCCmd = &cobra.Command{
|
|||||||
err = storage.MarkAndSweep(ctx, driver, registry, storage.GCOpts{
|
err = storage.MarkAndSweep(ctx, driver, registry, storage.GCOpts{
|
||||||
DryRun: dryRun,
|
DryRun: dryRun,
|
||||||
RemoveUntagged: removeUntagged,
|
RemoveUntagged: removeUntagged,
|
||||||
|
Quiet: quiet,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "failed to garbage collect: %v", err)
|
fmt.Fprintf(os.Stderr, "failed to garbage collect: %v", err)
|
||||||
|
@ -20,6 +20,7 @@ func emit(format string, a ...interface{}) {
|
|||||||
type GCOpts struct {
|
type GCOpts struct {
|
||||||
DryRun bool
|
DryRun bool
|
||||||
RemoveUntagged bool
|
RemoveUntagged bool
|
||||||
|
Quiet bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ManifestDel contains manifest structure which will be deleted
|
// ManifestDel contains manifest structure which will be deleted
|
||||||
@ -41,7 +42,9 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
|
|||||||
deleteLayerSet := make(map[string][]digest.Digest)
|
deleteLayerSet := make(map[string][]digest.Digest)
|
||||||
manifestArr := make([]ManifestDel, 0)
|
manifestArr := make([]ManifestDel, 0)
|
||||||
err := repositoryEnumerator.Enumerate(ctx, func(repoName string) error {
|
err := repositoryEnumerator.Enumerate(ctx, func(repoName string) error {
|
||||||
emit(repoName)
|
if !opts.Quiet {
|
||||||
|
emit(repoName)
|
||||||
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
named, err := reference.WithName(repoName)
|
named, err := reference.WithName(repoName)
|
||||||
@ -77,7 +80,9 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
|
|||||||
allTags, err := repository.Tags(ctx).All(ctx)
|
allTags, err := repository.Tags(ctx).All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(distribution.ErrRepositoryUnknown); ok {
|
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 nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("failed to retrieve tags %v", err)
|
return fmt.Errorf("failed to retrieve tags %v", err)
|
||||||
@ -87,14 +92,18 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Mark the manifest's blob
|
// 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{}{}
|
markSet[dgst] = struct{}{}
|
||||||
|
|
||||||
return markManifestReferences(dgst, manifestService, ctx, func(d digest.Digest) bool {
|
return markManifestReferences(dgst, manifestService, ctx, func(d digest.Digest) bool {
|
||||||
_, marked := markSet[d]
|
_, marked := markSet[d]
|
||||||
if !marked {
|
if !marked {
|
||||||
markSet[d] = struct{}{}
|
markSet[d] = struct{}{}
|
||||||
emit("%s: marking blob %s", repoName, d)
|
if !opts.Quiet {
|
||||||
|
emit("%s: marking blob %s", repoName, d)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return marked
|
return marked
|
||||||
})
|
})
|
||||||
@ -132,7 +141,7 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
|
|||||||
return fmt.Errorf("failed to mark: %v", err)
|
return fmt.Errorf("failed to mark: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
manifestArr = unmarkReferencedManifest(manifestArr, markSet)
|
manifestArr = unmarkReferencedManifest(manifestArr, markSet, opts.Quiet)
|
||||||
|
|
||||||
// sweep
|
// sweep
|
||||||
vacuum := NewVacuum(ctx, storageDriver)
|
vacuum := NewVacuum(ctx, storageDriver)
|
||||||
@ -156,9 +165,13 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error enumerating blobs: %v", err)
|
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 {
|
for dgst := range deleteSet {
|
||||||
emit("blob eligible for deletion: %s", dgst)
|
if !opts.Quiet {
|
||||||
|
emit("blob eligible for deletion: %s", dgst)
|
||||||
|
}
|
||||||
if opts.DryRun {
|
if opts.DryRun {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -170,7 +183,9 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
|
|||||||
|
|
||||||
for repo, dgsts := range deleteLayerSet {
|
for repo, dgsts := range deleteLayerSet {
|
||||||
for _, dgst := range dgsts {
|
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 {
|
if opts.DryRun {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -185,11 +200,14 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
|
|||||||
}
|
}
|
||||||
|
|
||||||
// unmarkReferencedManifest filters out manifest present in markSet
|
// 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)
|
filtered := make([]ManifestDel, 0)
|
||||||
for _, obj := range manifestArr {
|
for _, obj := range manifestArr {
|
||||||
if _, ok := markSet[obj.Digest]; !ok {
|
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)
|
filtered = append(filtered, obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user