Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tag/untag commands for container repositories #429

Merged
merged 1 commit into from
Feb 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/423.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added tag/untag commands to add and remove tags from images in container repositories.
2 changes: 2 additions & 0 deletions pulpcore/cli/container/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,15 @@ class PulpContainerRepositoryContext(PulpRepositoryContext):
CAPABILITIES = {
"sync": [PluginRequirement("container")],
"pulpexport": [PluginRequirement("container", "2.8.0.dev")],
"tag": [PluginRequirement("container", "2.3.0")],
}


class PulpContainerPushRepositoryContext(PulpRepositoryContext):
HREF = "container_container_push_repository_href"
ID_PREFIX = "repositories_container_container_push"
VERSION_CONTEXT = PulpContainerPushRepositoryVersionContext
CAPABILITIES = {"tag": [PluginRequirement("container", "2.3.0")]}


registered_repository_contexts["container:container"] = PulpContainerRepositoryContext
Expand Down
54 changes: 54 additions & 0 deletions pulpcore/cli/container/repository.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import re
from typing import Any, Dict

import click
Expand Down Expand Up @@ -37,6 +38,16 @@

translation = get_translation(__name__)
_ = translation.gettext
VALID_TAG_REGEX = r"^[A-Za-z0-9][A-Za-z0-9._-]*$"


def _tag_callback(ctx: click.Context, param: click.Parameter, value: str) -> str:
if len(value) == 0:
raise click.ClickException("Please pass a non empty tag name.")
Comment on lines +45 to +46
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, an empty string would not pass the regex. But i see this check provide a better error condition.

if re.match(VALID_TAG_REGEX, value) is None:
raise click.ClickException("Please pass a valid tag.")

return value


remote_option = resource_option(
Expand Down Expand Up @@ -122,3 +133,46 @@ def sync(
href=repository_href,
body=body,
)


@repository.command(name="tag")
@name_option
@href_option
@click.option("--tag", help=_("Name to tag an image with"), required=True, callback=_tag_callback)
@click.option("--digest", help=_("SHA256 digest of the Manifest file"), required=True)
@pass_repository_context
def add_tag(
repository_ctx: PulpRepositoryContext,
digest: str,
tag: str,
) -> None:
if not repository_ctx.capable("tag"):
raise click.ClickException(_("pulp_container 2.3.0 is required to tag images"))
Comment on lines +149 to +150
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Note for later:) Ha, we should have a needs_capability that raises itself.
Rationale: All mentions of Pulp versions should be in context.py.


digest = digest.strip()
if not digest.startswith("sha256:"):
digest = f"sha256:{digest}"
if len(digest) != 71: # len("sha256:") + 64
raise click.ClickException("Improper SHA256, please provide a valid 64 digit digest.")

repository_ctx.call(
"tag",
parameters={repository_ctx.HREF: repository_ctx.pulp_href},
body={"tag": tag, "digest": digest},
)


@repository.command(name="untag")
@name_option
@href_option
@click.option("--tag", help=_("Name of tag to remove"), required=True, callback=_tag_callback)
@pass_repository_context
def remove_tag(repository_ctx: PulpRepositoryContext, tag: str) -> None:
if not repository_ctx.capable("tag"):
raise click.ClickException(_("pulp_container 2.3.0 is required to untag images"))

repository_ctx.call(
"untag",
parameters={repository_ctx.HREF: repository_ctx.pulp_href},
body={"tag": tag},
)
27 changes: 27 additions & 0 deletions tests/scripts/pulp_container/test_tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

# shellcheck source=tests/scripts/config.source
. "$(dirname "$(dirname "$(realpath "$0")")")"/config.source

pulp debug has-plugin --name "container" || exit 3

cleanup() {
pulp container repository destroy --name "cli_test_container_repository" || true
pulp container remote destroy --name "cli_test_container_remote" || true
pulp orphan cleanup || true
}
trap cleanup EXIT

# Prepare
pulp container remote create --name "cli_test_container_remote" --url "$CONTAINER_REMOTE_URL" --upstream-name "$CONTAINER_IMAGE"
pulp container repository create --name "cli_test_container_repository"
pulp container repository sync --name "cli_test_container_repository" --remote "cli_test_container_remote"
manifest_digest="$(pulp container content -t manifest list | tr '\r\n' ' ' | jq -r .[0].digest)"

expect_succ pulp container repository tag --name "cli_test_container_repository" --tag "test_tag" --digest "$manifest_digest"
expect_succ pulp container repository version show --repository "cli_test_container_repository" --version "2"
test "$(echo "$OUTPUT" | jq -r '.content_summary.added["container.tag"].count')" -eq "1"

expect_succ pulp container repository untag --name "cli_test_container_repository" --tag "test_tag"
expect_succ pulp container repository version show --repository "cli_test_container_repository" --version "3"
test "$(echo "$OUTPUT" | jq -r '.content_summary.removed["container.tag"].count')" -eq "1"