Skip to content
Draft
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
4 changes: 4 additions & 0 deletions .agents/skills/debug-openshell-cluster/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ When `userns` is configured (e.g. `userns = "auto"` or `userns = "keep-id"`):
rootful Podman uses absolute host IDs (e.g. `uidmap = ["0:1000:1", "1:100000:65536"]`).
- `nomap` (without hyphen) is accepted as input but canonicalized to `no-map`
for Podman's API.
- A workload remains in `stopping` until Podman resorts to `SIGKILL`: inspect
supervisor logs for `failed to signal entrypoint process group`. The
supervisor must retain `CAP_KILL` so its root process can forward `SIGTERM`
to a workload that runs as the sandbox user.

### Step 6: Check Kubernetes Helm Gateways

Expand Down
37 changes: 36 additions & 1 deletion .agents/skills/test-release-canary/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The Release Canary (`.github/workflows/release-canary.yml`) smoke-tests the arti
|---|---|---|
| `macos` | `macos-latest-xlarge` | `install.sh` resolves the Homebrew formula, brew installs the cask, and `openshell status` reaches the brew-services–backed local gateway with the VM driver. |
| `ubuntu` | `ubuntu-latest` | `install.sh` installs the Debian package, the post-install systemd user service starts, and `openshell status` reaches the local gateway with the Docker driver. |
| `fedora` | `fedora:latest` container | `install.sh` installs the RPM packages, the local gateway starts under Podman, and `openshell status` succeeds. |
| `fedora` | `linux-amd64-cpu8` + Fedora Nix VM | `install.sh` installs the RPM packages, the root-owned local gateway starts with rootful Podman, and `openshell status` succeeds. |
| `kubernetes` | `ubuntu-latest` + kind | `helm install oci://ghcr.io/nvidia/openshell/helm-chart --version 0.0.0-dev` succeeds in a kind cluster, the gateway pod becomes Ready, port-forward exposes 8080, and the released CLI registers the in-cluster gateway and runs `openshell status` against it. |

All canary jobs disable anonymous OpenShell telemetry. Host package jobs inject
Expand Down Expand Up @@ -116,6 +116,41 @@ Swap `0.0.0-dev` for `0.0.0-dev.<sha>` to pin to a specific dev build. Tear down

Loopback registration auto-derives the gateway name to `openshell` if `--name` is omitted, which collides with the `install.sh`-installed local gateway — always pass `--name kind` (or another distinct name) when registering in addition to a local install.

## Local Fedora reproduction

The `fedora` job uses the repository's Nix test-guest harness instead of
running Fedora inside Docker. It can be reproduced on a Linux host with Nix,
KVM, and the repository checkout:

```shell
export INSTALL_SH_URL="https://raw.githubusercontent.com/NVIDIA/OpenShell/$(git rev-parse HEAD)/install.sh"
nix run .#test-guest -- \
--distro fedora \
--with podman-rootful \
-- \
sudo env \
SUDO_USER=root \
HOME=/root \
XDG_RUNTIME_DIR=/run/user/0 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus \
OPENSHELL_TELEMETRY_ENABLED=false \
INSTALL_SH_URL="$INSTALL_SH_URL" \
bash -s <<'EOF'
set -euo pipefail
mkdir -p "${XDG_RUNTIME_DIR}"
chmod 700 "${XDG_RUNTIME_DIR}"
systemctl start user-runtime-dir@0.service || true
systemctl start user@0.service
systemctl --user daemon-reload
mkdir -p "${HOME}/.config/openshell"
printf 'OPENSHELL_DRIVERS=podman\nOPENSHELL_PODMAN_SOCKET=/run/podman/podman.sock\nOPENSHELL_TELEMETRY_ENABLED=%s\n' \
"$OPENSHELL_TELEMETRY_ENABLED" > "${HOME}/.config/openshell/gateway.env"
podman --url unix:///run/podman/podman.sock info
curl -LsSf "${INSTALL_SH_URL}" | sh
openshell status
EOF
```

## Diagnosing failures

| Symptom | Likely cause | Where to look |
Expand Down
126 changes: 0 additions & 126 deletions .github/actions/setup-e2e-podman/action.yml

This file was deleted.

27 changes: 27 additions & 0 deletions .github/actions/setup-e2e-sandbox/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

name: Setup E2E Sandbox
description: Download an architecture-matched prebuilt OpenShell sandbox binary for E2E tests

runs:
using: composite
steps:
- name: Download prebuilt sandbox
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ runner.arch == 'X64' && 'openshell-sandbox-x86_64-unknown-linux-musl' || 'openshell-sandbox-aarch64-unknown-linux-musl' }}
path: .e2e/prebuilt-sandbox

- name: Configure prebuilt sandbox
shell: bash
run: | # zizmor: ignore[github-env] persists only a trusted runner-derived path
set -euo pipefail
sandbox="$GITHUB_WORKSPACE/.e2e/prebuilt-sandbox/openshell-sandbox"
if [[ ! -f "$sandbox" ]]; then
echo "downloaded artifact is missing $sandbox" >&2
exit 1
fi
chmod +x "$sandbox"
"$sandbox" --version
echo "OPENSHELL_SANDBOX_BIN=$sandbox" >> "$GITHUB_ENV"
121 changes: 87 additions & 34 deletions .github/workflows/branch-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,17 @@ jobs:
cargo-version: ${{ needs.version.outputs.cargo }}
secrets: inherit

build-rpm:
needs: [pr_metadata, version, build-cli, build-gateway]
if: needs.pr_metadata.outputs.run_core_e2e == 'true'
permissions:
contents: read
uses: ./.github/workflows/rpm-package.yml
with:
checkout-ref: ${{ github.sha }}
cargo-version: ${{ needs.version.outputs.cargo }}
secrets: inherit

build-gateway-plain:
needs: [pr_metadata, version]
if: needs.pr_metadata.outputs.run_core_e2e == 'true'
Expand Down Expand Up @@ -168,22 +179,6 @@ jobs:
interpreter: /lib/ld-linux-aarch64.so.1
secrets: inherit

build-driver-podman:
needs: [pr_metadata, version]
if: needs.pr_metadata.outputs.run_core_e2e == 'true'
permissions:
contents: read
uses: ./.github/workflows/build-binaries.yml
with:
package: openshell-driver-podman
binary: openshell-driver-podman
triple: x86_64-unknown-linux-gnu
runner: linux-amd64-cpu8
dev-shell: .#devShells.x86_64-linux.glibc-2-28
cargo-version: ${{ needs.version.outputs.cargo }}
interpreter: /lib64/ld-linux-x86-64.so.2
secrets: inherit

build-driver-kubernetes:
needs: [pr_metadata, version]
if: needs.pr_metadata.outputs.run_core_e2e == 'true'
Expand Down Expand Up @@ -253,16 +248,89 @@ jobs:
runner: linux-arm64-cpu8

podman-e2e:
needs: [pr_metadata, build-cli, build-gateway, build-supervisor-image]
needs: [pr_metadata, build-cli, build-gateway, build-sandbox]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/e2e-podman-test.yml

podman-fedora-rootful-e2e:
needs: [pr_metadata, build-cli, build-gateway, build-sandbox]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/e2e-podman-test.yml
with:
image-tag: ${{ github.sha }}
test-name: rust-podman-rootful, Fedora Nix VM
distro: fedora
configuration: podman-rootful
guest-gateway-user: root
gateway-config: e2e/configs/gateway/podman-rootful.toml
tests-in-vm: false
suite: sandbox_lifecycle

podman-fedora-rootful-rpm:
name: RPM install (rootful Podman, Fedora Nix VM)
needs: [pr_metadata, build-rpm]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
permissions:
actions: read
contents: read
packages: read
runs-on: linux-amd64-cpu8
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}

- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
with:
name: openshell

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: rpm-linux-x86_64
path: package-input

- name: Install PR RPMs and start rootful Podman gateway
run: |
set -euo pipefail

nix run .#test-guest -- \
--distro fedora \
--with podman-rootful \
--install package-input/openshell-[0-9]*.rpm \
--install package-input/openshell-gateway-*.rpm \
-- \
sudo env \
SUDO_USER=root \
HOME=/root \
XDG_RUNTIME_DIR=/run/user/0 \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus \
OPENSHELL_TELEMETRY_ENABLED=false \
bash -s <<'EOF'
set -euo pipefail
mkdir -p "${XDG_RUNTIME_DIR}"
chmod 700 "${XDG_RUNTIME_DIR}"
systemctl start user-runtime-dir@0.service || true
systemctl start user@0.service
systemctl --user daemon-reload
mkdir -p "${HOME}/.config/openshell"
printf 'OPENSHELL_DRIVERS=podman\nOPENSHELL_PODMAN_SOCKET=/run/podman/podman.sock\nOPENSHELL_TELEMETRY_ENABLED=%s\n' \
"$OPENSHELL_TELEMETRY_ENABLED" > "${HOME}/.config/openshell/gateway.env"
podman --url unix:///run/podman/podman.sock info
systemctl --user enable --now openshell-gateway
openshell status
EOF
vm-e2e:
needs: [pr_metadata, build-cli, build-gateway, build-vm-driver]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
Expand All @@ -288,21 +356,6 @@ jobs:
suite-matrix: >-
[{"suite":"external-driver","cmd":"mise run --no-deps --skip-deps e2e:docker:external-driver","apt_packages":"openssh-client","python_proto":false,"mcp":false}]

podman-external-driver-e2e:
needs: [pr_metadata, build-cli, build-gateway-plain, build-driver-podman, build-supervisor-image]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/e2e-podman-test.yml
with:
image-tag: ${{ github.sha }}
gateway-artifact: openshell-gateway-plain-x86_64-unknown-linux-gnu
external-driver-binary: openshell-driver-podman
suite-matrix: >-
[{"suite":"external-driver","runner":"ubuntu-26.04","podman_major":"5","podman_package_version":"5.7.0+ds2-3build1","conmon_package_version":"2.1.13+ds1-2","cmd":"mise run --no-deps --skip-deps e2e:podman:external-driver"}]

vm-external-driver-e2e:
needs: [pr_metadata, build-cli, build-gateway-plain, build-vm-driver]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
Expand Down Expand Up @@ -428,7 +481,7 @@ jobs:

core-e2e-result:
name: Core E2E result
needs: [pr_metadata, docker-e2e, podman-e2e, vm-e2e, docker-external-driver-e2e, podman-external-driver-e2e, vm-external-driver-e2e, kubernetes-e2e, kubernetes-external-driver-e2e, kubernetes-workspace-managed-e2e, kubernetes-workspace-operator-e2e]
needs: [pr_metadata, docker-e2e, podman-e2e, podman-fedora-rootful-e2e, podman-fedora-rootful-rpm, vm-e2e, docker-external-driver-e2e, vm-external-driver-e2e, kubernetes-e2e, kubernetes-external-driver-e2e, kubernetes-workspace-managed-e2e, kubernetes-workspace-operator-e2e]
if: always() && needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
runs-on: ubuntu-latest
steps:
Expand Down
Loading
Loading