Skip to content
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
56 changes: 40 additions & 16 deletions pyxis/create_container_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
Container Repository object to exist in Pyxis. This will typically be created as part
of product onboarding to RHTAP.

Flatpak images use different Quay namespaces and a different Pyxis registry: they are
pushed to quay.io/rh-flatpaks-prod/* or quay.io/rh-flatpaks-stage/*. For these, the
registry value in Pyxis is set to flatpaks.registry.redhat.io (for both prod and stage).

For stage, if you want to be able to pull an image from registry.stage.redhat.io,
the image is pushed to quay.io/redhat-pending, the Container Image is created
in stage Pyxis, but the registry value in Pyxis is still set to registry.access.redhat.com.
Expand Down Expand Up @@ -125,12 +129,14 @@ def setup_argparser() -> Any: # pragma: no cover
)
parser.add_argument(
"--rh-push",
help="If set to true, a second item will be created in ContainerImage.repositories "
"with the registry and repository entries converted to use Red Hat's official "
"registry. E.g. a mapped repository of "
"quay.io/redhat-pending/product---my-image will be converted to use "
"registry registry.access.redhat.com and repository product/my-image. Also, "
"the image will be marked as published.",
help="If set to true, the item created in ContainerImage.repositories "
"will have the registry and repository entries converted to use Red Hat's official "
"registry. For standard images (quay.io/redhat-prod/*, quay.io/redhat-pending/*) "
"registry is registry.access.redhat.com; for flatpaks (quay.io/rh-flatpaks-prod/*, "
"quay.io/rh-flatpaks-stage/*) registry is flatpaks.registry.redhat.io. "
"E.g. quay.io/redhat-pending/product----my-image becomes registry "
"registry.access.redhat.com and repository product/my-image. The image will be "
"marked as published.",
default="false",
)
parser.add_argument(
Expand Down Expand Up @@ -340,28 +346,46 @@ def update_container_image_repositories(
raise Exception("Image metadata was not successfully added to Pyxis.")


def _rh_push_registry(image_name: str) -> str:
"""Return the Pyxis registry string for rh_push when --rh-push is true.

For flatpak images (quay.io/rh-flatpaks-prod/* or quay.io/rh-flatpaks-stage/*)
returns flatpaks.registry.redhat.io. For other Red Hat images
(e.g. quay.io/redhat-prod/*, quay.io/redhat-pending/*) returns
registry.access.redhat.com.
"""
parts = image_name.split("/")
if len(parts) >= 2 and parts[1] in ("rh-flatpaks-prod", "rh-flatpaks-stage"):
return "flatpaks.registry.redhat.io"
return "registry.access.redhat.com"


def construct_repository(args, tags):
"""Build the repository dict for the Container Image.

When rh_push is true, the repository entry it adds will be for Red Hat
registries: registry is either registry.access.redhat.com (for standard
images like quay.io/redhat-prod/*, quay.io/redhat-pending/*) or
flatpaks.registry.redhat.io (for flatpak images quay.io/rh-flatpaks-prod/*,
quay.io/rh-flatpaks-stage/*). The repository path is derived via proxymap
(e.g. product----image -> product/image).
"""
image_name = args.name
image_registry = image_name.split("/")[0]
image_repo = image_name.split("/", 1)[1]

date_now = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f+00:00")

# For images released to registry.redhat.io we need a special repository item
# with published=true and registry and repository converted.
# E.g. if the name in the oras manifest result is
# "quay.io/redhat-prod/rhtas-tech-preview----cosign-rhel9",
# repository will be "rhtas-tech-preview/cosign-rhel9"
if args.rh_push == "true":
LOGGER.info("--rh-push is true. Associating registry.access.redhat.com repository.")
registry = _rh_push_registry(image_name)
LOGGER.info("--rh-push is true. Associating %s repository.", registry)
repo = {
"published": True,
"registry": "registry.access.redhat.com",
"registry": registry,
"repository": proxymap(image_name),
"push_date": date_now,
"tags": pyxis_tags(tags, date_now),
}
else:
image_registry = image_name.split("/")[0]
image_repo = image_name.split("/", 1)[1]
repo = {
"published": False,
"registry": image_registry,
Expand Down
58 changes: 58 additions & 0 deletions pyxis/test_create_container_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
create_container_image,
update_container_image_repositories,
construct_repository,
_rh_push_registry,
)


Expand Down Expand Up @@ -610,6 +611,27 @@ def test_repository_digest_values__multi_arch():
}


def test_rh_push_registry():
"""Flatpak namespaces use flatpaks.registry.redhat.io;
others use registry.access.redhat.com.
"""
assert (
_rh_push_registry("quay.io/rh-flatpaks-prod/foo/bar") == "flatpaks.registry.redhat.io"
)
assert (
_rh_push_registry("quay.io/rh-flatpaks-stage/foo/bar") == "flatpaks.registry.redhat.io"
)
assert (
_rh_push_registry("quay.io/redhat-prod/product----image")
== "registry.access.redhat.com"
)
assert (
_rh_push_registry("quay.io/redhat-pending/product----image")
== "registry.access.redhat.com"
)
assert _rh_push_registry("quay.io/some-org/repo") == "registry.access.redhat.com"


@patch("create_container_image.datetime")
def test_construct_repository__rh_push_true(mock_datetime):
mock_datetime.now = MagicMock(return_value=datetime(1970, 10, 10, 10, 10, 10))
Expand Down Expand Up @@ -643,6 +665,42 @@ def test_construct_repository__rh_push_true(mock_datetime):
}


@patch("create_container_image.datetime")
def test_construct_repository__rh_push_true_flatpak_prod(mock_datetime):
mock_datetime.now = MagicMock(return_value=datetime(1970, 10, 10, 10, 10, 10))
args = MagicMock()
args.media_type = "application/vnd.oci.image.manifest.v1+json"
args.architecture_digest = "sha256:abc"
args.digest = "sha256:top"
args.rh_push = "true"
args.name = "quay.io/rh-flatpaks-prod/myapp----myflatpak"
tags = ["latest"]

repo = construct_repository(args, tags)

assert repo["registry"] == "flatpaks.registry.redhat.io"
assert repo["repository"] == "myapp/myflatpak"
assert repo["published"] is True


@patch("create_container_image.datetime")
def test_construct_repository__rh_push_true_flatpak_stage(mock_datetime):
mock_datetime.now = MagicMock(return_value=datetime(1970, 10, 10, 10, 10, 10))
args = MagicMock()
args.media_type = "application/vnd.oci.image.manifest.v1+json"
args.architecture_digest = "sha256:def"
args.digest = "sha256:top2"
args.rh_push = "true"
args.name = "quay.io/rh-flatpaks-stage/namespace----another-flatpak"
tags = ["1.0"]

repo = construct_repository(args, tags)

assert repo["registry"] == "flatpaks.registry.redhat.io"
assert repo["repository"] == "namespace/another-flatpak" # proxymap: ---- -> /
assert repo["published"] is True


@patch("create_container_image.datetime")
def test_construct_repository__rh_push_false(mock_datetime):
mock_datetime.now = MagicMock(return_value=datetime(1970, 10, 10, 10, 10, 10))
Expand Down