use anyhow::{Context, Result};
use std::path::Path;
use tera::Tera;
const UNIT_TEMPLATE: &str = include_str!("../files/innisfree@.service");
pub fn render_unit(executable_path: &Path) -> Result<String> {
let mut ctx = tera::Context::new();
ctx.insert("executable_path", &executable_path.display().to_string());
Tera::one_off(UNIT_TEMPLATE, &ctx, false).context("rendering systemd unit template")
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
#[test]
fn renders_executable_path_into_exec_start() {
let unit = render_unit(&PathBuf::from("/opt/bin/innisfree")).unwrap();
assert!(
unit.contains("ExecStart=/opt/bin/innisfree up --name %i"),
"got:\n{unit}"
);
}
#[test]
fn rendered_unit_has_no_template_marker() {
let unit = render_unit(&PathBuf::from("/usr/bin/innisfree")).unwrap();
assert!(
!unit.contains("{{") && !unit.contains("}}"),
"Tera placeholder leaked into output:\n{unit}"
);
}
#[test]
fn preserves_systemd_instance_substitution() {
let unit = render_unit(&PathBuf::from("/usr/bin/innisfree")).unwrap();
assert!(unit.contains("--name %i"), "got:\n{unit}");
assert!(unit.contains("Description=innisfree tunnel for %i"));
}
#[test]
fn declares_required_capabilities() {
let unit = render_unit(&PathBuf::from("/usr/bin/innisfree")).unwrap();
assert!(unit.contains("AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE"));
assert!(unit.contains("CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE"));
}
#[test]
fn install_section_targets_multi_user() {
let unit = render_unit(&PathBuf::from("/usr/bin/innisfree")).unwrap();
assert!(unit.contains("[Install]\nWantedBy=multi-user.target"));
}
}