Skip to content

Commit c5d6d59

Browse files
committed
fix(ci): preserve VM runtime embedding inputs
Closes #3038 Compress platform runtime inputs in Nix and stage the complete bundle outside Cargo's target directory. Reject missing or empty embedding artifacts during the driver build. Signed-off-by: Simon Scatton <sscatton@nvidia.com>
1 parent 69a05eb commit c5d6d59

4 files changed

Lines changed: 60 additions & 65 deletions

File tree

.github/workflows/build-vm-driver.yml

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,31 +67,17 @@ jobs:
6767
- name: Build VM runtime
6868
run: nix build .#vm-runtime
6969

70-
- name: Compress Linux VM runtime
71-
if: runner.os == 'Linux'
70+
- name: Assemble compressed VM runtime
7271
run: |
73-
install -d target/vm-runtime-compressed
74-
zstd -19 -T0 result/libkrun.so -o target/vm-runtime-compressed/libkrun.so.zst
75-
zstd -19 -T0 result/libkrunfw.so.5 -o target/vm-runtime-compressed/libkrunfw.so.5.zst
76-
zstd -19 -T0 result/gvproxy -o target/vm-runtime-compressed/gvproxy.zst
77-
zstd -19 -T0 result/umoci -o target/vm-runtime-compressed/umoci.zst
78-
79-
- name: Compress macOS VM runtime
80-
if: runner.os == 'macOS'
81-
run: |
82-
install -d target/vm-runtime-compressed
83-
zstd -19 -T0 result/libkrun.dylib -o target/vm-runtime-compressed/libkrun.dylib.zst
84-
zstd -19 -T0 result/libkrunfw.5.dylib -o target/vm-runtime-compressed/libkrunfw.5.dylib.zst
85-
zstd -19 -T0 result/gvproxy -o target/vm-runtime-compressed/gvproxy.zst
86-
zstd -19 -T0 result/umoci -o target/vm-runtime-compressed/umoci.zst
87-
88-
- name: Add openshell-sandbox to VM runtime
89-
run: zstd -19 -T0 sandbox/openshell-sandbox -o target/vm-runtime-compressed/openshell-sandbox.zst
72+
compressed_dir="${RUNNER_TEMP}/vm-runtime-compressed"
73+
install -d "$compressed_dir"
74+
cp result/compressed/*.zst "$compressed_dir/"
75+
zstd -19 -T1 sandbox/openshell-sandbox -o "$compressed_dir/openshell-sandbox.zst"
9076
9177
- name: Build openshell-driver-vm
9278
uses: ./.github/actions/build-rust-binary
9379
env:
94-
OPENSHELL_VM_RUNTIME_COMPRESSED_DIR: ${{ github.workspace }}/target/vm-runtime-compressed
80+
OPENSHELL_VM_RUNTIME_COMPRESSED_DIR: ${{ runner.temp }}/vm-runtime-compressed
9581
with:
9682
package: openshell-driver-vm
9783
binary: openshell-driver-vm

architecture/build.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,12 @@ Runtime layout:
174174
`/usr/libexec/openshell/openshell-driver-vm` in Linux packages and published
175175
as a release artifact. Linux GNU VM driver binaries must not reference
176176
`GLIBC_*` symbols newer than `GLIBC_2.28`; release workflows verify this
177-
before publishing artifacts.
177+
before publishing artifacts. Nix produces the platform-specific compressed
178+
runtime inputs. CI combines them with the matching supervisor artifact in a
179+
runner-temporary directory outside Cargo's `target/` before the shared Rust
180+
cache action runs. An explicitly configured VM runtime bundle is required to
181+
contain every non-empty embedding input; the driver build fails before
182+
packaging when an input is absent or empty.
178183
- **Supervisor**: Alpine base with `nftables`, static binary at
179184
`/openshell-sandbox` (musl by default; see `SUPERVISOR_LIBC` above). Static
180185
linkage keeps the binary usable when the image is mounted/extracted into

crates/openshell-driver-vm/build.rs

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,10 @@ fn main() {
6262
return;
6363
};
6464

65-
if !compressed_dir.is_dir() {
66-
println!(
67-
"cargo:warning=Compressed runtime dir not found: {}",
68-
compressed_dir.display()
69-
);
70-
println!("cargo:warning=Run: mise run vm:setup && mise run vm:supervisor");
71-
generate_stub_resources(
72-
&out_dir,
73-
&[
74-
&format!("{libkrun_name}.zst"),
75-
&format!("{libkrunfw_name}.zst"),
76-
"gvproxy.zst",
77-
"openshell-sandbox.zst",
78-
"umoci.zst",
79-
],
80-
);
81-
return;
82-
}
65+
assert!(compressed_dir.is_dir(),
66+
"Compressed runtime dir not found: {}. Run: mise run vm:setup && mise run vm:supervisor",
67+
compressed_dir.display()
68+
);
8369

8470
let files = [
8571
(format!("{libkrun_name}.zst"), format!("{libkrun_name}.zst")),
@@ -95,20 +81,28 @@ fn main() {
9581
("umoci.zst".to_string(), "umoci.zst".to_string()),
9682
];
9783

98-
let mut all_found = true;
84+
for (src_name, _) in &files {
85+
let src_path = compressed_dir.join(src_name);
86+
let metadata = fs::metadata(&src_path).unwrap_or_else(|e| {
87+
panic!(
88+
"Required compressed artifact unavailable: {}: {e}",
89+
src_path.display()
90+
)
91+
});
92+
assert!(metadata.is_file(),
93+
"Required compressed artifact is not a file: {}",
94+
src_path.display()
95+
);
96+
assert!(metadata.len() != 0,
97+
"Required compressed artifact is empty: {}",
98+
src_path.display()
99+
);
100+
}
101+
99102
for (src_name, dst_name) in &files {
100103
let src_path = compressed_dir.join(src_name);
101104
let dst_path = out_dir.join(dst_name);
102105

103-
if !src_path.exists() {
104-
println!(
105-
"cargo:warning=Missing compressed artifact: {}",
106-
src_path.display()
107-
);
108-
all_found = false;
109-
continue;
110-
}
111-
112106
if dst_path.exists() {
113107
let _ = fs::remove_file(&dst_path);
114108
}
@@ -123,22 +117,6 @@ fn main() {
123117
let size = fs::metadata(&dst_path).map_or(0, |m| m.len());
124118
println!("cargo:warning=Embedded {src_name}: {size} bytes");
125119
}
126-
127-
if !all_found {
128-
println!(
129-
"cargo:warning=Some artifacts missing. Run: mise run vm:setup && mise run vm:supervisor"
130-
);
131-
generate_stub_resources(
132-
&out_dir,
133-
&[
134-
&format!("{libkrun_name}.zst"),
135-
&format!("{libkrunfw_name}.zst"),
136-
"gvproxy.zst",
137-
"openshell-sandbox.zst",
138-
"umoci.zst",
139-
],
140-
);
141-
}
142120
}
143121

144122
fn generate_stub_resources(out_dir: &Path, names: &[&str]) {

nix/pkgs/vm-runtime.nix

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
{
55
fetchurl,
6+
lib,
67
stdenv,
78
zstd,
89
}:
@@ -13,14 +14,32 @@ let
1314
x86_64-linux = {
1415
platform = "linux-x86_64";
1516
hash = "sha256-dw3Lc7IapCyNeE7j6dnlgd/b8Yc91/7IOi3XJORyILQ=";
17+
artifacts = [
18+
"libkrun.so"
19+
"libkrunfw.so.5"
20+
"gvproxy"
21+
"umoci"
22+
];
1623
};
1724
aarch64-linux = {
1825
platform = "linux-aarch64";
1926
hash = "sha256-aJDuDb7AsuH9R+AyXA/JIxE9fJmZ5kP0Lkhg6F0Ot5A=";
27+
artifacts = [
28+
"libkrun.so"
29+
"libkrunfw.so.5"
30+
"gvproxy"
31+
"umoci"
32+
];
2033
};
2134
aarch64-darwin = {
2235
platform = "darwin-aarch64";
2336
hash = "sha256-BDSeY5XGDozaBZzHTiQQX90jzsSc6shJZs5zdzludX0=";
37+
artifacts = [
38+
"libkrun.dylib"
39+
"libkrunfw.5.dylib"
40+
"gvproxy"
41+
"umoci"
42+
];
2443
};
2544
}
2645
.${stdenv.hostPlatform.system};
@@ -41,6 +60,13 @@ stdenv.mkDerivation {
4160
mkdir -p "$out"
4261
tar --extract --file ${archive} --directory "$out"
4362
63+
mkdir -p "$out/compressed"
64+
for artifact in ${lib.escapeShellArgs runtime.artifacts}; do
65+
zstd -19 -T1 "$out/$artifact" -o "$out/compressed/$artifact.zst"
66+
test -s "$out/compressed/$artifact.zst"
67+
zstd --test --quiet "$out/compressed/$artifact.zst"
68+
done
69+
4470
runHook postInstall
4571
'';
4672
}

0 commit comments

Comments
 (0)