Skip to content

chore(ci): multi-arch e2e-runner image & add oc-mirror and podman#5036

Merged
openshift-merge-bot[bot] merged 15 commits into
redhat-developer:mainfrom
zdrapela:multiplatform-e2e-runner
Jul 2, 2026
Merged

chore(ci): multi-arch e2e-runner image & add oc-mirror and podman#5036
openshift-merge-bot[bot] merged 15 commits into
redhat-developer:mainfrom
zdrapela:multiplatform-e2e-runner

Conversation

@zdrapela

@zdrapela zdrapela commented Jun 30, 2026

Copy link
Copy Markdown
Member

Make the e2e-runner container image buildable for both linux/amd64 and linux/arm64, and add tools required for disconnected environment smoke tests.

Dockerfile

  • Add podman and oc-mirror to the image (required for disconnected env. smoke test)
  • Update oc to 4.22
  • Pin base image to manifest list digest (resolves per-platform, Renovate-compatible)
  • Add ARG TARGETARCH — all tool downloads use it instead of hardcoded amd64/x86_64
  • Upgrade umoci v0.4.7 → v0.6.0 (first version with arm64 binaries)
  • Remove unused Go env vars (GO_VERSION, GO_SHA256, GOPATH)
  • Clean up AWS CLI install artifacts (rm -rf awscliv2.zip aws/)
  • Add apt-get clean to skopeo/podman install step

CI Workflow

  • Add matrix strategy: ubuntu-24.04 (amd64) + ubuntu-24.04-arm (arm64)
  • New merge job assembles per-arch digests into a multi-arch manifest list
  • Add pull_request trigger — builds both platforms (without pushing) on Dockerfile/yarnrc changes to catch build failures before merge
  • Push-only steps (login, digest export, merge) guarded with if: github.event_name != 'pull_request'
  • Detect platform via dpkg --print-architecture instead of mapping runner label names
  • Add HAS_QUAY_AUTH guard, timeout-minutes: 120, pin merge runner to ubuntu-24.04
  • Widen branch glob from release-1.* to release-* for future major versions

local-run.sh

  • Remove --platform=linux/amd64 from podman pull (auto-detects host arch)

Verified locally

Both images built and all tools (helm, oc, oc-mirror, ocm, yq, aws, az, gcloud, umoci, opm, operator-sdk, node, yarn, psql, skopeo, podman) confirmed working on both architectures.

https://redhat.atlassian.net/browse/RHIDP-13974

@rhdh-qodo-merge

Copy link
Copy Markdown

PR Summary by Qodo

chore(ci): make e2e-runner image builds multi-arch (amd64 + arm64)

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Pin Playwright base image to a multi-arch manifest digest.
• Parameterize tool downloads via TARGETARCH for amd64/arm64 builds.
• Let local-run podman pull auto-select the host architecture.
Diagram

graph TD
  A["CI / Developer"] --> B["buildx / podman build"] --> C[".ci/images/Dockerfile"] --> D["TARGETARCH (amd64/arm64)"] --> E["Arch-aware tool downloads"] --> F["e2e-runner image"]
  G["e2e-tests/local-run.sh"] --> H["podman pull runner image"] --> F
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use TARGETPLATFORM + explicit mapping
  • ➕ More future-proof (handles platform variants like linux/arm/v7)
  • ➕ Avoids assuming TARGETARCH strings match upstream naming schemes
  • ➖ Slightly more scripting/branching in the Dockerfile
  • ➖ No immediate benefit if only amd64/arm64 are required
2. Switch more tools to distro packages where available
  • ➕ Reduces curl-install surface area and arch-specific URL handling
  • ➕ Lets apt resolve architecture automatically
  • ➖ Versions may lag compared to pinned upstream releases
  • ➖ Some tools (oc/oc-mirror/opm) are not reliably available via apt with desired versions

Recommendation: The PR’s approach (TARGETARCH-driven URLs + targeted special-casing for oc/oc-mirror and AWS CLI naming) is the best fit for the current goal of amd64+arm64 support while keeping versions pinned. Consider TARGETPLATFORM mapping only if additional architectures/variants become a requirement.

Files changed (2) +35 / -27

Other (2) +35 / -27
DockerfileMake tool installs architecture-aware for multi-arch e2e-runner builds +34/-26

Make tool installs architecture-aware for multi-arch e2e-runner builds

• Pins the Playwright base image to a manifest-list digest and introduces TARGETARCH to drive architecture-specific downloads. Updates oc to 4.22.3, adds oc-mirror, upgrades umoci to v0.6.0 for arm64 support, and switches multiple tool URLs (helm/oc/ocm/yq/opm) to use the resolved architecture. Also removes unused Go-related env vars and installs podman alongside skopeo.

.ci/images/Dockerfile

local-run.shStop forcing amd64 when pulling the runner image locally +1/-1

Stop forcing amd64 when pulling the runner image locally

• Removes the explicit --platform=linux/amd64 flag from podman pull so the correct image variant is selected automatically on arm64 and amd64 hosts.

e2e-tests/local-run.sh

Comment thread .ci/images/Dockerfile Dismissed
@zdrapela zdrapela force-pushed the multiplatform-e2e-runner branch from 9b20e13 to ebb1f3f Compare June 30, 2026 09:31
@zdrapela zdrapela changed the title chore(ci): make e2e-runner Dockerfile multi-arch (amd64 + arm64) chore(ci): multi-arch e2e-runner image (amd64 + arm64) Jun 30, 2026
@zdrapela zdrapela force-pushed the multiplatform-e2e-runner branch from bda8d90 to cc32cb7 Compare June 30, 2026 09:41
@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 54.77%. Comparing base (a1a8bf9) to head (524341e).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5036      +/-   ##
==========================================
- Coverage   55.39%   54.77%   -0.62%     
==========================================
  Files         122      110      -12     
  Lines        2365     2147     -218     
  Branches      562      541      -21     
==========================================
- Hits         1310     1176     -134     
+ Misses       1048      969      -79     
+ Partials        7        2       -5     
Flag Coverage Δ
rhdh 54.77% <ø> (-0.62%) ⬇️

Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a1a8bf9...524341e. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown
Contributor

The container image build workflow finished with status: cancelled.

@zdrapela zdrapela force-pushed the multiplatform-e2e-runner branch from e7f2401 to 452bf05 Compare June 30, 2026 09:49
@github-actions

Copy link
Copy Markdown
Contributor

The container image build workflow finished with status: cancelled.

@zdrapela zdrapela force-pushed the multiplatform-e2e-runner branch from 452bf05 to d7171bb Compare June 30, 2026 09:49
@github-actions

Copy link
Copy Markdown
Contributor

The container image build workflow finished with status: cancelled.

@zdrapela zdrapela force-pushed the multiplatform-e2e-runner branch from d7171bb to 27fcb80 Compare June 30, 2026 09:51
@github-actions

Copy link
Copy Markdown
Contributor

The container image build workflow finished with status: cancelled.

@zdrapela zdrapela changed the title chore(ci): multi-arch e2e-runner image (amd64 + arm64) chore(ci): multi-arch e2e-runner image & add oc-mirror and podman Jun 30, 2026
@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Jun 30, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. TARGETARCH may be unset 🐞 Bug ☼ Reliability
Description
.ci/images/Dockerfile uses ${TARGETARCH} directly in multiple download URLs/paths, but `ARG
TARGETARCH has no fallback; builds that don’t inject TARGETARCH` will generate invalid URLs like
linux-.tar.gz and fail. This is especially likely for the repo-documented podman build ...
command, which does not pass --platform/--build-arg.
Code

.ci/images/Dockerfile[R6-7]

+# Automatically set by buildx/podman based on --platform (amd64 or arm64)
+ARG TARGETARCH
Relevance

⭐⭐ Medium

No prior reviews on TARGETARCH fallback; only general Dockerfile reliability fixes accepted (digest
pinning).

PR-#4575

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The Dockerfile declares ARG TARGETARCH without a default and later interpolates it into multiple
download URLs and paths; the repo’s build instructions show podman build without any
--platform/--build-arg, so TARGETARCH may be empty in that flow, causing broken URLs like
...linux-.tar.gz.

.ci/images/Dockerfile[6-72]
.ci/images/README[40-46]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Dockerfile assumes `TARGETARCH` is always provided by the builder, but the repo’s documented build flow uses plain `podman build` (no `--platform` / `--build-arg`). When `TARGETARCH` is empty, several downloads reference invalid URLs/paths and the build fails.

## Issue Context
- `ARG TARGETARCH` is declared but not defaulted.
- Multiple tool downloads use `${TARGETARCH}` in URLs and in extracted directory names.
- `.ci/images/README` documents a plain `podman build ... -f .ci/images/Dockerfile .` command.

## Fix Focus Areas
- Add a robust fallback for `TARGETARCH` (e.g., derive from `dpkg --print-architecture` when `TARGETARCH` is empty) and use that derived value consistently in the tool-download `RUN` blocks.
- Optionally update `.ci/images/README` to document `--platform` / `--build-arg TARGETARCH=...` for reproducibility.

### Suggested implementation sketch
In the tool install `RUN` block(s), compute a local variable:
```sh
ARCH="${TARGETARCH:-$(dpkg --print-architecture)}"
```
…and replace `linux-${TARGETARCH}` with `linux-${ARCH}`, and the `arm64` comparisons to use `${ARCH}`.

## Fix Focus Areas (exact locations)
- .ci/images/Dockerfile[6-72]
- .ci/images/README[40-46]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Runner pull breaks arm64 🐞 Bug ≡ Correctness
Description
e2e-tests/local-run.sh now pulls the runner image without --platform=linux/amd64, so on arm64
hosts Podman will try to pull an arm64 image/manifest for
quay.io/rhdh-community/rhdh-e2e-runner:main and can fail because the publishing workflow still
builds/pushes linux/amd64 only. This can block local e2e runs on arm64 machines until the image is
actually published as multi-arch.
Code

e2e-tests/local-run.sh[362]

+podman pull "$RUNNER_IMAGE"
Relevance

⭐⭐ Medium

local-run.sh changes often accepted, but no precedent on forcing --platform for podman pull.

PR-#4542

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The script pulls quay.io/.../rhdh-e2e-runner:main without a platform override, while the
build-and-push workflow explicitly builds only linux/amd64, so arm64 hosts may not find a matching
manifest/platform for that tag.

e2e-tests/local-run.sh[4-6]
e2e-tests/local-run.sh[360-363]
.github/workflows/push-e2e-runner.yaml[44-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`local-run.sh` no longer forces `linux/amd64` when pulling the runner image. However, the image build workflow currently publishes only `linux/amd64`, so arm64 hosts may fail to pull/run the default runner image tag.

## Issue Context
- `local-run.sh` defaults `RUNNER_IMAGE` to `quay.io/rhdh-community/rhdh-e2e-runner:main`.
- The push workflow sets `PLATFORM=linux/amd64` and builds only that platform.

## Fix Focus Areas
- Make the pull logic resilient: attempt a native pull first, and if it fails due to missing manifest/platform, retry with `--platform=linux/amd64` (or make platform a user-configurable flag with a safe default until multi-arch publishing exists).

### Suggested implementation sketch
```bash
if ! podman pull "$RUNNER_IMAGE"; then
 log::warn "Native-arch pull failed; retrying with --platform=linux/amd64"
 podman pull "$RUNNER_IMAGE" --platform=linux/amd64
fi
```

## Fix Focus Areas (exact locations)
- e2e-tests/local-run.sh[4-6]
- e2e-tests/local-run.sh[360-363]
- .github/workflows/push-e2e-runner.yaml[44-84]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Workflow ignores .yarn changes 🐞 Bug ☼ Reliability
Description
push-e2e-runner.yaml only triggers on .ci/images/Dockerfile and .yarnrc.yml, but the Docker
image build context explicitly includes .yarn/; changes to .yarn/** won’t rebuild/push the
runner image, so Quay can lag behind the repo state for Yarn artifacts included in the image.
Code

.github/workflows/push-e2e-runner.yaml[R4-14]

+  pull_request:
+    paths:
+      - '.ci/images/Dockerfile'
+      - '.yarnrc.yml'
  push:
    branches:
      - main
-      - 'release-1.*'
+      - 'release-*'
    paths:
      - '.ci/images/Dockerfile'
      - '.yarnrc.yml'
Evidence
The workflow path filters do not include .yarn/**, but the Dockerfile copies .yarn into the
image, meaning .yarn changes affect the built artifact without triggering rebuilds.

.github/workflows/push-e2e-runner.yaml[3-15]
.ci/images/Dockerfile[20-23]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The e2e-runner image build workflow triggers only when `.ci/images/Dockerfile` or `.yarnrc.yml` changes. However, the Dockerfile copies the `.yarn/` directory into the image, so changes under `.yarn/**` can change the produced image but won’t trigger a rebuild/push.

### Issue Context
This can lead to Quay publishing an image that doesn’t reflect the repo’s current `.yarn/` artifacts.

### Fix Focus Areas
- .github/workflows/push-e2e-runner.yaml[3-15]
- .ci/images/Dockerfile[20-23]

### Suggested fix
Add `.yarn/**` (or narrower `.yarn/releases/**` and `.yarn/patches/**`) to the `paths:` filters under both `pull_request` and `push` triggers.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Apt lists not cleaned ✓ Resolved 🐞 Bug ➹ Performance
Description
The skopeo/podman install layer runs apt-get update/apt-get install without removing
/var/lib/apt/lists/*, leaving package indexes in the final image layer and increasing image size.
Other install layers in this Dockerfile do clean these directories, so this is an unintended
regression.
Code

.ci/images/Dockerfile[R90-92]

+# Install skopeo and podman
RUN apt-get update -y && \
-    apt-get install -y skopeo
+    apt-get install -y --no-install-recommends skopeo podman
Relevance

⭐⭐ Medium

No historical evidence this repo enforces apt lists cleanup; only unrelated Dockerfile feedback
found.

PR-#4575

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The skopeo/podman installation step lacks the cleanup used elsewhere in the Dockerfile, which
leaves apt package list data behind in that layer.

.ci/images/Dockerfile[35-45]
.ci/images/Dockerfile[90-97]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The `apt-get update/install` layer for `skopeo` and `podman` does not remove `/var/lib/apt/lists/*`, so apt index files remain in the built image.

## Issue Context
Other apt-based install layers in the same Dockerfile clean `apt` lists and temporary directories; this one currently does not.

## Fix Focus Areas
- Add `apt-get clean` and `rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*` in the same `RUN` layer.

## Fix Focus Areas (exact locations)
- .ci/images/Dockerfile[90-93]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@github-actions

Copy link
Copy Markdown
Contributor

Image was built and published successfully. It is available at:

@zdrapela

Copy link
Copy Markdown
Member Author

/agentic_review

@rhdh-qodo-merge

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 27fcb80

@github-actions

Copy link
Copy Markdown
Contributor

The container image build workflow finished with status: cancelled.

@github-actions

Copy link
Copy Markdown
Contributor

The container image build workflow finished with status: cancelled.

@zdrapela zdrapela force-pushed the multiplatform-e2e-runner branch from d519eba to c6f5844 Compare June 30, 2026 11:19
@github-actions

Copy link
Copy Markdown
Contributor

The container image build workflow finished with status: cancelled.

@github-actions

Copy link
Copy Markdown
Contributor

Image was built and published successfully. It is available at:

@zdrapela

Copy link
Copy Markdown
Member Author

I believe the issues flagged by Qodo and SonarCloud aren't relevant.

  • Qodo - works fine in used environments, or already fixed.
  • SonarCloud - we need it for executing the E2E tests.

@zdrapela

zdrapela commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

/retest

zdrapela and others added 15 commits July 1, 2026 10:50
Bump OC client to 4.22.3 and install oc-mirror alongside oc for the upcoming disconnected CI job.

Co-authored-by: Cursor <cursoragent@cursor.com>
Parameterize all architecture-hardcoded tool downloads to support
building the e2e-runner image for both linux/amd64 and linux/arm64.

Changes:
- Pin base image to manifest list digest (supports both platforms)
- Add ARG TARGETARCH for dynamic arch resolution
- Helm, oc, oc-mirror, ocm-cli, yq, opm: use TARGETARCH in URLs
- AWS CLI: use $(uname -m) for native x86_64/aarch64 mapping
- umoci: upgrade v0.4.7 -> v0.6.0 (first version with arm64 binaries)
- Operator SDK: already multi-arch, unchanged
- Azure/GCloud/apt packages: already arch-agnostic, unchanged
- Remove unused Go env vars (GO_VERSION, GO_SHA256, GOPATH)
- local-run.sh: remove --platform=linux/amd64 from podman pull

Tested: both images build and all tools verified on both architectures.

Assisted-by: OpenCode
Add matrix strategy (ubuntu-24.04 + ubuntu-24.04-arm) to build the
e2e-runner image natively on both amd64 and arm64 runners. A merge
job assembles the per-arch digests into a multi-arch manifest list.

- build-image: matrix builds per-arch images, pushes arch-specific tags,
  exports digest as artifact
- merge: downloads digests, creates multi-arch manifest with
  docker buildx imagetools create, tags with branch and branch-sha

Assisted-by: OpenCode
Remove the downloaded zip and extracted aws/ directory after install
to reduce image size.

Assisted-by: OpenCode
Add apt-get clean and list removal to match all other apt-get install
blocks in the Dockerfile and reduce layer size.

Assisted-by: OpenCode
Pin the merge job to ubuntu-24.04 for consistency with the build jobs
instead of using ubuntu-latest.

Assisted-by: OpenCode
Add pull_request trigger so the e2e-runner image is built (without
pushing) on PRs that modify .ci/images/Dockerfile or .yarnrc.yml.
This catches build failures before merge.

- Add pull_request trigger with same path filters
- Guard push-only steps (login, digest export, merge) with event check
- Widen branch glob from 'release-1.*' to 'release-*' for future majors
- Use PR number in concurrency group and image tag

Assisted-by: OpenCode
Add -i/--runner-image CLI parameter to override the e2e runner
container image. Defaults to quay.io/rhdh-community/rhdh-e2e-runner:main.
Local images (localhost/ prefix) skip the podman pull step.

Assisted-by: OpenCode
…it.sh

- local-run.sh: remove -t from podman run flags. The -t (allocate TTY)
  is incompatible with piping through tee, causing a spurious exit
  code 127 when bash misparses continuation lines. The -i flag alone
  is sufficient.
- container-init.sh: use dpkg --print-architecture instead of
  hardcoded amd64 for the vault binary download, so arm64 containers
  get the native binary instead of relying on QEMU emulation.

Assisted-by: OpenCode
Re-add the localhost/ prefix check that was lost during rebase.
When using --runner-image localhost/..., skip the pull step since
the image is already available locally.

Assisted-by: OpenCode
Remove 2>/dev/null from podman pull so auth, network, and tag errors
are visible to the user when a pull fails.

Assisted-by: OpenCode
Add timeout-minutes: 20 to the merge job to prevent hangs on
registry hiccups. Aligns with the build-image job which already
has an explicit timeout.

Assisted-by: OpenCode
Use ${RUNNER_IMAGE:-default} so an exported env var is not silently
clobbered by the hardcoded default. The --runner-image CLI flag
still takes precedence over both.

Assisted-by: OpenCode
Document that -t (TTY allocation) is intentionally omitted because
stdout is piped through tee and CI has no TTY. Prevents future
contributors from adding it back.

Assisted-by: OpenCode
Add quay.expires-after=1w label to per-arch images so intermediate
tags (main-amd64, main-arm64, etc.) are automatically cleaned up
by Quay after one week. The multi-arch manifest tags are unaffected.

Assisted-by: OpenCode
@zdrapela zdrapela force-pushed the multiplatform-e2e-runner branch from a2108d1 to 524341e Compare July 1, 2026 08:51
@sonarqubecloud

sonarqubecloud Bot commented Jul 1, 2026

Copy link
Copy Markdown

Quality Gate Passed Quality Gate passed

Issues
1 New issue
1 Accepted issue

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Image was built and published successfully. It is available at:

@zdrapela

zdrapela commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

/retest

@zdrapela

zdrapela commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

/test e2e-ocp-helm

@rm3l

rm3l commented Jul 2, 2026

Copy link
Copy Markdown
Member

/override "SonarCloud Code Analysis"

Changes scoped to the E2E runner. Might make sense to explicitly exclude those E2E-related folders from SonarCloud analysis: https://github.com/redhat-developer/rhdh/blob/main/.sonarcloud.properties

@openshift-ci

openshift-ci Bot commented Jul 2, 2026

Copy link
Copy Markdown

@rm3l: Overrode contexts on behalf of rm3l: SonarCloud Code Analysis

Details

In response to this:

/override "SonarCloud Code Analysis"

Changes scoped to the E2E runner. Might make sense to explicitly exclude those E2E-related folders from SonarCloud analysis: https://github.com/redhat-developer/rhdh/blob/main/.sonarcloud.properties

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-merge-bot openshift-merge-bot Bot merged commit 830ac72 into redhat-developer:main Jul 2, 2026
26 checks passed
zdrapela added a commit to zdrapela/rhdh that referenced this pull request Jul 2, 2026
Both oc-mirror and podman are now pre-installed in the e2e-runner
image (PR redhat-developer#5036). Remove:
- disconnected::install_oc_mirror function and OC_MIRROR_BIN variable
- Runtime apt-get install podman block in operator handler
- Section lettering from both handlers

Assisted-by: OpenCode
zdrapela added a commit to zdrapela/rhdh that referenced this pull request Jul 4, 2026
Both oc-mirror and podman are now pre-installed in the e2e-runner
image (PR redhat-developer#5036). Remove:
- disconnected::install_oc_mirror function and OC_MIRROR_BIN variable
- Runtime apt-get install podman block in operator handler
- Section lettering from both handlers

Assisted-by: OpenCode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants