def test_lookup_unrecoverable_tags(initialized_db): # Ensure no existing tags are found. for repo in Repository.select(): assert not list(lookup_unrecoverable_tags(repo)) # Mark a tag as outside the expiration window and ensure it is found. repo = get_repository("devtable", "history") results, _ = list_repository_tag_history(repo, 1, 100, specific_tag_name="latest") assert len(results) == 2 results[1].lifetime_end_ms = 1 results[1].save() # Ensure the tag is now found. found = list(lookup_unrecoverable_tags(repo)) assert found assert len(found) == 1 assert found[0] == results[1] # Mark the tag as expiring in the future and ensure it is no longer found. results[1].lifetime_end_ms = get_epoch_timestamp_ms() + 1000000 results[1].save() found = list(lookup_unrecoverable_tags(repo)) assert not found
def garbage_collect_repo(repo): """ Performs garbage collection over the contents of a repository. """ # Purge expired tags. had_changes = False for tags in _chunk_iterate_for_deletion(oci_tag.lookup_unrecoverable_tags(repo)): logger.debug('Found %s tags to GC under repository %s', len(tags), repo) context = _GarbageCollectorContext(repo) for tag in tags: logger.debug('Deleting tag %s under repository %s', tag, repo) assert tag.repository_id == repo.id assert tag.lifetime_end_ms is not None _purge_oci_tag(tag, context) _run_garbage_collection(context) had_changes = True for tags in _chunk_iterate_for_deletion(pre_oci_tag.lookup_unrecoverable_tags(repo)): logger.debug('Found %s tags to GC under repository %s', len(tags), repo) context = _GarbageCollectorContext(repo) for tag in tags: logger.debug('Deleting tag %s under repository %s', tag, repo) assert tag.repository_id == repo.id assert tag.lifetime_end_ts is not None _purge_pre_oci_tag(tag, context) _run_garbage_collection(context) had_changes = True return had_changes
def garbage_collect_repo(repo): """ Performs garbage collection over the contents of a repository. """ # Purge expired tags. had_changes = False for tags in _chunk_iterate_for_deletion( oci_tag.lookup_unrecoverable_tags(repo)): logger.debug("Found %s tags to GC under repository %s", len(tags), repo) context = _GarbageCollectorContext(repo) for tag in tags: logger.debug("Deleting tag %s under repository %s", tag, repo) assert tag.repository_id == repo.id assert tag.lifetime_end_ms is not None _purge_oci_tag(tag, context) _run_garbage_collection(context) had_changes = True # TODO: Remove once we've removed the foreign key constraints from RepositoryTag and Image. for tags in _chunk_iterate_for_deletion( pre_oci_tag.lookup_unrecoverable_tags(repo)): logger.debug("Found %s tags to GC under repository %s", len(tags), repo) context = _GarbageCollectorContext(repo) for tag in tags: logger.debug("Deleting tag %s under repository %s", tag, repo) assert tag.repository_id == repo.id assert tag.lifetime_end_ts is not None _purge_pre_oci_tag(tag, context) _run_garbage_collection(context) had_changes = True # Purge expired uploaded blobs. for uploaded_blobs in _chunk_iterate_for_deletion( blob.lookup_expired_uploaded_blobs(repo)): logger.debug("Found %s uploaded blobs to GC under repository %s", len(uploaded_blobs), repo) context = _GarbageCollectorContext(repo) for uploaded_blob in uploaded_blobs: logger.debug("Deleting uploaded blob %s under repository %s", uploaded_blob, repo) assert uploaded_blob.repository_id == repo.id _purge_uploaded_blob(uploaded_blob, context) _run_garbage_collection(context) had_changes = True return had_changes