diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f09e1d3a9..4cf1fe8e25 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -210,58 +210,58 @@ jobs: if: matrix.arch == 'x86_64' - run: cargo +stable install cargo-careful if: matrix.profile == 'dev' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package hello_world - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package hello_world --uefi + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package hello_world qemu ${{ matrix.flags }} + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package hello_world qemu ${{ matrix.flags }} --uefi if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package wasmtime-demo --features ci + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package wasmtime-demo --features ci qemu ${{ matrix.flags }} if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package hello_world --no-default-features --microvm + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package hello_world --no-default-features qemu ${{ matrix.flags }} --microvm if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rusty_demo --features fs --virtiofsd + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package rusty_demo --features fs qemu ${{ matrix.flags }} --virtiofsd if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rusty_demo --features fs --virtiofsd --smp 4 + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package rusty_demo --features fs qemu ${{ matrix.flags }} --virtiofsd --smp 4 if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rusty_demo --features fs --virtiofsd --no-default-virtio-features + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package rusty_demo --features fs qemu ${{ matrix.flags }} --virtiofsd --no-default-virtio-features if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rusty_demo --features fs --virtiofsd --no-default-virtio-features --smp 4 + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package rusty_demo --features fs qemu ${{ matrix.flags }} --virtiofsd --no-default-virtio-features --smp 4 if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rusty_demo - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rusty_demo --smp 4 + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package rusty_demo qemu ${{ matrix.flags }} + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package rusty_demo qemu ${{ matrix.flags }} --smp 4 # https://github.com/hermit-os/kernel/issues/737 if: matrix.arch != 'aarch64' # https://github.com/hermit-os/kernel/issues/1286 continue-on-error: ${{ matrix.arch == 'riscv64' }} - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rusty_demo --smp 4 --uefi + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package rusty_demo qemu ${{ matrix.flags }} --smp 4 --uefi if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package rftrace-example --virtiofsd + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package rftrace-example qemu ${{ matrix.flags }} --virtiofsd if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package httpd --features ci,hermit/dhcpv4 --netdev virtio-net-pci + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev virtio-net-pci if: matrix.arch != 'riscv64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package httpd --features ci,hermit/dhcpv4 --netdev virtio-net-pci --no-default-virtio-features + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev virtio-net-pci --no-default-virtio-features if: matrix.arch != 'riscv64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package httpd --no-default-features --microvm --features ci,hermit/dhcpv4,hermit/tcp --netdev virtio-net-mmio + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --no-default-features --microvm --features ci,hermit/dhcpv4,hermit/tcp qemu ${{ matrix.flags }} --netdev virtio-net-mmio if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package httpd --features ci,hermit/dhcpv4 --netdev rtl8139 --features hermit/rtl8139 + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev rtl8139 --features hermit/rtl8139 if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package testudp --features hermit/udp,hermit/dhcpv4 --netdev virtio-net-pci + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package testudp --features hermit/udp,hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev virtio-net-pci if: matrix.arch != 'riscv64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package testudp --features hermit/udp,hermit/dhcpv4 --netdev rtl8139 --features hermit/rtl8139 + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package testudp --features hermit/udp,hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev rtl8139 --features hermit/rtl8139 if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package miotcp --features hermit/dhcpv4 --netdev virtio-net-pci + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package miotcp --features hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev virtio-net-pci if: matrix.arch != 'riscv64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package miotcp --features hermit/dhcpv4 --netdev rtl8139 --features hermit/rtl8139 + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package miotcp --features hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev rtl8139 --features hermit/rtl8139 if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package poll --features hermit/dhcpv4 --netdev virtio-net-pci + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package poll --features hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev virtio-net-pci if: matrix.arch != 'riscv64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package poll --features hermit/dhcpv4 --netdev rtl8139 --features hermit/rtl8139 + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package poll --features hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev rtl8139 --features hermit/rtl8139 if: matrix.arch == 'x86_64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package mioudp --features hermit/udp,hermit/dhcpv4 --netdev virtio-net-pci + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package mioudp --features hermit/udp,hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev virtio-net-pci if: matrix.arch != 'riscv64' - - run: cargo xtask ci qemu --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} ${{ matrix.flags }} --package mioudp --features hermit/udp,hermit/dhcpv4 --netdev rtl8139 --features hermit/rtl8139 + - run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package mioudp --features hermit/udp,hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev rtl8139 --features hermit/rtl8139 if: matrix.arch == 'x86_64' - - run: UHYVE=$CARGO_HOME/bin/uhyve cargo xtask ci uhyve --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --sudo --package rusty_demo + - run: UHYVE=$CARGO_HOME/bin/uhyve cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --sudo --package rusty_demo uhyve if: matrix.arch == 'x86_64' - - run: UHYVE=$CARGO_HOME/bin/uhyve cargo xtask ci uhyve --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --sudo --package rusty_demo --smp 4 + - run: UHYVE=$CARGO_HOME/bin/uhyve cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --sudo --package rusty_demo uhyve --smp 4 if: matrix.arch == 'x86_64' - - run: FIRECRACKER=$HOME/.local/bin/firecracker cargo xtask ci firecracker --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --sudo --package hello_world --no-default-features + - run: FIRECRACKER=$HOME/.local/bin/firecracker cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --sudo --package hello_world --no-default-features firecracker if: matrix.arch == 'x86_64' diff --git a/xtask/src/ci/firecracker.rs b/xtask/src/ci/firecracker.rs index 545ebc0296..daabbae759 100644 --- a/xtask/src/ci/firecracker.rs +++ b/xtask/src/ci/firecracker.rs @@ -5,30 +5,23 @@ use anyhow::Result; use clap::Args; use xshell::cmd; -use super::build::Build; - -/// Run hermit-rs images on Firecracker. +/// Run image on Firecracker. #[derive(Args)] pub struct Firecracker { /// Run Firecracker using `sudo`. #[arg(long)] sudo: bool, - - #[command(flatten)] - build: Build, } impl Firecracker { - pub fn run(mut self) -> Result<()> { - self.build.run()?; - + pub fn run(self, image: &Path, smp: usize) -> Result<()> { let sh = crate::sh()?; let config = format!( include_str!("firecracker_vm_config.json"), kernel_image_path = "hermit-loader-x86_64-fc", - initrd_path = self.build.image().display(), - vcpu_count = self.build.smp, + initrd_path = image.display(), + vcpu_count = smp, ); eprintln!("firecracker config"); eprintln!("{config}"); diff --git a/xtask/src/ci/mod.rs b/xtask/src/ci/mod.rs index f1d0fc4503..9632e95bf9 100644 --- a/xtask/src/ci/mod.rs +++ b/xtask/src/ci/mod.rs @@ -3,27 +3,21 @@ use std::path::Path; use anyhow::Result; use clap::Subcommand; -mod build; mod firecracker; mod qemu; +mod rs; mod uhyve; /// Run CI tasks. #[derive(Subcommand)] pub enum Ci { - Build(build::Build), - Firecracker(firecracker::Firecracker), - Qemu(qemu::Qemu), - Uhyve(uhyve::Uhyve), + Rs(rs::Rs), } impl Ci { pub fn run(self) -> Result<()> { match self { - Self::Build(mut build) => build.run(), - Self::Firecracker(firecracker) => firecracker.run(), - Self::Qemu(qemu) => qemu.run(), - Self::Uhyve(uhyve) => uhyve.run(), + Self::Rs(rs) => rs.run(), } } } diff --git a/xtask/src/ci/qemu.rs b/xtask/src/ci/qemu.rs index ef2057fc3c..c394a110b7 100644 --- a/xtask/src/ci/qemu.rs +++ b/xtask/src/ci/qemu.rs @@ -12,10 +12,9 @@ use sysinfo::{CpuRefreshKind, System}; use wait_timeout::ChildExt; use xshell::cmd; -use super::build::Build; use crate::arch::Arch; -/// Run hermit-rs images on QEMU. +/// Run image on QEMU. #[derive(Args)] pub struct Qemu { /// Enable hardware acceleration. @@ -45,9 +44,6 @@ pub struct Qemu { /// Enable the `virtiofsd` virtio-fs vhost-user device daemon. #[arg(long)] virtiofsd: bool, - - #[command(flatten)] - build: Build, } #[derive(ValueEnum, Clone, Copy)] @@ -58,33 +54,32 @@ pub enum NetworkDevice { } impl Qemu { - pub fn run(mut self) -> Result<()> { - self.build.run()?; - + pub fn run(self, image: &Path, smp: usize, arch: Arch, profile: &str) -> Result<()> { let sh = crate::sh()?; let virtiofsd = self.virtiofsd.then(spawn_virtiofsd).transpose()?; thread::sleep(Duration::from_millis(100)); - if self.build.package.contains("rftrace") { + let image_name = image.file_name().unwrap().to_str().unwrap(); + if image_name.contains("rftrace") { sh.create_dir("shared/tracedir")?; } - let arch = self.build.cargo_build.artifact.arch.name(); - let qemu = env::var("QEMU").unwrap_or_else(|_| format!("qemu-system-{arch}")); + let qemu = env::var("QEMU").unwrap_or_else(|_| format!("qemu-system-{}", arch.name())); let program = if self.sudo { "sudo" } else { qemu.as_str() }; let arg = self.sudo.then_some(qemu.as_str()); + let memory = self.memory(image_name, arch, profile); let qemu = cmd!(sh, "{program} {arg...}") .args(&["-display", "none"]) .args(&["-serial", "stdio"]) - .args(self.image_args()?) - .args(self.machine_args()) - .args(self.cpu_args()) - .args(&["-smp", &self.build.smp.to_string()]) - .args(self.memory_args()) + .args(self.image_args(image, arch)?) + .args(self.machine_args(arch)) + .args(self.cpu_args(arch)) + .args(&["-smp", &smp.to_string()]) + .args(&["-m".to_string(), format!("{memory}M")]) .args(self.netdev_args()) - .args(self.virtiofsd_args()); + .args(self.virtiofsd_args(memory)); eprintln!("$ {qemu}"); let mut qemu = KillChildOnDrop( @@ -96,13 +91,13 @@ impl Qemu { thread::sleep(Duration::from_millis(100)); if let Some(status) = qemu.0.try_wait()? { ensure!( - self.qemu_success(status), + self.qemu_success(status, arch), "QEMU exit code: {:?}", status.code() ); } - match self.build.package.as_str() { + match image_name { "httpd" => test_httpd()?, "testudp" => test_testudp()?, "miotcp" => test_miotcp()?, @@ -116,7 +111,7 @@ impl Qemu { bail!("QEMU timeout") }; ensure!( - self.qemu_success(status), + self.qemu_success(status, arch), "QEMU exit code: {:?}", status.code() ); @@ -126,23 +121,22 @@ impl Qemu { assert!(status.success()); } - if self.build.package.contains("rftrace") { - check_rftrace(&self.build.image())?; + if image_name.contains("rftrace") { + check_rftrace(image)?; } Ok(()) } - fn image_args(&self) -> Result> { - let arch = self.build.cargo_build.artifact.arch.name(); + fn image_args(&self, image: &Path, arch: Arch) -> Result> { let exe_suffix = if self.uefi { ".efi" } else { "" }; - let loader = format!("hermit-loader-{arch}{exe_suffix}"); + let loader = format!("hermit-loader-{}{exe_suffix}", arch.name()); let image_args = if self.uefi { let sh = crate::sh()?; sh.create_dir("target/esp/efi/boot")?; sh.copy_file(loader, "target/esp/efi/boot/bootx64.efi")?; - sh.copy_file(self.build.image(), "target/esp/efi/boot/hermit-app")?; + sh.copy_file(image, "target/esp/efi/boot/hermit-app")?; vec![ "-drive".to_string(), @@ -156,16 +150,16 @@ impl Qemu { ] } else { let mut image_args = vec!["-kernel".to_string(), loader]; - match self.build.cargo_build.artifact.arch { + match arch { Arch::X86_64 | Arch::Riscv64 => { image_args.push("-initrd".to_string()); - image_args.push(self.build.image().into_os_string().into_string().unwrap()); + image_args.push(image.to_str().unwrap().to_string()); } Arch::Aarch64 => { image_args.push("-device".to_string()); image_args.push(format!( "guest-loader,addr=0x48000000,initrd={}", - self.build.image().display() + image.display() )); } } @@ -175,7 +169,7 @@ impl Qemu { Ok(image_args) } - fn machine_args(&self) -> Vec { + fn machine_args(&self, arch: Arch) -> Vec { if self.microvm { let frequency = get_frequency(); vec![ @@ -189,9 +183,9 @@ impl Qemu { "-append".to_string(), format!("-freq {frequency}"), ] - } else if self.build.cargo_build.artifact.arch == Arch::Aarch64 { + } else if arch == Arch::Aarch64 { vec!["-machine".to_string(), "virt,gic-version=3".to_string()] - } else if self.build.cargo_build.artifact.arch == Arch::Riscv64 { + } else if arch == Arch::Riscv64 { vec![ "-machine".to_string(), "virt".to_string(), @@ -203,8 +197,8 @@ impl Qemu { } } - fn cpu_args(&self) -> Vec { - match self.build.cargo_build.artifact.arch { + fn cpu_args(&self, arch: Arch) -> Vec { + match arch { Arch::X86_64 => { let mut cpu_args = if self.accel { if cfg!(target_os = "linux") { @@ -242,11 +236,9 @@ impl Qemu { } } - fn memory(&self) -> usize { - if self.build.cargo_build.artifact.profile() == "release" - && self.build.package == "hello_world" - { - return match self.build.cargo_build.artifact.arch { + fn memory(&self, image_name: &str, arch: Arch, profile: &str) -> usize { + if profile == "release" && image_name == "hello_world" { + return match arch { Arch::X86_64 => { if self.uefi { 64 @@ -262,10 +254,6 @@ impl Qemu { 1024 } - fn memory_args(&self) -> [String; 2] { - ["-m".to_string(), format!("{}M", self.memory())] - } - fn netdev_args(&self) -> Vec { let Some(netdev) = self.netdev else { return vec![]; @@ -297,9 +285,8 @@ impl Qemu { netdev_args } - fn virtiofsd_args(&self) -> Vec { + fn virtiofsd_args(&self, memory: usize) -> Vec { if self.virtiofsd { - let memory = self.memory(); let default_virtio_features = if !self.no_default_virtio_features { ",packed=on" } else { @@ -320,8 +307,8 @@ impl Qemu { } } - fn qemu_success(&self, status: ExitStatus) -> bool { - if self.build.cargo_build.artifact.arch == Arch::X86_64 { + fn qemu_success(&self, status: ExitStatus, arch: Arch) -> bool { + if arch == Arch::X86_64 { status.code() == Some(3) } else { status.success() diff --git a/xtask/src/ci/build.rs b/xtask/src/ci/rs.rs similarity index 56% rename from xtask/src/ci/build.rs rename to xtask/src/ci/rs.rs index edc5bd08d2..5f57c47ad8 100644 --- a/xtask/src/ci/build.rs +++ b/xtask/src/ci/rs.rs @@ -1,14 +1,13 @@ use std::path::PathBuf; use anyhow::Result; -use clap::Args; +use clap::{Args, Subcommand}; use crate::cargo_build::CargoBuild; -/// Build hermit-rs images. +/// Work with hermit-rs images #[derive(Args)] -#[command(next_help_heading = "Build options")] -pub struct Build { +pub struct Rs { #[command(flatten)] pub cargo_build: CargoBuild, @@ -19,10 +18,38 @@ pub struct Build { /// Create multiple vCPUs. #[arg(long, default_value_t = 1)] pub smp: usize, + + #[command(subcommand)] + action: Action, +} + +#[derive(Subcommand)] +pub enum Action { + /// Build image. + Build, + Firecracker(super::firecracker::Firecracker), + Qemu(super::qemu::Qemu), + Uhyve(super::uhyve::Uhyve), } -impl Build { - pub fn run(&mut self) -> Result<()> { +impl Rs { + pub fn run(mut self) -> Result<()> { + let image = self.build()?; + + match self.action { + Action::Build => Ok(()), + Action::Firecracker(firecracker) => firecracker.run(&image, self.smp), + Action::Qemu(qemu) => qemu.run( + &image, + self.smp, + self.cargo_build.artifact.arch, + self.cargo_build.artifact.profile(), + ), + Action::Uhyve(uhyve) => uhyve.run(&image, self.smp), + } + } + + pub fn build(&mut self) -> Result { if super::in_ci() { eprintln!("::group::cargo build") } @@ -55,10 +82,6 @@ impl Build { eprintln!("::endgroup::") } - Ok(()) - } - - pub fn image(&self) -> PathBuf { - self.cargo_build.artifact.ci_image(&self.package) + Ok(self.cargo_build.artifact.ci_image(&self.package)) } } diff --git a/xtask/src/ci/uhyve.rs b/xtask/src/ci/uhyve.rs index fdd18d892f..941e5d7b1d 100644 --- a/xtask/src/ci/uhyve.rs +++ b/xtask/src/ci/uhyve.rs @@ -1,44 +1,31 @@ use std::env; +use std::path::Path; use anyhow::Result; use clap::Args; use xshell::cmd; -use super::build::Build; - -/// Run hermit-rs images on Uhyve. +/// Run image on Uhyve. #[derive(Args)] pub struct Uhyve { /// Run Uhyve using `sudo`. #[arg(long)] sudo: bool, - - #[command(flatten)] - build: Build, } impl Uhyve { - pub fn run(mut self) -> Result<()> { - self.build.run()?; - + pub fn run(self, image: &Path, smp: usize) -> Result<()> { let sh = crate::sh()?; - let image = self.build.image(); - let uhyve = env::var("UHYVE").unwrap_or_else(|_| "uhyve".to_string()); 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...} --verbose {image}") + cmd!(sh, "{program} {arg...} --verbose {smp_arg} {image}") .env("RUST_LOG", "debug") - .arg(self.cpu_count_arg()) .run()?; Ok(()) } - - fn cpu_count_arg(&self) -> String { - let smp = self.build.smp; - format!("--cpu-count={}", smp) - } }