mirror of
https://github.com/CloudNebulaProject/reddwarf.git
synced 2026-04-10 13:20:40 +00:00
141 lines
5.1 KiB
Rust
141 lines
5.1 KiB
Rust
|
|
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"));
|
||
|
|
}
|
||
|
|
}
|