Improve the garbage collection tests.
This commit is contained in:
parent
584a5a7ddd
commit
cf83c9a16a
2 changed files with 147 additions and 172 deletions
|
@ -44,6 +44,12 @@ def get_repository(namespace_name, repository_name):
|
|||
|
||||
|
||||
def purge_repository(namespace_name, repository_name):
|
||||
""" Completely delete all traces of the repository. Will return True upon
|
||||
complete success, and False upon partial or total failure. Garbage
|
||||
collection is incremental and repeatable, so this return value does
|
||||
not need to be checked or responded to.
|
||||
"""
|
||||
|
||||
repo = _basequery.get_existing_repository(namespace_name, repository_name)
|
||||
|
||||
# Delete all tags to allow gc to reclaim storage
|
||||
|
@ -57,12 +63,18 @@ def purge_repository(namespace_name, repository_name):
|
|||
unreferenced_candidates = set(img[0] for img in unreferenced_image_q.tuples())
|
||||
|
||||
# Gc to remove the images and storage
|
||||
garbage_collect_repo(repo, previously_referenced | unreferenced_candidates)
|
||||
all_repo_images = previously_referenced | unreferenced_candidates
|
||||
successful_gc = garbage_collect_repo(repo, all_repo_images)
|
||||
|
||||
if not successful_gc:
|
||||
return False
|
||||
|
||||
# Delete the rest of the repository metadata
|
||||
fetched = _basequery.get_existing_repository(namespace_name, repository_name)
|
||||
fetched.delete_instance(recursive=True, delete_nullable=False)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@ttl_cache(maxsize=1, ttl=600)
|
||||
def _get_gc_expiration_policies():
|
||||
|
@ -112,6 +124,13 @@ def find_repository_with_garbage(limit_to_gc_policy_s):
|
|||
|
||||
|
||||
def garbage_collect_repo(repo, extra_candidate_set=None):
|
||||
""" Garbage collect the specified repository object. This will remove all
|
||||
images, derived images, and other associated metadata, for images which
|
||||
are no longer referenced by a tag or another image which is itself
|
||||
tagged. Returns True if garbage collection was completed without error
|
||||
and False otherwise. Retries are safe and work incrementally, so this
|
||||
return value does not need to be checked or handled.
|
||||
"""
|
||||
logger.debug('Garbage collecting repository %s', repo.id)
|
||||
|
||||
storage_id_whitelist = set()
|
||||
|
@ -122,7 +141,7 @@ def garbage_collect_repo(repo, extra_candidate_set=None):
|
|||
|
||||
if not len(candidate_orphan_image_set):
|
||||
logger.debug('No candidate images for GC for repo: %s', repo.id)
|
||||
return
|
||||
return True
|
||||
|
||||
candidates_orphans = list(candidate_orphan_image_set)
|
||||
|
||||
|
@ -190,18 +209,20 @@ def garbage_collect_repo(repo, extra_candidate_set=None):
|
|||
.execute())
|
||||
except IntegrityError:
|
||||
logger.info('Could not GC derived images %s; will try again soon', to_remove)
|
||||
return
|
||||
return False
|
||||
|
||||
try:
|
||||
Image.delete().where(Image.id << to_remove).execute()
|
||||
except IntegrityError:
|
||||
logger.info('Could not GC images %s; will try again soon', to_remove)
|
||||
return
|
||||
return False
|
||||
|
||||
if len(to_remove) > 0:
|
||||
logger.info('Garbage collecting storage for images: %s', to_remove)
|
||||
storage.garbage_collect_storage(storage_id_whitelist)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def star_repository(user, repository):
|
||||
""" Stars a repository. """
|
||||
|
|
Reference in a new issue