reddwarf/crates/reddwarf-runtime/src/zone/config.rs

141 lines
5.1 KiB
Rust
Raw Normal View History

use crate::error::Result;
use crate::types::{NetworkMode, ZoneConfig};
/// Generate a zonecfg command file from a ZoneConfig
pub fn generate_zonecfg(config: &ZoneConfig) -> Result<String> {
let mut lines = Vec::new();
lines.push("create".to_string());
lines.push(format!("set brand={}", config.brand));
lines.push(format!("set zonepath={}", config.zonepath));
lines.push("set ip-type=exclusive".to_string());
// Network resource
let vnic_name = match &config.network {
NetworkMode::Etherstub(cfg) => &cfg.vnic_name,
NetworkMode::Direct(cfg) => &cfg.vnic_name,
};
lines.push("add net".to_string());
lines.push(format!("set physical={}", vnic_name));
lines.push("end".to_string());
// CPU cap
if let Some(ref cpu_cap) = config.cpu_cap {
lines.push("add capped-cpu".to_string());
lines.push(format!("set ncpus={}", cpu_cap));
lines.push("end".to_string());
}
// Memory cap
if let Some(ref memory_cap) = config.memory_cap {
lines.push("add capped-memory".to_string());
lines.push(format!("set physical={}", memory_cap));
lines.push("end".to_string());
}
// Filesystem mounts
for mount in &config.fs_mounts {
lines.push("add fs".to_string());
lines.push(format!("set dir={}", mount.mountpoint));
lines.push(format!("set special={}", mount.source));
lines.push(format!("set type={}", mount.fs_type));
for opt in &mount.options {
lines.push(format!("add options {}", opt));
}
lines.push("end".to_string());
}
lines.push("verify".to_string());
lines.push("commit".to_string());
Ok(lines.join("\n"))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::*;
#[test]
fn test_generate_zonecfg_lx_brand() {
let config = ZoneConfig {
zone_name: "test-zone".to_string(),
brand: ZoneBrand::Lx,
zonepath: "/zones/test-zone".to_string(),
network: NetworkMode::Etherstub(EtherstubConfig {
etherstub_name: "reddwarf0".to_string(),
vnic_name: "vnic0".to_string(),
ip_address: "10.0.0.2".to_string(),
gateway: "10.0.0.1".to_string(),
}),
zfs: ZfsConfig {
parent_dataset: "rpool/zones".to_string(),
clone_from: None,
quota: Some("10G".to_string()),
},
lx_image_path: Some("/images/ubuntu-22.04.tar.gz".to_string()),
processes: vec![],
cpu_cap: Some("2.0".to_string()),
memory_cap: Some("1G".to_string()),
fs_mounts: vec![],
};
let result = generate_zonecfg(&config).unwrap();
assert!(result.contains("set brand=lx"));
assert!(result.contains("set zonepath=/zones/test-zone"));
assert!(result.contains("set ip-type=exclusive"));
assert!(result.contains("set physical=vnic0"));
assert!(result.contains("set ncpus=2.0"));
assert!(result.contains("set physical=1G"));
assert!(result.contains("verify"));
assert!(result.contains("commit"));
}
#[test]
fn test_generate_zonecfg_custom_brand_with_fs_mounts() {
let config = ZoneConfig {
zone_name: "app-zone".to_string(),
brand: ZoneBrand::Reddwarf,
zonepath: "/zones/app-zone".to_string(),
network: NetworkMode::Direct(DirectNicConfig {
physical_nic: "igb0".to_string(),
vnic_name: "vnic1".to_string(),
ip_address: "192.168.1.10".to_string(),
gateway: "192.168.1.1".to_string(),
}),
zfs: ZfsConfig {
parent_dataset: "rpool/zones".to_string(),
clone_from: Some("rpool/zones/template@base".to_string()),
quota: None,
},
lx_image_path: None,
processes: vec![ContainerProcess {
name: "web".to_string(),
command: vec!["/usr/bin/node".to_string(), "server.js".to_string()],
working_dir: Some("/app".to_string()),
env: vec![("PORT".to_string(), "3000".to_string())],
}],
cpu_cap: None,
memory_cap: Some("512M".to_string()),
fs_mounts: vec![FsMount {
source: "/data/app-config".to_string(),
mountpoint: "/etc/app".to_string(),
fs_type: "lofs".to_string(),
options: vec!["ro".to_string()],
}],
};
let result = generate_zonecfg(&config).unwrap();
assert!(result.contains("set brand=reddwarf"));
assert!(result.contains("set physical=vnic1"));
assert!(result.contains("set physical=512M"));
assert!(result.contains("add fs"));
assert!(result.contains("set dir=/etc/app"));
assert!(result.contains("set special=/data/app-config"));
assert!(result.contains("set type=lofs"));
assert!(result.contains("add options ro"));
// No cpu cap
assert!(!result.contains("capped-cpu"));
}
}