Skip to content

Commit 9a01e1d

Browse files
committed
ci(e2e): add CentOS Stream 10 Docker/Podman/SELinux suite
PR NVIDIA#2092 adds SELinux relabeling (:z/:Z) support to the Docker and Podman driver bind mounts, but our existing E2E lanes run inside the Ubuntu-based ghcr.io/nvidia/openshell/ci container image, which does not enforce SELinux. That leaves the new relabeling behavior, and any future SELinux-sensitive change, without a host that can actually deny a mislabeled mount. Per the discussion on PR NVIDIA#2092 and the follow-up in NVIDIA#2093, add a Docker/Podman/SELinux compatibility suite backed by a CentOS Stream 10 VM booted under QEMU/KVM on the existing self-hosted linux-amd64-cpu8 runner (already used by driver-vm-linux.yml with --privileged). This needs no new runner class: it downloads a CentOS Stream 10 GenericCloud image, seeds it with cloud-init over a generated ISO, boots it under hardware-accelerated QEMU, and drives the guest entirely over SSH. Unlike the earlier attempt in NVIDIA#2093, VM creation lives in a standalone script (tasks/scripts/vm/centos-selinux-vm.sh) with create/status/ssh/ destroy subcommands instead of being embedded directly in the workflow YAML, wired up as mise run vm:centos-selinux:*. This lets a contributor reproduce the exact CI environment on their own machine to debug a SELinux/bind-mount issue without needing CI access. The script caches the downloaded base image and boots a copy-on-write overlay disk so repeated local runs don't re-download or mutate the cached image, and auto-detects KVM/HVF/TCG acceleration so it also runs (slowly) on non-KVM hosts such as a contributor's Mac. It also fixes a QEMU '-nographic cannot be used with -daemonize' incompatibility present in the prior attempt, found by actually booting a VM with the script. Once the guest is up, the workflow installs Docker Engine and Podman side by side, confirms SELinux is Enforcing, runs the standard e2e:docker and e2e:podman suites, and fails the job if the audit log shows AVC denials during the run. It is wired in as optional/ non-blocking via a new test:e2e-centos label, matching the existing test:e2e-kubernetes pattern. CI.md, CONTRIBUTING.md, and architecture/build.md are updated to document the new label and workflow. The centos-selinux-e2e and centos-selinux-e2e-result jobs in branch-e2e.yml unnecessarily depended on build-gateway, which the CentOS suite never uses (it only pulls the supervisor image). build-gateway only runs for run_core_e2e/run_kubernetes_ha_e2e, so when a PR carries only the test:e2e-centos label, build-gateway is skipped and GitHub's implicit success() check on needs skips centos-selinux-e2e in turn, tripping the always()-gated result job. Drop build-gateway from both jobs' needs so the suite runs correctly when only test:e2e-centos is applied. Signed-off-by: Eric Curtin <eric.curtin@docker.com>
1 parent 420a855 commit 9a01e1d

8 files changed

Lines changed: 811 additions & 8 deletions

File tree

.github/workflows/branch-e2e.yml

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
run_core_e2e: ${{ steps.labels.outputs.run_core_e2e }}
2525
run_gpu_e2e: ${{ steps.labels.outputs.run_gpu_e2e }}
2626
run_kubernetes_ha_e2e: ${{ steps.labels.outputs.run_kubernetes_ha_e2e }}
27+
run_centos_selinux_e2e: ${{ steps.labels.outputs.run_centos_selinux_e2e }}
2728
run_any_e2e: ${{ steps.labels.outputs.run_any_e2e }}
2829
steps:
2930
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
@@ -41,12 +42,14 @@ jobs:
4142
run_core_e2e=true
4243
run_gpu_e2e=true
4344
run_kubernetes_ha_e2e=true
45+
run_centos_selinux_e2e=true
4446
else
4547
run_core_e2e="$(jq -r 'index("test:e2e") != null' <<< "$LABELS_JSON")"
4648
run_gpu_e2e="$(jq -r 'index("test:e2e-gpu") != null' <<< "$LABELS_JSON")"
4749
run_kubernetes_ha_e2e="$(jq -r 'index("test:e2e-kubernetes") != null' <<< "$LABELS_JSON")"
50+
run_centos_selinux_e2e="$(jq -r 'index("test:e2e-centos") != null' <<< "$LABELS_JSON")"
4851
fi
49-
if [ "$run_core_e2e" = "true" ] || [ "$run_gpu_e2e" = "true" ] || [ "$run_kubernetes_ha_e2e" = "true" ]; then
52+
if [ "$run_core_e2e" = "true" ] || [ "$run_gpu_e2e" = "true" ] || [ "$run_kubernetes_ha_e2e" = "true" ] || [ "$run_centos_selinux_e2e" = "true" ]; then
5053
run_any_e2e=true
5154
else
5255
run_any_e2e=false
@@ -55,6 +58,7 @@ jobs:
5558
echo "run_core_e2e=$run_core_e2e"
5659
echo "run_gpu_e2e=$run_gpu_e2e"
5760
echo "run_kubernetes_ha_e2e=$run_kubernetes_ha_e2e"
61+
echo "run_centos_selinux_e2e=$run_centos_selinux_e2e"
5862
echo "run_any_e2e=$run_any_e2e"
5963
} >> "$GITHUB_OUTPUT"
6064
@@ -145,6 +149,16 @@ jobs:
145149
extra-helm-values: deploy/helm/openshell/ci/values-high-availability.yaml
146150
external-postgres-secret: openshell-ha-pg
147151

152+
centos-selinux-e2e:
153+
needs: [pr_metadata, build-supervisor]
154+
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_centos_selinux_e2e == 'true'
155+
permissions:
156+
contents: read
157+
packages: read
158+
uses: ./.github/workflows/e2e-centos-selinux.yml
159+
with:
160+
image-tag: ${{ github.sha }}
161+
148162
core-e2e-result:
149163
name: Core E2E result
150164
needs: [pr_metadata, build-gateway, build-supervisor, e2e, kubernetes-e2e]
@@ -225,3 +239,28 @@ jobs:
225239
fi
226240
done
227241
exit "$failed"
242+
243+
centos-selinux-e2e-result:
244+
name: CentOS Stream 10 SELinux E2E result
245+
needs: [pr_metadata, build-supervisor, centos-selinux-e2e]
246+
if: always() && needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_centos_selinux_e2e == 'true'
247+
runs-on: ubuntu-latest
248+
steps:
249+
- name: Verify CentOS Stream 10 SELinux E2E jobs
250+
env:
251+
BUILD_SUPERVISOR_RESULT: ${{ needs.build-supervisor.result }}
252+
CENTOS_SELINUX_E2E_RESULT: ${{ needs.centos-selinux-e2e.result }}
253+
run: |
254+
set -euo pipefail
255+
failed=0
256+
for item in \
257+
"build-supervisor:$BUILD_SUPERVISOR_RESULT" \
258+
"centos-selinux-e2e:$CENTOS_SELINUX_E2E_RESULT"; do
259+
name="${item%%:*}"
260+
result="${item#*:}"
261+
if [ "$result" != "success" ]; then
262+
echo "::error::$name concluded $result"
263+
failed=1
264+
fi
265+
done
266+
exit "$failed"

0 commit comments

Comments
 (0)