def _is_storage_orphaned(candidate_id): """ Returns the whether the given candidate storage ID is orphaned. Must be executed under a transaction. """ with ensure_under_transaction(): try: ManifestBlob.get(blob=candidate_id) return False except ManifestBlob.DoesNotExist: pass try: Image.get(storage=candidate_id) return False except Image.DoesNotExist: pass try: UploadedBlob.get(blob=candidate_id) return False except UploadedBlob.DoesNotExist: pass return True
def placements_to_filtered_paths_set(placements_list): """ Returns the list of paths to remove from storage, filtered from the given placements query by removing any CAS paths that are still referenced by storage(s) in the database. """ if not placements_list: return set() with ensure_under_transaction(): # Find the content checksums not referenced by other storages. Any that are, we cannot # remove. content_checksums = set([ placement.storage.content_checksum for placement in placements_list if placement.storage.cas_path ]) unreferenced_checksums = set() if content_checksums: # Check the current image storage. query = ImageStorage.select( ImageStorage.content_checksum ).where( ImageStorage.content_checksum << list(content_checksums)) is_referenced_checksums = set([ image_storage.content_checksum for image_storage in query ]) if is_referenced_checksums: logger.warning( "GC attempted to remove CAS checksums %s, which are still IS referenced", is_referenced_checksums, ) # Check the ApprBlob table as well. query = ApprBlob.select(ApprBlob.digest).where( ApprBlob.digest << list(content_checksums)) appr_blob_referenced_checksums = set( [blob.digest for blob in query]) if appr_blob_referenced_checksums: logger.warning( "GC attempted to remove CAS checksums %s, which are ApprBlob referenced", appr_blob_referenced_checksums, ) unreferenced_checksums = (content_checksums - appr_blob_referenced_checksums - is_referenced_checksums) # Return all placements for all image storages found not at a CAS path or with a content # checksum that is referenced. return { ( get_image_location_for_id(placement.location_id).name, get_layer_path(placement.storage), placement.storage.content_checksum, ) for placement in placements_list if not placement.storage.cas_path or placement.storage.content_checksum in unreferenced_checksums }