Skip to content

Commit 6355e70

Browse files
ci: verify each compute driver can be compiled out
Adds verify-drivers-compiled-out.sh, a mise task that exercises the per-driver Cargo features, and a matching step in the branch-checks workflow. The script mirrors verify-telemetry-compiled-out.sh: a table of stable driver-exclusive marker strings pulled from each driver crate, with present/absent/only modes. The 'only' mode asserts presence for a selected driver list AND absence for every other driver in one sweep, so a single script invocation covers both directions per build. The mise task exercises: default (all four drivers present), each single-driver build, one mixed feature set (docker+podman), and a zero-driver extension-only build that must link cleanly and must contain none of the four driver markers. After the zero-driver build the task also runs `cargo test -p openshell-server --lib --no-default-features` so the #[cfg]-gated extension-only unit tests actually execute in CI rather than being silently skipped by the default-features test job. The telemetry-off task uses a mixed --features driver-...,driver-... gateway build so the telemetry-marker absence check still exercises a representative in-tree-driver build path. Signed-off-by: Dimitar Mirchev <28221091+dimityrmirchev@users.noreply.github.com>
1 parent bbb1f6f commit 6355e70

7 files changed

Lines changed: 230 additions & 2 deletions

File tree

.github/workflows/branch-checks.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ jobs:
125125
- name: Verify telemetry can be compiled out
126126
run: mise run rust:verify:telemetry-off
127127

128+
- name: Verify each compute driver can be compiled out
129+
run: mise run rust:verify:drivers-off
130+
128131
- name: sccache stats
129132
if: always()
130133
run: |

crates/openshell-driver-docker/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
66
#![allow(clippy::result_large_err)]
77

8+
/// Compile-out guard: greppable proof this crate is linked into a binary.
9+
///
10+
/// `tasks/scripts/verify-drivers-compiled-out.sh` asserts this string is
11+
/// present when `--features driver-docker` is on and absent when it is
12+
/// off. `#[used]` prevents dead-code elimination; the linker cannot drop it.
13+
/// Do not remove without updating the verify script.
14+
#[used]
15+
static COMPILE_MARKER: &str = "OPENSHELL_DRIVER_MARKER:docker";
16+
817
use bollard::Docker;
918
use bollard::errors::Error as BollardError;
1019
use bollard::models::{

crates/openshell-driver-kubernetes/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,12 @@ pub use config::{
1111
};
1212
pub use driver::{KubernetesComputeDriver, KubernetesDriverError};
1313
pub use grpc::ComputeDriverService;
14+
15+
/// Compile-out guard: greppable proof this crate is linked into a binary.
16+
///
17+
/// `tasks/scripts/verify-drivers-compiled-out.sh` asserts this string is
18+
/// present when `--features driver-kubernetes` is on and absent when it is
19+
/// off. `#[used]` prevents dead-code elimination; the linker cannot drop it.
20+
/// Do not remove without updating the verify script.
21+
#[used]
22+
static COMPILE_MARKER: &str = "OPENSHELL_DRIVER_MARKER:kubernetes";

crates/openshell-driver-podman/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,12 @@ pub(crate) mod watcher;
1313
pub use config::PodmanComputeConfig;
1414
pub use driver::PodmanComputeDriver;
1515
pub use grpc::ComputeDriverService;
16+
17+
/// Compile-out guard: greppable proof this crate is linked into a binary.
18+
///
19+
/// `tasks/scripts/verify-drivers-compiled-out.sh` asserts this string is
20+
/// present when `--features driver-podman` is on and absent when it is
21+
/// off. `#[used]` prevents dead-code elimination; the linker cannot drop it.
22+
/// Do not remove without updating the verify script.
23+
#[used]
24+
static COMPILE_MARKER: &str = "OPENSHELL_DRIVER_MARKER:podman";

crates/openshell-server/src/compute/vm.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ use tonic::transport::Endpoint;
5656
#[cfg(unix)]
5757
use tower::service_fn;
5858

59+
/// Compile-out guard: greppable proof `driver-vm` is compiled in.
60+
///
61+
/// `tasks/scripts/verify-drivers-compiled-out.sh` asserts this string is
62+
/// present when `--features driver-vm` is on and absent when it is off.
63+
/// The VM driver runs out-of-process and has no in-server crate dependency,
64+
/// so this marker lives with the launcher plumbing gated by the feature.
65+
/// `#[used]` prevents dead-code elimination. Do not remove without
66+
/// updating the verify script.
67+
#[used]
68+
static COMPILE_MARKER: &str = "OPENSHELL_DRIVER_MARKER:vm";
69+
5970
const DRIVER_BIN_NAME: &str = "openshell-driver-vm";
6071
const COMPUTE_DRIVER_SOCKET_RUN_DIR: &str = "run";
6172
const COMPUTE_DRIVER_SOCKET_NAME: &str = "compute-driver.sock";

tasks/rust.toml

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,41 @@ run = [
3333
# markers, so the absent checks below can never become silently vacuous.
3434
"cargo build -p openshell-server --bin openshell-gateway",
3535
"tasks/scripts/verify-telemetry-compiled-out.sh present target/debug/openshell-gateway",
36-
# Guard: telemetry-free builds must contain no telemetry markers.
37-
"cargo build -p openshell-server --bin openshell-gateway --no-default-features",
36+
# Guard: telemetry-free builds must contain no telemetry markers. The
37+
# gateway needs at least one compute driver to link, so build with a
38+
# single-driver feature set that excludes telemetry.
39+
"cargo build -p openshell-server --bin openshell-gateway --no-default-features --features driver-kubernetes,driver-docker,driver-podman,driver-vm",
3840
"tasks/scripts/verify-telemetry-compiled-out.sh absent target/debug/openshell-gateway",
3941
"cargo build -p openshell-sandbox --bin openshell-sandbox --no-default-features",
4042
"tasks/scripts/verify-telemetry-compiled-out.sh absent target/debug/openshell-sandbox",
4143
]
44+
45+
["rust:verify:drivers-off"]
46+
description = "Verify each compute driver can be compiled out via per-driver cargo features"
47+
run = [
48+
# Positive control: the default build carries every driver's markers.
49+
"cargo build -p openshell-server --bin openshell-gateway",
50+
"tasks/scripts/verify-drivers-compiled-out.sh present all target/debug/openshell-gateway",
51+
52+
# Each single-driver build carries only that driver's markers.
53+
"cargo build -p openshell-server --bin openshell-gateway --no-default-features --features driver-kubernetes",
54+
"tasks/scripts/verify-drivers-compiled-out.sh only kubernetes target/debug/openshell-gateway",
55+
"cargo build -p openshell-server --bin openshell-gateway --no-default-features --features driver-docker",
56+
"tasks/scripts/verify-drivers-compiled-out.sh only docker target/debug/openshell-gateway",
57+
"cargo build -p openshell-server --bin openshell-gateway --no-default-features --features driver-podman",
58+
"tasks/scripts/verify-drivers-compiled-out.sh only podman target/debug/openshell-gateway",
59+
"cargo build -p openshell-server --bin openshell-gateway --no-default-features --features driver-vm",
60+
"tasks/scripts/verify-drivers-compiled-out.sh only vm target/debug/openshell-gateway",
61+
62+
# Mixed feature set: verifies driver features compose additively.
63+
"cargo build -p openshell-server --bin openshell-gateway --no-default-features --features driver-docker,driver-podman",
64+
"tasks/scripts/verify-drivers-compiled-out.sh only docker,podman target/debug/openshell-gateway",
65+
66+
# Zero-driver build is a valid extension-only gateway shape. Assert both
67+
# that the binary links and that none of the built-in driver markers survived.
68+
"cargo build -p openshell-server --bin openshell-gateway --no-default-features",
69+
"tasks/scripts/verify-drivers-compiled-out.sh absent all target/debug/openshell-gateway",
70+
# The zero-driver profile also gates the extension-only unit test paths. Run the library test
71+
# suite under --no-default-features so those assertions actually execute.
72+
"cargo test -p openshell-server --lib --no-default-features",
73+
]
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#!/usr/bin/env bash
2+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
# Verify whether compute-driver code is present in a compiled binary.
6+
#
7+
# Per-driver Cargo features (driver-kubernetes, driver-docker, driver-podman,
8+
# driver-vm) on openshell-server, all default-on, gate the driver crates and
9+
# their in-server plumbing. Building with --no-default-features and enabling
10+
# only a subset must produce a binary that carries only those drivers. This
11+
# guard inspects a built binary for markers that only exist when a given
12+
# driver is compiled in.
13+
#
14+
# Markers are strings baked into each driver's code and must not overlap
15+
# with other drivers or shared code. The `present` positive control fails
16+
# loudly if a marker goes stale, so `absent` checks can never become
17+
# silently vacuous.
18+
19+
set -euo pipefail
20+
21+
# Marker table: DRIVER=marker_that_only_appears_when_that_driver_is_compiled_in
22+
#
23+
# Each driver crate declares a `#[used] static COMPILE_MARKER` holding a
24+
# well-known byte string; the VM driver's marker lives in compute::vm behind
25+
# `#[cfg(feature = "driver-vm")]`. `#[used]` prevents dead-code elimination
26+
# so the marker survives every optimization level and strip mode. Keep these
27+
# in sync with the driver crates.
28+
declare -A MARKERS=(
29+
[kubernetes]="OPENSHELL_DRIVER_MARKER:kubernetes"
30+
[docker]="OPENSHELL_DRIVER_MARKER:docker"
31+
[podman]="OPENSHELL_DRIVER_MARKER:podman"
32+
[vm]="OPENSHELL_DRIVER_MARKER:vm"
33+
)
34+
35+
ALL_DRIVERS=(kubernetes docker podman vm)
36+
37+
usage() {
38+
cat >&2 <<'EOF'
39+
Usage:
40+
verify-drivers-compiled-out.sh present <driver|all> <binary>
41+
Assert the driver's markers ARE present. Use as a positive control.
42+
verify-drivers-compiled-out.sh absent <driver|all> <binary>
43+
Assert the driver's markers are NOT present.
44+
verify-drivers-compiled-out.sh only <driver[,driver...]> <binary>
45+
Assert markers are present for each listed driver AND absent for
46+
each unlisted one. Covers presence + absence in a single pass.
47+
48+
Drivers: kubernetes docker podman vm (or 'all')
49+
EOF
50+
}
51+
52+
if [[ $# -lt 3 ]]; then
53+
usage
54+
exit 2
55+
fi
56+
57+
mode=$1
58+
selector=$2
59+
binary=$3
60+
61+
if [[ ! -f $binary ]]; then
62+
echo "error: binary not found: $binary" >&2
63+
exit 2
64+
fi
65+
if ! command -v strings >/dev/null 2>&1; then
66+
echo "error: 'strings' (binutils) is required to inspect the binary" >&2
67+
exit 2
68+
fi
69+
70+
dump=$(strings -a "$binary")
71+
failed=0
72+
73+
# Assert that $1 marker appears at least once in $dump for driver $2.
74+
assert_present() {
75+
local driver=$1
76+
local marker=${MARKERS[$driver]}
77+
local count
78+
count=$(grep -c -F "$marker" <<<"$dump" || true)
79+
if [[ $count -eq 0 ]]; then
80+
echo "FAIL: driver '$driver' marker '$marker' missing from $(basename "$binary")" >&2
81+
failed=1
82+
else
83+
echo "OK: driver '$driver' compiled in ($count occurrence(s) of '$marker')"
84+
fi
85+
}
86+
87+
# Assert that $1 marker does NOT appear in $dump for driver $2.
88+
assert_absent() {
89+
local driver=$1
90+
local marker=${MARKERS[$driver]}
91+
local count
92+
count=$(grep -c -F "$marker" <<<"$dump" || true)
93+
if [[ $count -ne 0 ]]; then
94+
echo "FAIL: driver '$driver' marker '$marker' found in $(basename "$binary") ($count occurrence(s)); driver was not compiled out" >&2
95+
failed=1
96+
else
97+
echo "OK: driver '$driver' compiled out (0 occurrences of '$marker')"
98+
fi
99+
}
100+
101+
# Expand 'all' or a comma-separated list into the SELECTED array in the
102+
# caller's scope. Exits 2 on any unknown driver. Runs in the current shell
103+
# so that exit propagates — do not call this from a subshell or process
104+
# substitution.
105+
resolve_drivers() {
106+
local input=$1
107+
SELECTED=()
108+
if [[ $input == "all" ]]; then
109+
SELECTED=("${ALL_DRIVERS[@]}")
110+
return
111+
fi
112+
local drivers
113+
IFS=',' read -r -a drivers <<<"$input"
114+
for d in "${drivers[@]}"; do
115+
if [[ -z ${MARKERS[$d]+set} ]]; then
116+
echo "error: unknown driver '$d'. known: ${ALL_DRIVERS[*]}" >&2
117+
exit 2
118+
fi
119+
SELECTED+=("$d")
120+
done
121+
}
122+
123+
resolve_drivers "$selector"
124+
125+
case "$mode" in
126+
present)
127+
for d in "${SELECTED[@]}"; do
128+
assert_present "$d"
129+
done
130+
;;
131+
absent)
132+
for d in "${SELECTED[@]}"; do
133+
assert_absent "$d"
134+
done
135+
;;
136+
only)
137+
declare -A present_set=()
138+
for d in "${SELECTED[@]}"; do
139+
present_set[$d]=1
140+
done
141+
for d in "${ALL_DRIVERS[@]}"; do
142+
if [[ -n ${present_set[$d]+set} ]]; then
143+
assert_present "$d"
144+
else
145+
assert_absent "$d"
146+
fi
147+
done
148+
;;
149+
*)
150+
usage
151+
exit 2
152+
;;
153+
esac
154+
155+
exit "$failed"

0 commit comments

Comments
 (0)