def find_repository_with_garbage(limit_to_gc_policy_s): expiration_timestamp = get_epoch_timestamp() - limit_to_gc_policy_s try: candidates = (RepositoryTag.select( RepositoryTag.repository).join(Repository).join( Namespace, on=(Repository.namespace_user == Namespace.id)).where( ~(RepositoryTag.lifetime_end_ts >> None), (RepositoryTag.lifetime_end_ts <= expiration_timestamp), (Namespace.removed_tag_expiration_s == limit_to_gc_policy_s), ).limit(500).distinct().alias("candidates")) found = (RepositoryTag.select( candidates.c.repository_id).from_(candidates).order_by( db_random_func()).get()) if found is None: return return Repository.get(Repository.id == found.repository_id) except RepositoryTag.DoesNotExist: return None except Repository.DoesNotExist: return None
def create_temporary_hidden_tag(repo, image_obj, expiration_s): """ Create a tag with a defined timeline, that will not appear in the UI or CLI. Returns the name of the temporary tag or None on error. """ now_ts = get_epoch_timestamp() expire_ts = now_ts + expiration_s tag_name = str(uuid4()) # Ensure the repository is not marked for deletion. with db_transaction(): current = Repository.get(id=repo) if current.state == RepositoryState.MARKED_FOR_DELETION: return None RepositoryTag.create( repository=repo, image=image_obj, name=tag_name, lifetime_start_ts=now_ts, lifetime_end_ts=expire_ts, hidden=True, ) return tag_name
def lookup_unrecoverable_tags(repo): """ Returns the tags in a repository that are expired and past their time machine recovery period. """ expired_clause = get_epoch_timestamp() - Namespace.removed_tag_expiration_s return (RepositoryTag.select().join(Repository).join( Namespace, on=(Repository.namespace_user == Namespace.id)).where( RepositoryTag.repository == repo).where( ~(RepositoryTag.lifetime_end_ts >> None), RepositoryTag.lifetime_end_ts <= expired_clause, ))
def create_temporary_hidden_tag(repo, image_obj, expiration_s): """ Create a tag with a defined timeline, that will not appear in the UI or CLI. Returns the name of the temporary tag. """ now_ts = get_epoch_timestamp() expire_ts = now_ts + expiration_s tag_name = str(uuid4()) RepositoryTag.create( repository=repo, image=image_obj, name=tag_name, lifetime_start_ts=now_ts, lifetime_end_ts=expire_ts, hidden=True, ) return tag_name
def delete_app_release(repo, tag_name, media_type, models_ref): """Terminate a Tag/media-type couple It find the corresponding tag/manifest and remove from the manifestlistmanifest the manifest 1. it terminates the current tag (in all-cases) 2. if the new manifestlist is not empty, it creates a new tag for it """ ManifestListManifest = models_ref.ManifestListManifest manifestlistmanifest_set_name = models_ref.manifestlistmanifest_set_name media_type_id = ManifestListManifest.media_type.get_id(manifest_media_type(media_type)) with db_transaction(): tag = tag_model.get_tag(repo, tag_name, models_ref) manifest_list = tag.manifest_list list_json = manifest_list.manifest_list_json mlm_query = ManifestListManifest.select().where( ManifestListManifest.manifest_list == tag.manifest_list ) list_manifest_ids = sorted([mlm.manifest_id for mlm in mlm_query]) manifestlistmanifest = ( getattr(tag.manifest_list, manifestlistmanifest_set_name) .where(ManifestListManifest.media_type == media_type_id) .get() ) index = list_manifest_ids.index(manifestlistmanifest.manifest_id) list_manifest_ids.pop(index) list_json.pop(index) if not list_json: tag.lifetime_end = get_epoch_timestamp() tag.save() else: manifestlist = manifest_list_model.get_or_create_manifest_list( list_json, LIST_MEDIA_TYPE, SCHEMA_VERSION, models_ref ) manifest_list_model.create_manifestlistmanifest( manifestlist, list_manifest_ids, list_json, models_ref ) tag = tag_model.create_or_update_tag( repo, tag_name, models_ref, manifest_list=manifestlist, tag_kind="release" ) return tag
def _tag_alive(query, now_ts=None): if now_ts is None: now_ts = get_epoch_timestamp() return query.where((RepositoryTag.lifetime_end_ts >> None) | (RepositoryTag.lifetime_end_ts > now_ts))
def get_expired_tag_in_repo(repo, tag_name): return (RepositoryTag.select().where( RepositoryTag.name == tag_name, RepositoryTag.repository == repo).where(~(RepositoryTag.lifetime_end_ts >> None)).where( RepositoryTag.lifetime_end_ts <= get_epoch_timestamp()).get())