Skip to content

Commit 3b79984

Browse files
committed
test(e2e): migrate community policy fixtures
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
1 parent 6b6d4fb commit 3b79984

7 files changed

Lines changed: 132 additions & 2 deletions

File tree

‎.audit/3388-public-policy-proto.tsv‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ ts phase decision why evidence result
4545
2026-09-19T06:48:30Z validation Validate standalone incremental L7 fragments with the same portable annotations as complete PolicyDocument payloads Incremental update messages reuse public L7 rules and binary selectors but do not contain a complete policy root, so root-only validation would let callers bypass required oneofs and string bounds openshell-policy-schema fragment validators; openshell-policy lowering; server ingress; Go SDK converter tests Direct API fragments now fail the same Protovalidate constraints before contextual lowering and merge validation
4646
2026-09-19T07:14:05Z boundary-hardening Validate complete provider and merged-policy documents before persistence, safely project JavaScript prototype-shaped parameter keys, and canonicalize legacy set-valued storage fields Final independent review found that per-fragment validation missed aggregate limits, TypeScript object inheritance could erase untrusted map keys, and stricter public uniqueness rules could reject status-only rewrites of older equivalent records provider mixed-batch and 1025-rule regressions; TypeScript __proto__/constructor regression; sandbox and provider durable rewrite regressions All write paths now fail before partial persistence, SDK projection retains every own key without prototype mutation, and legacy duplicate ports or matcher alternatives preserve their enforcement meaning
4747
2026-09-19T07:26:31Z build Add protobuf to the Nix development shell The pinned Rust Protovalidate runtime compiles its bundled constraint descriptor at build time; mise already provides protoc but the multi-architecture Rust CI shell did not x86_64-linux Branch Checks lint failure; prost-protovalidate-types 0.6.0 build script; mise and flake tool inventories Local and Nix-backed Rust builds now supply the same required descriptor compiler without changing runtime behavior
48+
2026-09-19T07:56:21Z e2e-fixture Adapt published community-image fixtures at the backend test boundary without accepting legacy YAML in production The external base image still embeds singular port fields; container-backed suites can derive and import a corrected image while VM and tmachine lifecycle suites can select an explicit minimal PolicyDocument e2e Dockerfile and Docker Podman Kubernetes launchers; VM policy fixture; tmachine conformance environment Image-policy discovery remains covered on container backends, registry-only suites remain deterministic, and the strict authored contract is unchanged
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# Minimal explicit policy for backend lifecycle suites that cannot consume the
5+
# locally migrated community-image fixture. Tests that need additional access
6+
# pass their own purpose-built policies.
7+
version: 1

‎e2e/docker/Dockerfile.external-kubernetes-gateway‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ FROM ${GATEWAY_BASE_IMAGE}
99
ARG TARGETARCH
1010
ARG SUPERVISOR_IMAGE=ghcr.io/nvidia/openshell/supervisor:latest
1111
ARG SANDBOX_RUNTIME_IMAGE=ghcr.io/nvidia/openshell/sandbox:latest
12+
ARG SANDBOX_IMAGE=ghcr.io/nvidia/openshell-community/sandboxes/base:latest
13+
ARG SANDBOX_IMAGE_PULL_POLICY=if_not_present
1214
COPY deploy/docker/.build/prebuilt-binaries/${TARGETARCH}/openshell-gateway /usr/local/bin/openshell-gateway
1315
COPY deploy/docker/.build/prebuilt-binaries/${TARGETARCH}/openshell-driver-kubernetes /usr/local/bin/openshell-driver-kubernetes
1416

@@ -17,8 +19,8 @@ ENV OPENSHELL_COMPUTE_DRIVER=kubernetes \
1719
OPENSHELL_GATEWAY_ID=openshell \
1820
OPENSHELL_SANDBOX_NAMESPACE=openshell \
1921
OPENSHELL_K8S_SANDBOX_SERVICE_ACCOUNT=openshell-sandbox \
20-
OPENSHELL_SANDBOX_IMAGE=ghcr.io/nvidia/openshell-community/sandboxes/base:latest \
21-
OPENSHELL_SANDBOX_IMAGE_PULL_POLICY=if_not_present \
22+
OPENSHELL_SANDBOX_IMAGE=${SANDBOX_IMAGE} \
23+
OPENSHELL_SANDBOX_IMAGE_PULL_POLICY=${SANDBOX_IMAGE_PULL_POLICY} \
2224
OPENSHELL_GRPC_ENDPOINT=http://openshell.openshell.svc.cluster.local:8080 \
2325
OPENSHELL_SUPERVISOR_IMAGE=${SUPERVISOR_IMAGE} \
2426
OPENSHELL_SUPERVISOR_IMAGE_PULL_POLICY=if_not_present \

‎e2e/rust/e2e-vm.sh‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ E2E_TEST_OVERRIDE="${OPENSHELL_E2E_VM_TEST:-}"
5353
E2E_FEATURES="${OPENSHELL_E2E_VM_FEATURES-e2e-vm}"
5454
SANDBOX_IMAGE="${OPENSHELL_SANDBOX_IMAGE:-${COMMUNITY_SANDBOX_IMAGE:-ghcr.io/nvidia/openshell-community/sandboxes/base:latest}}"
5555

56+
# The published community image predates the strict public PolicyDocument
57+
# contract. VM e2e pulls that image directly from its registry, so give the
58+
# lifecycle-oriented suite an explicit compatible policy instead of weakening
59+
# production parsing or requiring a local registry just for the fixture.
60+
export OPENSHELL_SANDBOX_POLICY="${OPENSHELL_SANDBOX_POLICY:-${ROOT}/e2e/configs/policy-document-default.yaml}"
61+
5662
# The VM driver places `compute-driver.sock` under `[openshell.drivers.vm].state_dir`.
5763
# AF_UNIX SUN_LEN is 104 bytes on macOS (108 on Linux), so paths anchored
5864
# in the workspace's `target/` blow the limit on typical developer

‎e2e/with-kube-gateway.sh‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
# Set OPENSHELL_E2E_KUBE_EXTRA_VALUES to one or more colon-separated Helm values
3232
# files, relative to the repository root or absolute, to layer additional chart
3333
# configuration on top of ci/values-skaffold.yaml.
34+
# Set OPENSHELL_E2E_KUBE_SANDBOX_IMAGE to test a non-default workload image. The
35+
# local kind/k3d path otherwise derives a strict PolicyDocument fixture from the
36+
# published community base image, whose baked policy predates that contract.
3437
#
3538
# Image source:
3639
# - Ephemeral k3d mode builds local
@@ -803,6 +806,33 @@ else
803806
fi
804807
REGISTRY_VALUE="${REGISTRY_VALUE%/}"
805808

809+
prepare_policy_document_community_image() {
810+
local source_image=$1
811+
local source_id source_digest fixture_image
812+
813+
echo "Refreshing latest sandbox image ${source_image}..." >&2
814+
docker pull "${source_image}" >&2
815+
source_id="$(docker image inspect --format '{{.Id}}' "${source_image}")"
816+
source_digest="${source_id#sha256:}"
817+
if ! [[ "${source_digest}" =~ ^[0-9a-f]{64}$ ]]; then
818+
echo "ERROR: could not resolve a stable image ID for ${source_image}." >&2
819+
return 1
820+
fi
821+
822+
fixture_image="openshell/e2e-community-base:policy-document-v1-${source_digest:0:12}"
823+
if ! docker image inspect "${fixture_image}" >/dev/null 2>&1; then
824+
echo "Preparing PolicyDocument E2E fixture from ${source_image}..." >&2
825+
docker build \
826+
--pull=false \
827+
--build-arg "BASE_IMAGE=${source_image}" \
828+
--file "${ROOT}/e2e/docker/Dockerfile.policy-document-community-base" \
829+
--tag "${fixture_image}" \
830+
"${ROOT}/e2e/docker" >&2
831+
fi
832+
833+
printf '%s\n' "${fixture_image}"
834+
}
835+
806836
# Resolve a host-gateway IP that sandbox pods can dial to reach test fixtures
807837
# running on the developer/CI host (HTTP fixtures bound to 0.0.0.0 plus sibling
808838
# Docker containers with published ports). The Helm chart wires this into pod
@@ -892,6 +922,26 @@ elif [[ "${KUBE_CONTEXT}" == k3d-* ]] && command -v k3d >/dev/null 2>&1; then
892922
import_cluster_name="${candidate}"
893923
fi
894924
fi
925+
926+
DEFAULT_SANDBOX_IMAGE="ghcr.io/nvidia/openshell-community/sandboxes/base:latest"
927+
KUBE_SANDBOX_IMAGE="${OPENSHELL_E2E_KUBE_SANDBOX_IMAGE:-${DEFAULT_SANDBOX_IMAGE}}"
928+
KUBE_SANDBOX_IMAGE_PULL_POLICY="${OPENSHELL_E2E_KUBE_SANDBOX_IMAGE_PULL_POLICY:-if_not_present}"
929+
POLICY_DOCUMENT_FIXTURE_IMAGE=""
930+
if [ "${KUBE_SANDBOX_IMAGE}" = "${DEFAULT_SANDBOX_IMAGE}" ]; then
931+
if [ -z "${import_cluster_name}" ] && ! [[ "${KUBE_CONTEXT}" == kind-* ]]; then
932+
echo "ERROR: the published community base image still contains a legacy policy." >&2
933+
echo " Set OPENSHELL_E2E_KUBE_SANDBOX_IMAGE to a PolicyDocument-compatible image for this cluster." >&2
934+
exit 2
935+
fi
936+
require_cmd docker
937+
POLICY_DOCUMENT_FIXTURE_IMAGE="$(prepare_policy_document_community_image "${KUBE_SANDBOX_IMAGE}")"
938+
export OPENSHELL_COMMUNITY_REGISTRY="openshell/e2e-community-sandboxes"
939+
KUBE_SANDBOX_IMAGE="${OPENSHELL_COMMUNITY_REGISTRY}/base:latest"
940+
docker image tag "${POLICY_DOCUMENT_FIXTURE_IMAGE}" "${KUBE_SANDBOX_IMAGE}"
941+
export OPENSHELL_E2E_COMMUNITY_BASE_IMAGE="${KUBE_SANDBOX_IMAGE}"
942+
KUBE_SANDBOX_IMAGE_PULL_POLICY=never
943+
fi
944+
895945
if [ "${OPENSHELL_E2E_KUBE_BUILD_IMAGES}" = "1" ]; then
896946
require_cmd docker
897947
echo "Building local Kubernetes e2e images (${REGISTRY_VALUE}/{gateway,sandbox,supervisor}:${IMAGE_TAG_VALUE})..."
@@ -925,6 +975,8 @@ if [ "${OPENSHELL_E2E_KUBE_BUILD_IMAGES}" = "1" ]; then
925975
--build-arg "TARGETARCH=${external_arch}" \
926976
--build-arg "SUPERVISOR_IMAGE=${REGISTRY_VALUE}/supervisor:${IMAGE_TAG_VALUE}" \
927977
--build-arg "SANDBOX_RUNTIME_IMAGE=${REGISTRY_VALUE}/sandbox:${IMAGE_TAG_VALUE}" \
978+
--build-arg "SANDBOX_IMAGE=${KUBE_SANDBOX_IMAGE}" \
979+
--build-arg "SANDBOX_IMAGE_PULL_POLICY=${KUBE_SANDBOX_IMAGE_PULL_POLICY}" \
928980
--tag "${REGISTRY_VALUE}/gateway:${IMAGE_TAG_VALUE}" \
929981
--file "${ROOT}/e2e/docker/Dockerfile.external-kubernetes-gateway" \
930982
"${ROOT}"
@@ -983,6 +1035,20 @@ elif [ "${OPENSHELL_E2E_KUBE_BUILD_IMAGES}" = "1" ] \
9831035
kind load docker-image "${image}" --name "${kind_cluster_name}"
9841036
done
9851037
fi
1038+
if [ -n "${POLICY_DOCUMENT_FIXTURE_IMAGE}" ]; then
1039+
if [ -n "${import_cluster_name}" ]; then
1040+
echo "Importing ${KUBE_SANDBOX_IMAGE} into k3d cluster ${import_cluster_name}..."
1041+
k3d image import "${KUBE_SANDBOX_IMAGE}" --cluster "${import_cluster_name}" \
1042+
--mode direct >/dev/null
1043+
elif [[ "${KUBE_CONTEXT}" == kind-* ]] && command -v kind >/dev/null 2>&1; then
1044+
kind_cluster_name="${KUBE_CONTEXT#kind-}"
1045+
echo "Loading ${KUBE_SANDBOX_IMAGE} into kind cluster ${kind_cluster_name}..."
1046+
kind load docker-image "${KUBE_SANDBOX_IMAGE}" --name "${kind_cluster_name}"
1047+
else
1048+
echo "ERROR: cannot load the PolicyDocument sandbox fixture into ${KUBE_CONTEXT}." >&2
1049+
exit 2
1050+
fi
1051+
fi
9861052

9871053
# The Kubernetes compute driver creates and watches Sandbox CRs reconciled
9881054
# by the upstream agent-sandbox-controller. Without the CRD + controller,
@@ -1009,6 +1075,8 @@ fi
10091075
helm_extra_args=()
10101076
helm_post_renderer_args=()
10111077
helm_extra_args+=(--set "server.telemetryEnabled=${OPENSHELL_TELEMETRY_ENABLED}")
1078+
helm_extra_args+=(--set "server.sandboxImage=${KUBE_SANDBOX_IMAGE}")
1079+
helm_extra_args+=(--set "server.sandboxImagePullPolicy=${KUBE_SANDBOX_IMAGE_PULL_POLICY}")
10121080
if [ "${OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER:-0}" = "1" ]; then
10131081
if [ "${OPENSHELL_E2E_KUBE_BUILD_IMAGES}" != "1" ]; then
10141082
echo "ERROR: external Kubernetes driver e2e requires OPENSHELL_E2E_KUBE_BUILD_IMAGES=1." >&2

‎e2e/with-podman-gateway.sh‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,31 @@ ensure_podman_supervisor_image() {
474474
exit 2
475475
}
476476

477+
prepare_policy_document_community_image() {
478+
local source_image=$1
479+
local source_id source_digest fixture_image
480+
481+
source_id="$(podman_cmd image inspect --format '{{.Id}}' "${source_image}")"
482+
source_digest="${source_id#sha256:}"
483+
if ! [[ "${source_digest}" =~ ^[0-9a-f]{64}$ ]]; then
484+
echo "ERROR: could not resolve a stable image ID for ${source_image}." >&2
485+
return 1
486+
fi
487+
488+
fixture_image="openshell/e2e-community-base:policy-document-v1-${source_digest:0:12}"
489+
if ! podman_cmd image exists "${fixture_image}" 2>/dev/null; then
490+
echo "Preparing PolicyDocument E2E fixture from ${source_image}..." >&2
491+
podman_cmd build \
492+
--pull=never \
493+
--build-arg "BASE_IMAGE=${source_image}" \
494+
--file "${ROOT}/e2e/docker/Dockerfile.policy-document-community-base" \
495+
--tag "${fixture_image}" \
496+
"${ROOT}/e2e/docker" >&2
497+
fi
498+
499+
printf '%s\n' "${fixture_image}"
500+
}
501+
477502
ensure_podman_sandbox_runtime_image() {
478503
local image=$1
479504

@@ -629,6 +654,12 @@ if ! podman_cmd image exists "${SANDBOX_IMAGE_REQUEST}" 2>/dev/null; then
629654
echo "Pulling ${SANDBOX_IMAGE_REQUEST}..."
630655
podman_cmd pull "${SANDBOX_IMAGE_REQUEST}"
631656
fi
657+
if [ "${SANDBOX_IMAGE_REQUEST}" = "${DEFAULT_SANDBOX_IMAGE}" ]; then
658+
SANDBOX_IMAGE_REQUEST="$(prepare_policy_document_community_image "${SANDBOX_IMAGE_REQUEST}")"
659+
export OPENSHELL_E2E_COMMUNITY_BASE_IMAGE="${SANDBOX_IMAGE_REQUEST}"
660+
export OPENSHELL_COMMUNITY_REGISTRY="openshell/e2e-community-sandboxes"
661+
podman_cmd tag "${SANDBOX_IMAGE_REQUEST}" "${OPENSHELL_COMMUNITY_REGISTRY}/base:latest"
662+
fi
632663
SANDBOX_IMAGE_ID="$(podman_cmd image inspect --format '{{.Id}}' "${SANDBOX_IMAGE_REQUEST}")"
633664
SANDBOX_IMAGE_ID="${SANDBOX_IMAGE_ID#sha256:}"
634665
SANDBOX_IMAGE_DIGEST="$(podman_cmd image inspect --format '{{.Digest}}' "${SANDBOX_IMAGE_REQUEST}")"

‎tests/ansible/playbooks/conformance/cli.yaml‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@
3939
- conformance_archive.stat.isreg | default(false)
4040
fail_msg: OpenShell conformance test bundle did not contain tests.tar.zst
4141

42+
# The published community image still contains the legacy singular `port`
43+
# policy field. This suite validates CLI lifecycle behavior, so provide a
44+
# minimal current PolicyDocument explicitly and keep production parsing
45+
# strict. Container-backed e2e suites separately cover image policy loading.
46+
- name: Install PolicyDocument conformance fixture
47+
become: true
48+
ansible.builtin.copy:
49+
content: |
50+
version: 1
51+
dest: /var/lib/openshell-conformance/policy-document-default.yaml
52+
owner: tmachine
53+
group: tmachine
54+
mode: "0600"
55+
4256
- name: Run OpenShell conformance archive
4357
ansible.builtin.command:
4458
argv:
@@ -52,6 +66,7 @@
5266
- --no-capture
5367
environment:
5468
OPENSHELL_BIN: /usr/local/bin/openshell
69+
OPENSHELL_SANDBOX_POLICY: /var/lib/openshell-conformance/policy-document-default.yaml
5570
register: conformance_result
5671
changed_when: false
5772
failed_when: false

0 commit comments

Comments
 (0)