Skip to content
Open
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
9 changes: 8 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2024"

[features]
default = ["ci"]
ci = ["dep:libc", "dep:ovmf-prebuilt", "dep:sysinfo", "dep:ureq", "dep:vsock", "dep:wait-timeout"]
ci = ["dep:libc", "dep:ovmf-prebuilt", "dep:shlex", "dep:sysinfo", "dep:ureq", "dep:vsock", "dep:wait-timeout"]

[dependencies]
anyhow = "1.0"
Expand All @@ -14,6 +14,7 @@ goblin = { version = "0.10", default-features = false, features = ["archive", "e
home = "0.5"
libc = { version = "0.2", optional = true }
ovmf-prebuilt = { version = "0.2", optional = true }
shlex = { version = "2", optional = true }
sysinfo = { version = "0.39", optional = true }
ureq = { version = "3", default-features = false, features = ["rustls"], optional = true }
vsock = { version = "0.5", optional = true }
Expand Down
12 changes: 11 additions & 1 deletion xtask/src/ci/firecracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,32 @@ use anyhow::Result;
use clap::Args;
use xshell::cmd;

use crate::ci;

/// Run image on Firecracker.
#[derive(Args)]
pub struct Firecracker {
/// Run Firecracker using `sudo`.
#[arg(long)]
sudo: bool,

/// Arguments to pass to Firecracker and Hermit, separated by another `--`.
#[arg(last = true)]
firecracker_and_hermit_args: Vec<String>,
}

impl Firecracker {
pub fn run(self, image: &Path, smp: usize) -> Result<()> {
let sh = crate::sh()?;

let (firecracker_args, hermit_args) = ci::split_args(&self.firecracker_and_hermit_args);
let quoted_hermit_args = shlex::try_join(hermit_args.iter().map(AsRef::as_ref))?;

let config = format!(
include_str!("firecracker_vm_config.json"),
kernel_image_path = "hermit-loader-x86_64-fc",
initrd_path = image.display(),
boot_args = quoted_hermit_args,
vcpu_count = smp,
);
eprintln!("firecracker config");
Expand All @@ -39,7 +49,7 @@ impl Firecracker {
for run in 1.. {
let log_path = Path::new("firecracker.log");
sh.write_file(log_path, "")?;
let res = cmd!(sh, "{program} {arg...} --no-api --config-file {config_path} --log-path {log_path} --level Info --show-level --show-log-origin").run();
let res = cmd!(sh, "{program} {arg...} --no-api --config-file {config_path} --log-path {log_path} --level Info --show-level --show-log-origin {firecracker_args...}").run();
let log = sh.read_file(log_path)?;

eprintln!("firecracker log");
Expand Down
2 changes: 1 addition & 1 deletion xtask/src/ci/firecracker_vm_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"boot-source": {{
"kernel_image_path": "{kernel_image_path}",
"initrd_path": "{initrd_path}",
"boot_args": ""
"boot_args": "{boot_args}"
}},
"drives": [],
"machine-config": {{
Expand Down
7 changes: 7 additions & 0 deletions xtask/src/ci/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ fn in_ci() -> bool {
std::env::var_os("CI") == Some("true".into())
}

fn split_args<T: PartialEq<str>>(args: &[T]) -> (&[T], &[T]) {
match args.iter().position(|arg| arg == "--") {
Some(index) => (&args[..index], &args[index + 1..]),
None => (args, &[]),
}
}

pub fn parent_root() -> &'static Path {
crate::project_root().parent().unwrap()
}
16 changes: 14 additions & 2 deletions xtask/src/ci/qemu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use wait_timeout::ChildExt as _;
use xshell::cmd;

use crate::arch::Arch;
use crate::ci;

const DEFAULT_GUEST_IP: IpAddr = IpAddr::V4(Ipv4Addr::new(10, 0, 5, 3));

Expand Down Expand Up @@ -51,6 +52,10 @@ pub struct Qemu {
/// Use a TAP device for networking.
#[arg(long)]
tap: bool,

/// Arguments to pass to QEMU and Hermit, separated by another `--`.
#[arg(last = true)]
qemu_and_hermit_args: Vec<String>,
}

#[derive(ValueEnum, PartialEq, Eq, Clone, Copy)]
Expand Down Expand Up @@ -101,6 +106,8 @@ impl Qemu {
) -> Result<()> {
let sh = crate::sh()?;

let (qemu_args, hermit_args) = ci::split_args(&self.qemu_and_hermit_args);

let virtiofsd = self
.devices
.iter()
Expand Down Expand Up @@ -136,7 +143,8 @@ impl Qemu {
.args(&["-m".to_owned(), format!("{memory}M")])
.args(&["-global", "virtio-mmio.force-legacy=off"])
.args(self.device_args(memory))
.args(self.cmdline_args(image_name));
.args(qemu_args)
.args(self.cmdline_args(image_name, hermit_args));

eprintln!("$ {qemu}");
let mut qemu = Command::from(qemu);
Expand Down Expand Up @@ -482,10 +490,14 @@ impl Qemu {
.collect()
}

fn cmdline_args(&self, image_name: &str) -> Vec<String> {
fn cmdline_args(&self, image_name: &str, hermit_args: &[String]) -> Vec<String> {
let (user_kernel_args, user_app_args) = ci::split_args(hermit_args);

let mut cmdline = self.kernel_args();
cmdline.extend(user_kernel_args.iter().cloned());

let mut app_args = self.app_args(image_name);
app_args.extend(user_app_args.iter().cloned());
if !app_args.is_empty() {
cmdline.push("--".to_owned());
cmdline.append(&mut app_args);
Expand Down
15 changes: 12 additions & 3 deletions xtask/src/ci/uhyve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,29 @@ pub struct Uhyve {
/// Run Uhyve using `sudo`.
#[arg(long)]
sudo: bool,

/// Arguments to pass to Uhyve and Hermit, separated by another `--`.
#[arg(last = true)]
uhyve_and_hermit_args: Vec<String>,
}

impl Uhyve {
pub fn run(self, image: &Path, smp: usize) -> Result<()> {
let sh = crate::sh()?;

let uhyve_and_hermit_args = &self.uhyve_and_hermit_args[..];

let uhyve = env::var("UHYVE").unwrap_or_else(|_| "uhyve".to_owned());
let program = if self.sudo { "sudo" } else { uhyve.as_str() };
let arg = self.sudo.then_some(uhyve.as_str());
let smp_arg = format!("--cpu-count={smp}");

cmd!(sh, "{program} {arg...} {smp_arg} {image}")
.env("RUST_LOG", "debug")
.run()?;
cmd!(
Comment thread
mkroening marked this conversation as resolved.
sh,
"{program} {arg...} {smp_arg} {image} {uhyve_and_hermit_args...}"
)
.env("RUST_LOG", "debug")
.run()?;

Ok(())
}
Expand Down
Loading