use crate::config::{Config, ZramConfig};
use std::fs;
use std::path::Path;
pub fn generate_units(output_dir: &str, config: &Config) -> Result<(), Box<dyn std::error::Error>> {
let output_path = Path::new(output_dir);
fs::create_dir_all(output_path)?;
for device_config in &config.devices {
generate_device_unit(output_path, device_config)?;
generate_swap_unit(output_path, device_config)?;
}
Ok(())
}
fn generate_device_unit(
output_dir: &Path,
config: &ZramConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let unit_name = format!("trueno-zram{}.service", config.device);
let unit_path = output_dir.join(&unit_name);
let unit_content = format!(
r"# Generated by trueno-zram-generator
[Unit]
Description=Configure zram device {device}
DefaultDependencies=no
After=local-fs.target
Before=swap.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/trueno-zram create --device {device} --size {size} --algorithm {algorithm} --streams {streams}
ExecStop=/usr/bin/trueno-zram remove --device {device}
[Install]
WantedBy=swap.target
",
device = config.device,
size = config.size,
algorithm = config.algorithm,
streams = config.streams,
);
fs::write(unit_path, unit_content)?;
Ok(())
}
fn generate_swap_unit(
output_dir: &Path,
config: &ZramConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let unit_name = format!("dev-zram{}.swap", config.device);
let unit_path = output_dir.join(&unit_name);
let unit_content = format!(
r"# Generated by trueno-zram-generator
[Unit]
Description=Compressed swap on zram{device}
Requires=trueno-zram{device}.service
After=trueno-zram{device}.service
[Swap]
What=/dev/zram{device}
Priority={priority}
[Install]
WantedBy=swap.target
",
device = config.device,
priority = config.priority,
);
fs::write(unit_path, unit_content)?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
#[test]
fn test_generate_units() {
let temp_dir = std::env::temp_dir().join("trueno-zram-test");
let _ = fs::remove_dir_all(&temp_dir);
fs::create_dir_all(&temp_dir).unwrap();
let config = Config {
devices: vec![ZramConfig {
device: 0,
size: "4G".to_string(),
algorithm: "lz4".to_string(),
streams: 4,
priority: 100,
}],
};
generate_units(temp_dir.to_str().unwrap(), &config).unwrap();
assert!(temp_dir.join("trueno-zram0.service").exists());
assert!(temp_dir.join("dev-zram0.swap").exists());
let _ = fs::remove_dir_all(&temp_dir);
}
}