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 test_get_most_recent_tag_lifetime_start(initialized_db): repo = get_repository("devtable", "simple") tag = get_most_recent_tag(repo) with assert_query_count(1): tags = get_most_recent_tag_lifetime_start([repo]) assert tags[repo.id] == tag.lifetime_start_ms
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 test_list_repository_tag_history_with_history(initialized_db): repo = get_repository("devtable", "history") with assert_query_count(1): results, _ = list_repository_tag_history(repo, 1, 100) assert len(results) == 2 assert results[0].lifetime_end_ms is None assert results[1].lifetime_end_ms is not None with assert_query_count(1): 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 with assert_query_count(1): results, _ = list_repository_tag_history(repo, 1, 100, specific_tag_name="foobar") assert len(results) == 0
def wrapper(namespace_name, repo_name, *args, **kwargs): """ Conditionally allow changes depending on the Repository's state. NORMAL -> Pass READ_ONLY -> Block all POST/PUT/DELETE MIRROR -> Same as READ_ONLY, except treat the Mirroring Robot User as Normal MARKED_FOR_DELETION -> Block everything as a 404 """ user = get_authenticated_user() if user is None: # NOTE: Remaining auth checks will be handled by subsequent decorators. return f(namespace_name, repo_name, *args, **kwargs) repository = get_repository(namespace_name, repo_name) if not repository: return f(namespace_name, repo_name, *args, **kwargs) if repository.state == RepositoryState.MARKED_FOR_DELETION: abort(404) if repository.state == RepositoryState.READ_ONLY: abort(405, "%s/%s is in read-only mode." % (namespace_name, repo_name)) if repository.state == RepositoryState.MIRROR: mirror = get_mirror(repository) robot = mirror.internal_robot if mirror is not None else None if mirror is None: abort( 500, "Repository %s/%s is set as a mirror but the Mirror configuration is missing." % (namespace_name, repo_name), ) elif robot is None: abort( 400, "Repository %s/%s is configured for mirroring but no robot is assigned." % (namespace_name, repo_name), ) elif user.id != robot.id: abort( 405, "Repository %s/%s is a mirror. Mirrored repositories cannot be modified directly." % (namespace_name, repo_name), ) elif user.id == robot.id: pass # User is designated robot for this mirror repo. else: msg = ( "An internal error has occurred while verifying repository %s/%s state. Please report " "this to an administrator." ) % (namespace_name, repo_name) raise Exception(msg) return f(namespace_name, repo_name, *args, **kwargs)
def test_list_repository_tag_history(namespace_name, repo_name, initialized_db): repo = get_repository(namespace_name, repo_name) with assert_query_count(1): results, has_more = list_repository_tag_history(repo, 1, 100) assert results assert not has_more
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_find_matching_tag(namespace_name, repo_name, tag_names, expected, initialized_db): repo = get_repository(namespace_name, repo_name) if expected is not None: with assert_query_count(1): found = find_matching_tag(repo, tag_names) assert found is not None assert found.name == expected assert not found.lifetime_end_ms else: with assert_query_count(1): assert find_matching_tag(repo, tag_names) is None
def test_list_repository_tag_history(namespace_name, repo_name, initialized_db): repo = get_repository(namespace_name, repo_name) with assert_query_count(1): results, has_more = list_repository_tag_history(repo, 1, 100) assert results assert not has_more assert results[0].manifest.id is not None assert results[0].manifest.digest is not None assert results[0].manifest.media_type is not None assert results[0].manifest.layers_compressed_size is not None
def test_get_or_create_manifest_invalid_image(initialized_db): repository = get_repository("devtable", "simple") latest_tag = get_tag(repository, "latest") parsed = DockerSchema1Manifest(Bytes.for_string_or_unicode( latest_tag.manifest.manifest_bytes), validate=False) builder = DockerSchema1ManifestBuilder("devtable", "simple", "anothertag") builder.add_layer(parsed.blob_digests[0], '{"id": "foo", "parent": "someinvalidimageid"}') sample_manifest_instance = builder.build(docker_v2_signing_key) created_manifest = get_or_create_manifest(repository, sample_manifest_instance, storage) assert created_manifest is None
def lookup_repository(self, namespace_name, repo_name, kind_filter=None, raise_on_error=False, manifest_ref=None): """ Looks up and returns a reference to the repository with the given namespace and name, or None if none. If the repository does not exist and the given manifest_ref exists upstream, creates the repository. """ repo = get_repository(namespace_name, repo_name) exists = repo is not None if exists: return RepositoryReference.for_repo_obj( repo, namespace_name, repo_name, repo.namespace_user.stripe_id is None if repo else None, state=repo.state if repo is not None else None, ) # we only create a repository for images that exist upstream, and if # we're not given a manifest reference then we can't check whether the # image exists upstream or not, so we refuse to create the repo. if manifest_ref is None: return None try: self._proxy.manifest_exists(manifest_ref, ACCEPTED_MEDIA_TYPES) except UpstreamRegistryError as e: if raise_on_error: raise RepositoryDoesNotExist(str(e)) return None repo = create_repository(namespace_name, repo_name, self._user) return RepositoryReference.for_repo_obj( repo, namespace_name, repo_name, repo.namespace_user.stripe_id is None if repo else None, state=repo.state if repo is not None else None, )
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_get_most_recent_tag(initialized_db): repo = get_repository("outsideorg", "coolrepo") with assert_query_count(1): assert get_most_recent_tag(repo).name == "latest"
def test_get_expired_tag(namespace_name, repo_name, tag_name, expected, initialized_db): repo = get_repository(namespace_name, repo_name) with assert_query_count(1): assert bool(get_expired_tag(repo, tag_name)) == expected
def test_get_most_recent_tag(initialized_db): repo = get_repository('outsideorg', 'coolrepo') with assert_query_count(1): assert get_most_recent_tag(repo).name == 'latest'