use crate::Config;
pub(crate) fn blk_device_name(index: usize) -> String {
let letter = (b'a' + index as u8) as char;
format!("vd{letter}")
}
pub(crate) fn build(config: &Config, effective_vsock_port: Option<u32>) -> String {
let mut s = config.cmdline.clone();
s.push_str(" vmette.boot=ctl");
if let Some(port) = effective_vsock_port {
s.push_str(&format!(" vmette.vsock_port={}", port));
}
s
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
fn base() -> Config {
Config::new("/k", "/i")
}
#[test]
fn empty_cmdline_appends_only_boot_token() {
let s = build(&base(), None);
assert_eq!(s, "console=hvc0 quiet vmette.boot=ctl");
}
#[test]
fn no_legacy_vmette_tokens_emitted() {
let mut c = base();
c.exec_cmd = Some("echo hi".into());
c.rootfs = Some(crate::Rootfs::Share(crate::RootfsShare {
path: PathBuf::from("/r"),
read_only: true,
}));
c.shares = vec![crate::ShareMount {
tag: "work".into(),
path: PathBuf::from("/w"),
}];
c.env = vec![("FOO".into(), "bar".into())];
c.switch_root = true;
c.net = true;
c.workload = crate::WorkloadStrategy::Agent;
let s = build(&c, Some(5000));
for token in [
"vmette.exec",
"vmette.rootfs",
"vmette.rootfs_block",
"vmette.rootfs_ro",
"vmette.scratch_dev",
"vmette.share=",
"vmette.switch_root",
"vmette.net",
"vmette.desktop",
"vmette.display",
"vmette.env",
"vmette.snapshot_mode",
] {
assert!(!s.contains(token), "leaked legacy token {token}: {s}");
}
assert!(s.contains("vmette.boot=ctl"));
assert!(s.contains("vmette.vsock_port=5000"));
}
#[test]
fn vsock_port_only_emitted_when_some() {
assert!(build(&base(), Some(55555)).contains("vmette.vsock_port=55555"));
assert!(!build(&base(), None).contains("vmette.vsock_port"));
}
#[test]
fn blk_device_name_maps_index_to_letter() {
assert_eq!(blk_device_name(0), "vda");
assert_eq!(blk_device_name(1), "vdb");
assert_eq!(blk_device_name(3), "vdd");
}
}