Skip to content

Commit 2b1b23e

Browse files
jobselkomdellweg
authored andcommitted
Serve Python content form a repository version
closes #1324 Assisted by: Claude Sonnet 4
1 parent 06a92c8 commit 2b1b23e

File tree

8 files changed

+88
-6
lines changed

8 files changed

+88
-6
lines changed

CHANGES/1324.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added `--version` option to `pulp python distribution` for serving content from a specific repository version.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed `PulpEntityContext.update` method to correctly pass `partial=True` to `preprocess_entity`.

CHANGES/pulp-glue/1324.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added repository version logic to `PulpPythonDistributionContext` for `pulp_python>=3.21.0`.

pulp-glue/docs/dev/learn/architecture.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Those include:
2424

2525
- `PulpContext.api`: When accessed, the `api.json` file for the addressed server will be read or downloaded and processed.
2626
Scheduled version checks will be evaluated at that point.
27-
- `PulpContext.needs_version`: This function can be used at any time to declare that an operation needs a plugin in a version range.
27+
- `PulpContext.needs_plugin`: This function can be used at any time to declare that an operation needs a plugin in a version range.
2828
The actual check will be performed immediately when `api` already was accessed, or scheduled for later.
2929
- `PulpEntityContext.entity`: This property can be used to collect lookup attributes for entities by assigning dicts to it.
3030
On read access, the entity lookup will be performed through the `api` property.
@@ -50,7 +50,7 @@ Typically, plugin requirements are checked by passing into `PulpContext.has_plug
5050
Some Entities may provide support for different Pulp concepts based on their plugins version.
5151
e.g. `Pulp Import Export` for a specific repository type may be added in a certain Pulp Plugin version.
5252
You can add a `capability` to the `PulpEntityContext` subclass with an attached `PluginRequirement`.
53-
Whenever glue attempts to perform the corresonding action, the capabilities are first checked against the server's versions.
53+
Whenever glue attempts to perform the corresponding action, the capabilities are first checked against the server's versions.
5454

5555
### API quirks
5656

@@ -60,5 +60,5 @@ See the `pulp_glue.common.api_quirk` decorator.
6060

6161
## Plugin System
6262

63-
Pulp Glue comes with a plugin interface to be easily extendible.
63+
Pulp Glue comes with a plugin interface to be easily extendable.
6464
Multiple plugins can be provided by the same Python package and some plugins are shipped with the pulp-glue core package.

pulp-glue/src/pulp_glue/common/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,7 @@ def update(
11841184
if parameters:
11851185
_parameters.update(parameters)
11861186
if body is not None:
1187-
body = self.preprocess_entity(body, partial=False)
1187+
body = self.preprocess_entity(body, partial=True)
11881188
if self.pulp_ctx.fake_mode:
11891189
assert self._entity is not None
11901190
if body is not None:

pulp-glue/src/pulp_glue/python/context.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
PulpRepositoryVersionContext,
1212
api_spec_quirk,
1313
)
14+
from pulp_glue.common.exceptions import PulpException
1415
from pulp_glue.common.i18n import get_translation
1516

1617
translation = get_translation(__package__)
@@ -67,11 +68,33 @@ def preprocess_entity(self, body: EntityDefinition, partial: bool = False) -> En
6768
self.pulp_ctx.needs_plugin(PluginRequirement("python", specifier=">=3.4.0"))
6869
if "remote" in body:
6970
self.pulp_ctx.needs_plugin(PluginRequirement("python", specifier=">=3.6.0"))
71+
if "version" in body:
72+
self.pulp_ctx.needs_plugin(PluginRequirement("python", specifier=">=3.21.0"))
7073
if self.pulp_ctx.has_plugin(PluginRequirement("core", specifier=">=3.16.0")):
7174
if "repository" in body and "publication" not in body:
7275
body["publication"] = None
7376
if "repository" not in body and "publication" in body:
7477
body["repository"] = None
78+
79+
version = body.pop("version", None)
80+
if version is not None:
81+
repository_href = body.pop("repository", None)
82+
if not repository_href and partial:
83+
current_entity = self.entity
84+
repository_href = current_entity.get("repository")
85+
if not repository_href and (
86+
repository_version_href := current_entity.get("repository_version")
87+
):
88+
repository_href = f"{repository_version_href.rsplit('/', 3)[0]}/"
89+
if not repository_href:
90+
raise PulpException(_("--repository must be provided"))
91+
body["repository_version"] = f"{repository_href}versions/{version}/"
92+
body["repository"] = None
93+
elif "repository" in body and self.pulp_ctx.has_plugin(
94+
PluginRequirement("python", specifier=">=3.21.0")
95+
):
96+
body["repository_version"] = None
97+
7598
return body
7699

77100

src/pulpcore/cli/python/distribution.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
default_type="python",
4040
context_table={"python:python": PulpPythonRepositoryContext},
4141
help=_(
42-
"Repository to be used for auto-distributing."
43-
" When set, this will unset the 'publication'."
42+
"Repository to be distributed."
43+
" When used, this will replace any attached 'publication'."
4444
" Specified as '[[<plugin>:]<type>:]<name>' or as href."
4545
),
4646
href_pattern=PulpPythonRepositoryContext.HREF_PATTERN,
@@ -75,6 +75,15 @@ def distribution(ctx: click.Context, pulp_ctx: PulpCLIContext, /, distribution_t
7575
),
7676
),
7777
repository_option,
78+
pulp_option(
79+
"--version",
80+
type=int,
81+
help=_(
82+
"The repository version number to distribute."
83+
" When unset, the latest version of the repository will be auto-distributed."
84+
),
85+
needs_plugins=[PluginRequirement("python", specifier=">=3.21.0")],
86+
),
7887
content_guard_option,
7988
pulp_option(
8089
"--allow-uploads/--block-uploads",

tests/scripts/pulp_python/test_distribution.sh

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ cleanup() {
1010
pulp python repository destroy --name "cli_test_python_distribution_repository" || true
1111
pulp python remote destroy --name "cli_test_python_distribution_remote" || true
1212
pulp python distribution destroy --name "cli_test_python_distro" || true
13+
pulp python distribution destroy --name "cli_test_python_distro_repo" || true
14+
pulp python distribution destroy --name "cli_test_python_distro_repo_version" || true
1315
}
1416
trap cleanup EXIT
1517

@@ -42,3 +44,48 @@ expect_succ pulp python distribution update \
4244
--remote "cli_test_python_distribution_remote"
4345

4446
expect_succ pulp python distribution destroy --distribution "cli_test_python_distro"
47+
48+
# Test repository_version functionality
49+
if pulp debug has-plugin --name "python" --specifier ">=3.21.0"; then
50+
expect_succ pulp python distribution create \
51+
--name "cli_test_python_distro_repo" \
52+
--base-path "cli_test_python_distro_repo" \
53+
--repository "cli_test_python_distribution_repository"
54+
expect_succ pulp python distribution show --distribution "cli_test_python_distro_repo"
55+
echo "$OUTPUT" | jq -e '.repository_version == null'
56+
echo "$OUTPUT" | jq -e '.repository != null'
57+
58+
expect_succ pulp python distribution create \
59+
--name "cli_test_python_distro_repo_version" \
60+
--base-path "cli_test_python_distro_repo_version" \
61+
--repository "cli_test_python_distribution_repository" \
62+
--version 0
63+
expect_succ pulp python distribution show --distribution "cli_test_python_distro_repo_version"
64+
echo "$OUTPUT" | jq -e '.repository_version | contains("/versions/0/")'
65+
echo "$OUTPUT" | jq -e '.repository == null'
66+
67+
expect_succ pulp python distribution update \
68+
--distribution "cli_test_python_distro_repo_version" \
69+
--repository "cli_test_python_distribution_repository" \
70+
--version 1
71+
expect_succ pulp python distribution show --distribution "cli_test_python_distro_repo_version"
72+
echo "$OUTPUT" | jq -e '.repository_version | contains("/versions/1/")'
73+
echo "$OUTPUT" | jq -e '.repository == null'
74+
75+
expect_succ pulp python distribution update \
76+
--distribution "cli_test_python_distro_repo_version" \
77+
--version 0
78+
expect_succ pulp python distribution show --distribution "cli_test_python_distro_repo_version"
79+
echo "$OUTPUT" | jq -e '.repository_version | contains("/versions/0/")'
80+
echo "$OUTPUT" | jq -e '.repository == null'
81+
82+
expect_succ pulp python distribution update \
83+
--distribution "cli_test_python_distro_repo_version" \
84+
--repository "cli_test_python_distribution_repository"
85+
expect_succ pulp python distribution show --distribution "cli_test_python_distro_repo_version"
86+
echo "$OUTPUT" | jq -e '.repository_version == null'
87+
echo "$OUTPUT" | jq -e '.repository != null'
88+
89+
expect_succ pulp python distribution destroy --distribution "cli_test_python_distro_repo"
90+
expect_succ pulp python distribution destroy --distribution "cli_test_python_distro_repo_version"
91+
fi

0 commit comments

Comments
 (0)