Add dry-run option
This will help us validate and debug the prune command. Change-Id: I54ba30e1963593762e1e1435bc7e67e7eb637d3e
This commit is contained in:
parent
404b903c77
commit
66bf00a416
@ -1,5 +1,5 @@
|
||||
# Copyright 2019 Red Hat, Inc.
|
||||
# Copyright 2021 Acme Gating, LLC
|
||||
# Copyright 2021, 2024 Acme Gating, LLC
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -553,8 +553,8 @@ class RegistryServer:
|
||||
# same host/port settings.
|
||||
cherrypy.server.httpserver = None
|
||||
|
||||
def prune(self):
|
||||
self.store.prune()
|
||||
def prune(self, dry_run):
|
||||
self.store.prune(dry_run)
|
||||
|
||||
|
||||
def main():
|
||||
@ -566,6 +566,9 @@ def main():
|
||||
parser.add_argument('-d', dest='debug',
|
||||
help='Debug log level',
|
||||
action='store_true')
|
||||
parser.add_argument('--dry-run', dest='dry_run',
|
||||
help='Do not actually delete anything when pruning',
|
||||
action='store_true')
|
||||
parser.add_argument('command',
|
||||
nargs='?',
|
||||
help='Command: serve, prune',
|
||||
@ -591,7 +594,7 @@ def main():
|
||||
s.start()
|
||||
cherrypy.engine.block()
|
||||
elif args.command == 'prune':
|
||||
s.prune()
|
||||
s.prune(args.dry_run)
|
||||
else:
|
||||
print("Unknown command: %s", args.command)
|
||||
sys.exit(1)
|
||||
|
@ -258,7 +258,7 @@ class Storage:
|
||||
path = os.path.join(namespace, 'repos', repo, 'manifests')
|
||||
return self.backend.list_objects(path)
|
||||
|
||||
def prune(self):
|
||||
def prune(self, dry_run):
|
||||
"""Prune the registry
|
||||
|
||||
Prune all namespaces in the registry according to configured
|
||||
@ -273,13 +273,14 @@ class Storage:
|
||||
for namespace in self.backend.list_objects(''):
|
||||
uploadpath = os.path.join(namespace.path, 'uploads/')
|
||||
for upload in self.backend.list_objects(uploadpath):
|
||||
self._prune(upload, upload_target)
|
||||
self._prune(upload, upload_target, dry_run)
|
||||
if not manifest_target:
|
||||
continue
|
||||
repopath = os.path.join(namespace.path, 'repos/')
|
||||
kept_manifests = []
|
||||
for repo in self.backend.list_objects(repopath):
|
||||
kept_manifests.extend(self._prune(repo, manifest_target))
|
||||
kept_manifests.extend(
|
||||
self._prune(repo, manifest_target, dry_run))
|
||||
# mark/sweep manifest blobs
|
||||
layers = set()
|
||||
for manifest in kept_manifests:
|
||||
@ -290,7 +291,7 @@ class Storage:
|
||||
blobpath = os.path.join(namespace.path, 'blobs/')
|
||||
for blob in self.backend.list_objects(blobpath):
|
||||
if blob.name not in layers:
|
||||
self._prune(blob, upload_target)
|
||||
self._prune(blob, upload_target, dry_run)
|
||||
|
||||
def _get_layers_from_manifest(self, namespace, path):
|
||||
self.log.debug('Get layers %s', path)
|
||||
@ -310,14 +311,15 @@ class Storage:
|
||||
layers.append(layer['digest'])
|
||||
return layers
|
||||
|
||||
def _prune(self, root_obj, target):
|
||||
def _prune(self, root_obj, target, dry_run):
|
||||
kept = []
|
||||
if root_obj.isdir:
|
||||
for obj in self.backend.list_objects(root_obj.path):
|
||||
kept.extend(self._prune(obj, target))
|
||||
kept.extend(self._prune(obj, target, dry_run))
|
||||
if not kept and root_obj.ctime < target:
|
||||
self.log.debug('Prune %s', root_obj.path)
|
||||
self.backend.delete_object(root_obj.path)
|
||||
if not dry_run:
|
||||
self.backend.delete_object(root_obj.path)
|
||||
else:
|
||||
self.log.debug('Keep %s', root_obj.path)
|
||||
kept.append(root_obj)
|
||||
|
Loading…
Reference in New Issue
Block a user