Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
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)
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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
Exemple #9
0
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,
        )
Exemple #12
0
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
Exemple #13
0
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"
Exemple #14
0
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
Exemple #15
0
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'