Skip to content
Open
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/+distribution-content-filter.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added `--distribution` filter to `pulp container content list` to resolve the served repository version and list tags (or other content) for that image.
68 changes: 67 additions & 1 deletion src/pulpcore/cli/container/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,33 @@

import click

from pulp_glue.common.context import PluginRequirement, PulpContentContext
from pulp_glue.common.context import (
EntityDefinition,
PluginRequirement,
PulpContentContext,
PulpDistributionContext,
PulpRepositoryContext,
)
from pulp_glue.container.context import (
PulpContainerBlobContext,
PulpContainerDistributionContext,
PulpContainerManifestContext,
PulpContainerPushRepositoryContext,
PulpContainerRepositoryContext,
PulpContainerTagContext,
)

from pulp_cli.generic import (
PulpCLIContext,
content_filter_options,
href_option,
label_command,
list_command,
option_group,
option_processor,
pulp_group,
pulp_option,
resource_option,
show_command,
type_option,
)
Expand All @@ -34,6 +46,44 @@ def _content_callback(ctx: click.Context, value: dict[str, t.Any]) -> None:
entity_ctx.entity = value


def _repository_version_from_distribution(
pulp_ctx: PulpCLIContext, distribution: EntityDefinition
) -> str:
if repository_version := distribution.get("repository_version"):
return t.cast(str, repository_version)

repository_href = distribution.get("repository")
if not repository_href:
raise click.ClickException(
_(
"Distribution '{name}' is not associated with a repository or repository version."
).format(name=distribution.get("name", ""))
)
if "/container-push/" in repository_href:
repo_ctx: PulpRepositoryContext = PulpContainerPushRepositoryContext(
pulp_ctx, pulp_href=repository_href
)
else:
repo_ctx = PulpContainerRepositoryContext(pulp_ctx, pulp_href=repository_href)

return t.cast(str, repo_ctx.entity["latest_version_href"])


def _process_distribution_filter(ctx: click.Context) -> None:
distribution = ctx.params.pop("distribution", None)
if not distribution:
return
if ctx.params.get("repository_version"):
raise click.UsageError(_("Cannot use --distribution together with --repository-version."))

assert isinstance(distribution, PulpContainerDistributionContext)
pulp_ctx = ctx.find_object(PulpCLIContext)
assert pulp_ctx is not None
ctx.params["repository_version"] = _repository_version_from_distribution(
pulp_ctx, distribution.entity
)


@pulp_group()
@type_option(
choices={
Expand All @@ -47,6 +97,20 @@ def content() -> None:
pass


distribution_filter_option = resource_option(
"--distribution",
default_plugin="container",
default_type="container",
context_table={
"container:container": PulpContainerDistributionContext,
},
href_pattern=PulpDistributionContext.HREF_PATTERN,
help=_(
"Filter {entities} by the repository version served by this distribution (name or href)."
),
)


list_options = [
pulp_option(
"--media-type",
Expand Down Expand Up @@ -86,6 +150,8 @@ def content() -> None:
allowed_with_contexts=(PulpContainerManifestContext,),
),
*content_filter_options,
distribution_filter_option,
option_processor(callback=_process_distribution_filter),
]

lookup_options = [
Expand Down
12 changes: 3 additions & 9 deletions src/pulpcore/cli/container/distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from pulp_glue.common.context import (
EntityDefinition,
EntityFieldDefinition,
PluginRequirement,
PulpEntityContext,
PulpRepositoryContext,
)
Expand Down Expand Up @@ -104,9 +103,6 @@ def update(

distribution: EntityDefinition = distribution_ctx.entity
body: EntityDefinition = {}
non_blocking = base_path is None and distribution_ctx.pulp_ctx.has_plugin(
PluginRequirement("core", specifier=">=3.24.0")
)

if private is not None:
body["private"] = private
Expand All @@ -127,18 +123,16 @@ def update(
repository = t.cast(PulpEntityContext, repository)
if version is not None:
if distribution["repository"]:
distribution_ctx.update(body={"repository": ""}, non_blocking=non_blocking)
distribution_ctx.update(body={"repository": ""}, non_blocking=False)
body["repository_version"] = f"{repository.pulp_href}versions/{version}/"
else:
if distribution["repository_version"]:
distribution_ctx.update(
body={"repository_version": ""}, non_blocking=non_blocking
)
distribution_ctx.update(body={"repository_version": ""}, non_blocking=False)
body["repository"] = repository.pulp_href
elif version is not None:
# keep current repository, change version
if distribution["repository"]:
distribution_ctx.update(body={"repository": ""}, non_blocking=non_blocking)
distribution_ctx.update(body={"repository": ""}, non_blocking=False)
body["repository_version"] = f"{distribution['repository']}versions/{version}/"
elif distribution["repository_version"]:
# 'dummy' vars are to get us around a mypy/1.2 complaint about '_'
Expand Down
14 changes: 14 additions & 0 deletions tests/scripts/pulp_container/test_content.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set -eu
pulp debug has-plugin --name "container" || exit 23

cleanup() {
pulp container distribution destroy --name "cli_test_container_content_distro" || true
pulp container repository destroy --name "cli_test_container_content_repository" || true
pulp container remote destroy --name "cli_test_container_content_remote" || true
}
Expand All @@ -16,6 +17,9 @@ trap cleanup EXIT
pulp container remote create --name "cli_test_container_content_remote" --url "$CONTAINER_REMOTE_URL" --upstream-name "$CONTAINER_IMAGE"
pulp container repository create --name "cli_test_container_content_repository"
pulp container repository sync --name "cli_test_container_content_repository" --remote "cli_test_container_content_remote"
pulp container distribution create --name "cli_test_container_content_distro" \
--base-path "cli_test_container_content_distro" \
--repository "cli_test_container_content_repository"

# Check each content list
expect_succ pulp container content -t blob list
Expand Down Expand Up @@ -69,3 +73,13 @@ test "$(echo "$OUTPUT" | jq -r length)" -ge "1"

expect_succ pulp container content -t blob list --digest "$blob_digest"
test "$(echo "$OUTPUT" | jq -r length)" -ge "1"

# Filter tags by repository version and by distribution (resolves to repository version)
repo_ver_href="$(pulp container repository show --name "cli_test_container_content_repository" | jq -r .latest_version_href)"
expect_succ pulp container content -t tag list --repository-version "$repo_ver_href"
test "$(echo "$OUTPUT" | jq -r length)" -ge "1"
expect_succ pulp container content -t tag list --distribution "cli_test_container_content_distro"
test "$(echo "$OUTPUT" | jq -r length)" -ge "1"
expect_fail pulp container content -t tag list \
--distribution "cli_test_container_content_distro" \
--repository-version "$repo_ver_href"
Loading