emu_cli/
template.rs

1use super::vm::VM;
2use anyhow::{anyhow, Result};
3use serde::Serialize;
4use tinytemplate::TinyTemplate;
5
6const EMU_DEFAULT_PATH: &str = "/bin/emu";
7
8const SYSTEMD_UNIT: &str = "
9[Unit]
10Description=Virtual Machine: {vm_name}
11
12[Service]
13Type=simple
14ExecStart={emu_path} run -e {vm_name}
15TimeoutStopSec=30
16ExecStop={emu_path} shutdown {vm_name}
17KillSignal=SIGCONT
18FinalKillSignal=SIGKILL
19
20[Install]
21WantedBy=default.target
22";
23
24#[derive(Serialize)]
25pub struct Data {
26    vm_name: String,
27    emu_path: String,
28}
29
30impl Data {
31    pub fn new(vm_name: String) -> Self {
32        Self {
33            vm_name,
34            emu_path: match std::env::current_exe() {
35                Ok(path) => path.to_str().unwrap().to_string(),
36                Err(_) => EMU_DEFAULT_PATH.to_string(),
37            },
38        }
39    }
40}
41
42#[derive(Debug, Clone, Default)]
43pub struct Systemd;
44
45impl Systemd {
46    pub fn template(&self, vm: &VM) -> Result<String> {
47        let mut t = TinyTemplate::new();
48        t.add_template("systemd", SYSTEMD_UNIT)?;
49        let data = Data::new(vm.name());
50        match t.render("systemd", &data) {
51            Ok(x) => Ok(x),
52            Err(e) => Err(anyhow!(e)),
53        }
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use anyhow::Result;
61
62    #[test]
63    fn test_template() -> Result<()> {
64        let out = Systemd::template(&Systemd, &"vm1".to_string().into())?;
65        assert!(out.contains("vm1"));
66
67        Ok(())
68    }
69}