Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions posit-bakery/posit_bakery/plugins/builtin/imagetools/oras.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,21 @@ class OrasCopy(OrasCommand):

@property
def command(self) -> list[str]:
"""Build the oras cp command."""
"""Build the oras cp command.

``oras cp`` has two endpoints, so unlike every other oras subcommand it
takes ``--from-plain-http`` and ``--to-plain-http`` rather than a single
``--plain-http`` -- passing the latter exits with ``unknown flag``.

Each flag is only emitted when that end is actually a registry: an OCI
layout is a filesystem path, and a plain-HTTP flag aimed at it is at best
meaningless.
"""
cmd = [self.oras_bin, "cp"]
if self.plain_http:
cmd.append("--plain-http")
if self.plain_http and not self.from_oci_layout:
cmd.append("--from-plain-http")
if self.plain_http and not self.to_oci_layout:
cmd.append("--to-plain-http")
if self.from_oci_layout:
cmd.append("--from-oci-layout")
if self.to_oci_layout:
Expand Down
72 changes: 70 additions & 2 deletions posit-bakery/test/plugins/builtin/imagetools/test_oras.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,17 +548,85 @@ def test_manifest_index_create_with_plain_http(self):
assert cmd.command == expected

def test_copy_with_plain_http(self):
"""Test that --plain-http flag is included when plain_http=True."""
"""`oras cp` takes per-endpoint plain-HTTP flags, not a single --plain-http.

Unlike every other oras subcommand, `cp` has two endpoints. Passing a bare
`--plain-http` exits with `unknown flag`, so registry-to-registry copies
must emit both `--from-plain-http` and `--to-plain-http`.
"""
cmd = OrasCopy(
oras_bin="oras",
source="localhost:5000/test:source",
destination="localhost:5000/test:dest",
plain_http=True,
)

expected = ["oras", "cp", "--plain-http", "localhost:5000/test:source", "localhost:5000/test:dest"]
expected = [
"oras",
"cp",
"--from-plain-http",
"--to-plain-http",
"localhost:5000/test:source",
"localhost:5000/test:dest",
]
assert cmd.command == expected

def test_copy_never_emits_bare_plain_http(self):
"""Regression guard: `--plain-http` is not a valid flag for `oras cp`.

Asserted across every layout combination so no future branch can
reintroduce it.
"""
for from_layout, to_layout in ((False, False), (True, False), (False, True)):
cmd = OrasCopy(
oras_bin="oras",
source="localhost:5000/test:source",
destination="localhost:5000/test:dest",
plain_http=True,
from_oci_layout=from_layout,
to_oci_layout=to_layout,
)
assert "--plain-http" not in cmd.command

def test_copy_plain_http_skipped_for_layout_endpoints(self):
"""A plain-HTTP flag is only meaningful for an endpoint that is a registry.

An OCI layout is a filesystem path, so the flag aimed at it is dropped.
"""
# Layout source, registry destination -> only --to-plain-http.
cmd = OrasCopy(
oras_bin="oras",
source="/tmp/out@sha256:abc",
destination="localhost:5000/test:dest",
plain_http=True,
from_oci_layout=True,
)
assert cmd.command == [
"oras",
"cp",
"--to-plain-http",
"--from-oci-layout",
"/tmp/out@sha256:abc",
"localhost:5000/test:dest",
]

# Registry source, layout destination -> only --from-plain-http.
cmd = OrasCopy(
oras_bin="oras",
source="localhost:5000/test:source",
destination="/tmp/src:image",
plain_http=True,
to_oci_layout=True,
)
assert cmd.command == [
"oras",
"cp",
"--from-plain-http",
"--to-oci-layout",
"localhost:5000/test:source",
"/tmp/src:image",
]


@pytest.fixture
def mock_image_target_factory():
Expand Down
Loading