def rollback(mirror, since_ms): """ :param mirror: Mirror to perform rollback on :param start_time: Time mirror was started; all changes after will be undone :return: """ repository_ref = registry_model.lookup_repository( mirror.repository.namespace_user.username, mirror.repository.name) tags, has_more = registry_model.list_repository_tag_history( repository_ref, 1, 100, since_time_ms=since_ms) for tag in tags: logger.debug("Repo mirroring rollback tag '%s'" % tag) # If the tag has an end time, it was either deleted or moved. if tag.lifetime_end_ms: # If a future entry exists with a start time equal to the end time for this tag, # then the action was a move, rather than a delete and a create. newer_tag = filter( lambda t: tag != t and tag.name == t.name and tag. lifetime_end_ms and t.lifetime_start_ms == tag.lifetime_end_ms, tags, )[0] if newer_tag: logger.debug("Repo mirroring rollback revert tag '%s'" % tag) retarget_tag(tag.name, tag.manifest._db_id, is_reversion=True) else: logger.debug("Repo mirroring recreate tag '%s'" % tag) retarget_tag(tag.name, tag.manifest._db_id, is_reversion=True) # If the tag has a start time, it was created. elif tag.lifetime_start_ms: logger.debug("Repo mirroring rollback delete tag '%s'" % tag) delete_tag(mirror.repository, tag.name)
def test_retarget_tag(initialized_db): repo = get_repository("devtable", "history") results, _ = list_repository_tag_history(repo, 1, 100, specific_tag_name="latest") assert len(results) == 2 assert results[0].lifetime_end_ms is None assert results[1].lifetime_end_ms is not None # Revert back to the original manifest. created = retarget_tag("latest", results[0].manifest, is_reversion=True, now_ms=results[1].lifetime_end_ms + 10000) assert created.lifetime_end_ms is None assert created.reversion assert created.name == "latest" assert created.manifest == results[0].manifest # Verify in the history. results, _ = list_repository_tag_history(repo, 1, 100, specific_tag_name="latest") assert len(results) == 3 assert results[0].lifetime_end_ms is None assert results[1].lifetime_end_ms is not None assert results[2].lifetime_end_ms is not None assert results[0] == created
def rollback(mirror, since_ms): """ :param mirror: Mirror to perform rollback on :param start_time: Time mirror was started; all changes after will be undone :return: """ repository_ref = registry_model.lookup_repository( mirror.repository.namespace_user.username, mirror.repository.name) tags = [] index = 1 has_more = True while has_more: tags_page, has_more = registry_model.list_repository_tag_history( repository_ref, index, TAG_ROLLBACK_PAGE_SIZE, since_time_ms=since_ms) tags.extend(tags_page) index = index + 1 for tag in tags: logger.debug("Repo mirroring rollback tag '%s'" % tag) # If the tag has an end time, it was either deleted or moved. if tag.lifetime_end_ms: # If a future entry exists with a start time equal to the end time for this tag, # then the action was a move, rather than a delete and a create. tag_list = list( filter( lambda t: tag != t and tag.name == t.name and tag. lifetime_end_ms and t.lifetime_start_ms == tag. lifetime_end_ms, tags, )) if len(tag_list) > 0: logger.debug("Repo mirroring rollback revert tag '%s'" % tag) retarget_tag(tag.name, tag.manifest._db_id, is_reversion=True) else: logger.debug("Repo mirroring recreate tag '%s'" % tag) retarget_tag(tag.name, tag.manifest._db_id, is_reversion=True) # If the tag has a start time, it was created. elif tag.lifetime_start_ms: logger.debug("Repo mirroring rollback delete tag '%s'" % tag) delete_tag(mirror.repository, tag.name)
def test_retarget_tag_wrong_name(initialized_db): repo = get_repository("devtable", "history") results, _ = list_repository_tag_history(repo, 1, 100, specific_tag_name="latest") assert len(results) == 2 created = retarget_tag("someothername", results[1].manifest, is_reversion=True) assert created is None results, _ = list_repository_tag_history(repo, 1, 100, specific_tag_name="latest") assert len(results) == 2
def test_retarget_tag(initialized_db): repo = get_repository("devtable", "history") results, _ = list_repository_tag_history(repo, 1, 100, specific_tag_name="latest") assert len(results) == 2 assert results[0].lifetime_end_ms is None assert results[1].lifetime_end_ms is not None # Revert back to the original manifest. created = retarget_tag("latest", results[0].manifest, is_reversion=True, now_ms=results[1].lifetime_end_ms + 10000) assert created.lifetime_end_ms is None assert created.reversion assert created.name == "latest" assert created.manifest == results[0].manifest # Verify in the history. results, _ = list_repository_tag_history(repo, 1, 100, specific_tag_name="latest") assert len(results) == 3 assert results[0].lifetime_end_ms is None assert results[1].lifetime_end_ms is not None assert results[2].lifetime_end_ms is not None assert results[0] == created # Verify old-style tables. repository_tag = TagToRepositoryTag.get(tag=created).repository_tag assert repository_tag.lifetime_start_ts == int(created.lifetime_start_ms / 1000) tag_manifest = TagManifest.get(tag=repository_tag) assert TagManifestToManifest.get( tag_manifest=tag_manifest).manifest == created.manifest
def test_delete_tags_for_manifest_same_manifest(initialized_db): new_repo = model.repository.create_repository("devtable", "newrepo", None) manifest_1, _ = create_manifest_for_testing(new_repo, "1") manifest_2, _ = create_manifest_for_testing(new_repo, "2") assert manifest_1.digest != manifest_2.digest # Add some tag history, moving a tag back and forth between two manifests. retarget_tag("latest", manifest_1) retarget_tag("latest", manifest_2) retarget_tag("latest", manifest_1) retarget_tag("latest", manifest_2) retarget_tag("another1", manifest_1) retarget_tag("another2", manifest_2) # Delete all tags pointing to the first manifest. delete_tags_for_manifest(manifest_1) assert get_tag(new_repo, "latest").manifest == manifest_2 assert get_tag(new_repo, "another1") is None assert get_tag(new_repo, "another2").manifest == manifest_2 # Delete all tags pointing to the second manifest, which should actually delete the `latest` # tag now. delete_tags_for_manifest(manifest_2) assert get_tag(new_repo, "latest") is None assert get_tag(new_repo, "another1") is None assert get_tag(new_repo, "another2") is None