Skip to content

Commit cec4402

Browse files
committed
Add a check for required binaries
- We require bwrap in the target container currently, make that clear. That needs to be done in the entrypoint shell script. - Once we're past that we're in Rust, so add infrastructure to verify that we have systemctl and objcopy for the UKI extraction. Signed-off-by: Colin Walters <[email protected]>
1 parent 2c3c056 commit cec4402

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed

Cargo.lock

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/kit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ strum = { version = "0.26", features = ["derive"] }
4949
quick-xml = "0.36"
5050
oci-spec = "0.8.2"
5151
sha2 = "0.10"
52+
which = "7.0"
5253

5354
[dev-dependencies]
5455
similar-asserts = "1.5"

crates/kit/scripts/entrypoint.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ set -euo pipefail
33

44
SELFEXE=/run/selfexe
55

6+
# Check for required binaries early
7+
if ! command -v bwrap &>/dev/null; then
8+
echo "Error: bwrap (bubblewrap) is currently required in the target container image" >&2
9+
exit 1
10+
fi
11+
612
# Shell script library
713
init_tmproot() {
814
if test -d /run/tmproot; then return 0; fi

crates/kit/src/run_ephemeral.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,29 @@ fn parse_service_exit_code(status_content: &str) -> Result<i32> {
700700
Ok(0)
701701
}
702702

703+
/// Check for required binaries in the target container image
704+
///
705+
/// These binaries must be present in the container image being run as an ephemeral VM.
706+
fn check_required_container_binaries() -> Result<()> {
707+
// We use systemctl in a few places. objcopy is for UKI extraction.
708+
let required_binaries = ["systemctl", "objcopy"];
709+
710+
let mut missing = Vec::new();
711+
712+
for binary in &required_binaries {
713+
if which::which(binary).is_err() {
714+
missing.push(format!("Missing required executable: {}", binary));
715+
}
716+
}
717+
718+
if !missing.is_empty() {
719+
return Err(eyre!("{}", missing.join("\n")));
720+
}
721+
722+
debug!("All required container binaries found");
723+
Ok(())
724+
}
725+
703726
/// VM execution inside container: extracts kernel/initramfs, starts virtiofsd processes,
704727
/// generates systemd mount units, sets up command execution, launches QEMU.
705728
pub(crate) async fn run_impl(opts: RunEphemeralOpts) -> Result<()> {
@@ -708,6 +731,9 @@ pub(crate) async fn run_impl(opts: RunEphemeralOpts) -> Result<()> {
708731

709732
debug!("Running QEMU implementation inside container");
710733

734+
// Check for required binaries in the target container image early
735+
check_required_container_binaries()?;
736+
711737
// Initialize status writer for supervisor monitoring
712738
let status_writer = StatusWriter::new("/run/supervisor-status.json");
713739
status_writer.update_state(SupervisorState::WaitingForSystemd)?;

0 commit comments

Comments
 (0)