mirror of https://github.com/telemt/telemt.git
Add multi-platform service manager integration
Implement automatic init system detection and service file generation for systemd, OpenRC (Alpine/Gentoo), and FreeBSD rc.d: - Add src/service module with init system detection and generators - Auto-detect init system via filesystem probes - Generate platform-appropriate service files during --init systemd enhancements: - ExecReload for SIGHUP config reload - PIDFile directive - Comprehensive security hardening (ProtectKernelTunables, RestrictAddressFamilies, MemoryDenyWriteExecute, etc.) - CAP_NET_BIND_SERVICE for privileged ports OpenRC support: - Standard openrc-run script with depend/reload functions - Directory setup in start_pre FreeBSD rc.d support: - rc.subr integration with rc.conf variables - reload extra command The --init command now detects the init system and runs the appropriate enable/start commands (systemctl, rc-update, sysrc). Signed-off-by: Vladimir Krivopalov <argenet@yandex.ru>
This commit is contained in:
parent
e48331e344
commit
dd548d1049
195
src/cli.rs
195
src/cli.rs
|
|
@ -401,10 +401,16 @@ pub fn parse_init_args(args: &[String]) -> Option<InitOptions> {
|
|||
|
||||
/// Run the fire-and-forget setup.
|
||||
pub fn run_init(opts: InitOptions) -> Result<(), Box<dyn std::error::Error>> {
|
||||
use crate::service::{self, InitSystem, ServiceOptions};
|
||||
|
||||
eprintln!("[telemt] Fire-and-forget setup");
|
||||
eprintln!();
|
||||
|
||||
// 1. Generate or validate secret
|
||||
|
||||
// 1. Detect init system
|
||||
let init_system = service::detect_init_system();
|
||||
eprintln!("[+] Detected init system: {}", init_system);
|
||||
|
||||
// 2. Generate or validate secret
|
||||
let secret = match opts.secret {
|
||||
Some(s) => {
|
||||
if s.len() != 32 || !s.chars().all(|c| c.is_ascii_hexdigit()) {
|
||||
|
|
@ -415,80 +421,134 @@ pub fn run_init(opts: InitOptions) -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
None => generate_secret(),
|
||||
};
|
||||
|
||||
|
||||
eprintln!("[+] Secret: {}", secret);
|
||||
eprintln!("[+] User: {}", opts.username);
|
||||
eprintln!("[+] Port: {}", opts.port);
|
||||
eprintln!("[+] Domain: {}", opts.domain);
|
||||
|
||||
// 2. Create config directory
|
||||
|
||||
// 3. Create config directory
|
||||
fs::create_dir_all(&opts.config_dir)?;
|
||||
let config_path = opts.config_dir.join("config.toml");
|
||||
|
||||
// 3. Write config
|
||||
|
||||
// 4. Write config
|
||||
let config_content = generate_config(&opts.username, &secret, opts.port, &opts.domain);
|
||||
fs::write(&config_path, &config_content)?;
|
||||
eprintln!("[+] Config written to {}", config_path.display());
|
||||
|
||||
// 4. Write systemd unit
|
||||
|
||||
// 5. Generate and write service file
|
||||
let exe_path = std::env::current_exe()
|
||||
.unwrap_or_else(|_| PathBuf::from("/usr/local/bin/telemt"));
|
||||
|
||||
let unit_path = Path::new("/etc/systemd/system/telemt.service");
|
||||
let unit_content = generate_systemd_unit(&exe_path, &config_path);
|
||||
|
||||
match fs::write(unit_path, &unit_content) {
|
||||
|
||||
let service_opts = ServiceOptions {
|
||||
exe_path: &exe_path,
|
||||
config_path: &config_path,
|
||||
user: None, // Let systemd/init handle user
|
||||
group: None,
|
||||
pid_file: "/var/run/telemt.pid",
|
||||
working_dir: Some("/var/lib/telemt"),
|
||||
description: "Telemt MTProxy - Telegram MTProto Proxy",
|
||||
};
|
||||
|
||||
let service_path = service::service_file_path(init_system);
|
||||
let service_content = service::generate_service_file(init_system, &service_opts);
|
||||
|
||||
// Ensure parent directory exists
|
||||
if let Some(parent) = Path::new(service_path).parent() {
|
||||
let _ = fs::create_dir_all(parent);
|
||||
}
|
||||
|
||||
match fs::write(service_path, &service_content) {
|
||||
Ok(()) => {
|
||||
eprintln!("[+] Systemd unit written to {}", unit_path.display());
|
||||
eprintln!("[+] Service file written to {}", service_path);
|
||||
|
||||
// Make script executable for OpenRC/FreeBSD
|
||||
#[cfg(unix)]
|
||||
if init_system == InitSystem::OpenRC || init_system == InitSystem::FreeBSDRc {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let mut perms = fs::metadata(service_path)?.permissions();
|
||||
perms.set_mode(0o755);
|
||||
fs::set_permissions(service_path, perms)?;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("[!] Cannot write systemd unit (run as root?): {}", e);
|
||||
eprintln!("[!] Manual unit file content:");
|
||||
eprintln!("{}", unit_content);
|
||||
|
||||
// Still print links and config
|
||||
eprintln!("[!] Cannot write service file (run as root?): {}", e);
|
||||
eprintln!("[!] Manual service file content:");
|
||||
eprintln!("{}", service_content);
|
||||
|
||||
// Still print links and installation instructions
|
||||
eprintln!();
|
||||
eprintln!("{}", service::installation_instructions(init_system));
|
||||
print_links(&opts.username, &secret, opts.port, &opts.domain);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Reload systemd
|
||||
run_cmd("systemctl", &["daemon-reload"]);
|
||||
|
||||
// 6. Enable service
|
||||
run_cmd("systemctl", &["enable", "telemt.service"]);
|
||||
eprintln!("[+] Service enabled");
|
||||
|
||||
// 7. Start service (unless --no-start)
|
||||
if !opts.no_start {
|
||||
run_cmd("systemctl", &["start", "telemt.service"]);
|
||||
eprintln!("[+] Service started");
|
||||
|
||||
// Brief delay then check status
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
let status = Command::new("systemctl")
|
||||
.args(["is-active", "telemt.service"])
|
||||
.output();
|
||||
|
||||
match status {
|
||||
Ok(out) if out.status.success() => {
|
||||
eprintln!("[+] Service is running");
|
||||
}
|
||||
_ => {
|
||||
eprintln!("[!] Service may not have started correctly");
|
||||
eprintln!("[!] Check: journalctl -u telemt.service -n 20");
|
||||
|
||||
// 6. Install and enable service based on init system
|
||||
match init_system {
|
||||
InitSystem::Systemd => {
|
||||
run_cmd("systemctl", &["daemon-reload"]);
|
||||
run_cmd("systemctl", &["enable", "telemt.service"]);
|
||||
eprintln!("[+] Service enabled");
|
||||
|
||||
if !opts.no_start {
|
||||
run_cmd("systemctl", &["start", "telemt.service"]);
|
||||
eprintln!("[+] Service started");
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
let status = Command::new("systemctl")
|
||||
.args(["is-active", "telemt.service"])
|
||||
.output();
|
||||
|
||||
match status {
|
||||
Ok(out) if out.status.success() => {
|
||||
eprintln!("[+] Service is running");
|
||||
}
|
||||
_ => {
|
||||
eprintln!("[!] Service may not have started correctly");
|
||||
eprintln!("[!] Check: journalctl -u telemt.service -n 20");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eprintln!("[+] Service not started (--no-start)");
|
||||
eprintln!("[+] Start manually: systemctl start telemt.service");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eprintln!("[+] Service not started (--no-start)");
|
||||
eprintln!("[+] Start manually: systemctl start telemt.service");
|
||||
InitSystem::OpenRC => {
|
||||
run_cmd("rc-update", &["add", "telemt", "default"]);
|
||||
eprintln!("[+] Service enabled");
|
||||
|
||||
if !opts.no_start {
|
||||
run_cmd("rc-service", &["telemt", "start"]);
|
||||
eprintln!("[+] Service started");
|
||||
} else {
|
||||
eprintln!("[+] Service not started (--no-start)");
|
||||
eprintln!("[+] Start manually: rc-service telemt start");
|
||||
}
|
||||
}
|
||||
InitSystem::FreeBSDRc => {
|
||||
run_cmd("sysrc", &["telemt_enable=YES"]);
|
||||
eprintln!("[+] Service enabled");
|
||||
|
||||
if !opts.no_start {
|
||||
run_cmd("service", &["telemt", "start"]);
|
||||
eprintln!("[+] Service started");
|
||||
} else {
|
||||
eprintln!("[+] Service not started (--no-start)");
|
||||
eprintln!("[+] Start manually: service telemt start");
|
||||
}
|
||||
}
|
||||
InitSystem::Unknown => {
|
||||
eprintln!("[!] Unknown init system - service file written but not installed");
|
||||
eprintln!("[!] You may need to install it manually");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
eprintln!();
|
||||
|
||||
// 8. Print links
|
||||
|
||||
// 7. Print links
|
||||
print_links(&opts.username, &secret, opts.port, &opts.domain);
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -581,35 +641,6 @@ weight = 10
|
|||
)
|
||||
}
|
||||
|
||||
fn generate_systemd_unit(exe_path: &Path, config_path: &Path) -> String {
|
||||
format!(
|
||||
r#"[Unit]
|
||||
Description=Telemt MTProxy
|
||||
Documentation=https://github.com/telemt/telemt
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart={exe} {config}
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
LimitNOFILE=65535
|
||||
# Security hardening
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/etc/telemt
|
||||
PrivateTmp=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"#,
|
||||
exe = exe_path.display(),
|
||||
config = config_path.display(),
|
||||
)
|
||||
}
|
||||
|
||||
fn run_cmd(cmd: &str, args: &[&str]) {
|
||||
match Command::new(cmd).args(args).output() {
|
||||
Ok(output) => {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ mod crypto;
|
|||
mod daemon;
|
||||
mod error;
|
||||
mod ip_tracker;
|
||||
mod service;
|
||||
#[cfg(test)]
|
||||
mod ip_tracker_regression_tests;
|
||||
mod maestro;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,374 @@
|
|||
//! Service manager integration for telemt.
|
||||
//!
|
||||
//! Supports generating service files for:
|
||||
//! - systemd (Linux)
|
||||
//! - OpenRC (Alpine, Gentoo)
|
||||
//! - rc.d (FreeBSD)
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
/// Detected init/service system.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum InitSystem {
|
||||
/// systemd (most modern Linux distributions)
|
||||
Systemd,
|
||||
/// OpenRC (Alpine, Gentoo, some BSDs)
|
||||
OpenRC,
|
||||
/// FreeBSD rc.d
|
||||
FreeBSDRc,
|
||||
/// No known init system detected
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for InitSystem {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
InitSystem::Systemd => write!(f, "systemd"),
|
||||
InitSystem::OpenRC => write!(f, "OpenRC"),
|
||||
InitSystem::FreeBSDRc => write!(f, "FreeBSD rc.d"),
|
||||
InitSystem::Unknown => write!(f, "unknown"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Detects the init system in use on the current host.
|
||||
pub fn detect_init_system() -> InitSystem {
|
||||
// Check for systemd first (most common on Linux)
|
||||
if Path::new("/run/systemd/system").exists() {
|
||||
return InitSystem::Systemd;
|
||||
}
|
||||
|
||||
// Check for OpenRC
|
||||
if Path::new("/sbin/openrc-run").exists() || Path::new("/sbin/openrc").exists() {
|
||||
return InitSystem::OpenRC;
|
||||
}
|
||||
|
||||
// Check for FreeBSD rc.d
|
||||
if Path::new("/etc/rc.subr").exists() && Path::new("/etc/rc.d").exists() {
|
||||
return InitSystem::FreeBSDRc;
|
||||
}
|
||||
|
||||
// Fallback: check if systemctl exists even without /run/systemd
|
||||
if Path::new("/usr/bin/systemctl").exists() || Path::new("/bin/systemctl").exists() {
|
||||
return InitSystem::Systemd;
|
||||
}
|
||||
|
||||
InitSystem::Unknown
|
||||
}
|
||||
|
||||
/// Returns the default service file path for the given init system.
|
||||
pub fn service_file_path(init_system: InitSystem) -> &'static str {
|
||||
match init_system {
|
||||
InitSystem::Systemd => "/etc/systemd/system/telemt.service",
|
||||
InitSystem::OpenRC => "/etc/init.d/telemt",
|
||||
InitSystem::FreeBSDRc => "/usr/local/etc/rc.d/telemt",
|
||||
InitSystem::Unknown => "/etc/init.d/telemt",
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for generating service files.
|
||||
pub struct ServiceOptions<'a> {
|
||||
/// Path to the telemt executable
|
||||
pub exe_path: &'a Path,
|
||||
/// Path to the configuration file
|
||||
pub config_path: &'a Path,
|
||||
/// User to run as (optional)
|
||||
pub user: Option<&'a str>,
|
||||
/// Group to run as (optional)
|
||||
pub group: Option<&'a str>,
|
||||
/// PID file path
|
||||
pub pid_file: &'a str,
|
||||
/// Working directory
|
||||
pub working_dir: Option<&'a str>,
|
||||
/// Description
|
||||
pub description: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> Default for ServiceOptions<'a> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
exe_path: Path::new("/usr/local/bin/telemt"),
|
||||
config_path: Path::new("/etc/telemt/config.toml"),
|
||||
user: Some("telemt"),
|
||||
group: Some("telemt"),
|
||||
pid_file: "/var/run/telemt.pid",
|
||||
working_dir: Some("/var/lib/telemt"),
|
||||
description: "Telemt MTProxy - Telegram MTProto Proxy",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates a service file for the given init system.
|
||||
pub fn generate_service_file(init_system: InitSystem, opts: &ServiceOptions) -> String {
|
||||
match init_system {
|
||||
InitSystem::Systemd => generate_systemd_unit(opts),
|
||||
InitSystem::OpenRC => generate_openrc_script(opts),
|
||||
InitSystem::FreeBSDRc => generate_freebsd_rc_script(opts),
|
||||
InitSystem::Unknown => generate_systemd_unit(opts), // Default to systemd format
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates an enhanced systemd unit file.
|
||||
fn generate_systemd_unit(opts: &ServiceOptions) -> String {
|
||||
let user_line = opts.user.map(|u| format!("User={}", u)).unwrap_or_default();
|
||||
let group_line = opts.group.map(|g| format!("Group={}", g)).unwrap_or_default();
|
||||
let working_dir = opts.working_dir.map(|d| format!("WorkingDirectory={}", d)).unwrap_or_default();
|
||||
|
||||
format!(
|
||||
r#"[Unit]
|
||||
Description={description}
|
||||
Documentation=https://github.com/telemt/telemt
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart={exe} --foreground --pid-file {pid_file} {config}
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
PIDFile={pid_file}
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
{user}
|
||||
{group}
|
||||
{working_dir}
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65535
|
||||
LimitNPROC=4096
|
||||
|
||||
# Security hardening
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
PrivateTmp=true
|
||||
PrivateDevices=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
RestrictNamespaces=true
|
||||
RestrictRealtime=true
|
||||
RestrictSUIDSGID=true
|
||||
MemoryDenyWriteExecute=true
|
||||
LockPersonality=true
|
||||
|
||||
# Allow binding to privileged ports and writing to specific paths
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
ReadWritePaths=/etc/telemt /var/run /var/lib/telemt
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"#,
|
||||
description = opts.description,
|
||||
exe = opts.exe_path.display(),
|
||||
config = opts.config_path.display(),
|
||||
pid_file = opts.pid_file,
|
||||
user = user_line,
|
||||
group = group_line,
|
||||
working_dir = working_dir,
|
||||
)
|
||||
}
|
||||
|
||||
/// Generates an OpenRC init script.
|
||||
fn generate_openrc_script(opts: &ServiceOptions) -> String {
|
||||
let user = opts.user.unwrap_or("root");
|
||||
let group = opts.group.unwrap_or("root");
|
||||
|
||||
format!(
|
||||
r#"#!/sbin/openrc-run
|
||||
# OpenRC init script for telemt
|
||||
|
||||
description="{description}"
|
||||
command="{exe}"
|
||||
command_args="--daemon --pid-file {pid_file} {config}"
|
||||
command_user="{user}:{group}"
|
||||
pidfile="{pid_file}"
|
||||
|
||||
depend() {{
|
||||
need net
|
||||
after firewall
|
||||
}}
|
||||
|
||||
start_pre() {{
|
||||
checkpath --directory --owner {user}:{group} --mode 0755 /var/run
|
||||
checkpath --directory --owner {user}:{group} --mode 0755 /var/lib/telemt
|
||||
}}
|
||||
|
||||
reload() {{
|
||||
ebegin "Reloading ${{RC_SVCNAME}}"
|
||||
start-stop-daemon --signal HUP --pidfile "${{pidfile}}"
|
||||
eend $?
|
||||
}}
|
||||
"#,
|
||||
description = opts.description,
|
||||
exe = opts.exe_path.display(),
|
||||
config = opts.config_path.display(),
|
||||
pid_file = opts.pid_file,
|
||||
user = user,
|
||||
group = group,
|
||||
)
|
||||
}
|
||||
|
||||
/// Generates a FreeBSD rc.d script.
|
||||
fn generate_freebsd_rc_script(opts: &ServiceOptions) -> String {
|
||||
let user = opts.user.unwrap_or("root");
|
||||
let group = opts.group.unwrap_or("wheel");
|
||||
|
||||
format!(
|
||||
r#"#!/bin/sh
|
||||
#
|
||||
# PROVIDE: telemt
|
||||
# REQUIRE: LOGIN NETWORKING
|
||||
# KEYWORD: shutdown
|
||||
#
|
||||
# Add the following lines to /etc/rc.conf to enable telemt:
|
||||
#
|
||||
# telemt_enable="YES"
|
||||
# telemt_config="/etc/telemt/config.toml" # optional
|
||||
# telemt_user="telemt" # optional
|
||||
# telemt_group="telemt" # optional
|
||||
#
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
name="telemt"
|
||||
rcvar="telemt_enable"
|
||||
desc="{description}"
|
||||
|
||||
load_rc_config $name
|
||||
|
||||
: ${{telemt_enable:="NO"}}
|
||||
: ${{telemt_config:="{config}"}}
|
||||
: ${{telemt_user:="{user}"}}
|
||||
: ${{telemt_group:="{group}"}}
|
||||
: ${{telemt_pidfile:="{pid_file}"}}
|
||||
|
||||
pidfile="${{telemt_pidfile}}"
|
||||
command="{exe}"
|
||||
command_args="--daemon --pid-file ${{telemt_pidfile}} ${{telemt_config}}"
|
||||
|
||||
start_precmd="telemt_prestart"
|
||||
reload_cmd="telemt_reload"
|
||||
extra_commands="reload"
|
||||
|
||||
telemt_prestart() {{
|
||||
install -d -o ${{telemt_user}} -g ${{telemt_group}} -m 755 /var/run
|
||||
install -d -o ${{telemt_user}} -g ${{telemt_group}} -m 755 /var/lib/telemt
|
||||
}}
|
||||
|
||||
telemt_reload() {{
|
||||
if [ -f "${{pidfile}}" ]; then
|
||||
echo "Reloading ${{name}} configuration."
|
||||
kill -HUP $(cat ${{pidfile}})
|
||||
else
|
||||
echo "${{name}} is not running."
|
||||
return 1
|
||||
fi
|
||||
}}
|
||||
|
||||
run_rc_command "$1"
|
||||
"#,
|
||||
description = opts.description,
|
||||
exe = opts.exe_path.display(),
|
||||
config = opts.config_path.display(),
|
||||
pid_file = opts.pid_file,
|
||||
user = user,
|
||||
group = group,
|
||||
)
|
||||
}
|
||||
|
||||
/// Installation instructions for each init system.
|
||||
pub fn installation_instructions(init_system: InitSystem) -> &'static str {
|
||||
match init_system {
|
||||
InitSystem::Systemd => {
|
||||
r#"To install and enable the service:
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable telemt
|
||||
sudo systemctl start telemt
|
||||
|
||||
To check status:
|
||||
sudo systemctl status telemt
|
||||
|
||||
To view logs:
|
||||
journalctl -u telemt -f
|
||||
|
||||
To reload configuration:
|
||||
sudo systemctl reload telemt
|
||||
"#
|
||||
}
|
||||
InitSystem::OpenRC => {
|
||||
r#"To install and enable the service:
|
||||
sudo chmod +x /etc/init.d/telemt
|
||||
sudo rc-update add telemt default
|
||||
sudo rc-service telemt start
|
||||
|
||||
To check status:
|
||||
sudo rc-service telemt status
|
||||
|
||||
To reload configuration:
|
||||
sudo rc-service telemt reload
|
||||
"#
|
||||
}
|
||||
InitSystem::FreeBSDRc => {
|
||||
r#"To install and enable the service:
|
||||
sudo chmod +x /usr/local/etc/rc.d/telemt
|
||||
sudo sysrc telemt_enable="YES"
|
||||
sudo service telemt start
|
||||
|
||||
To check status:
|
||||
sudo service telemt status
|
||||
|
||||
To reload configuration:
|
||||
sudo service telemt reload
|
||||
"#
|
||||
}
|
||||
InitSystem::Unknown => {
|
||||
r#"No supported init system detected.
|
||||
You may need to create a service file manually or run telemt directly:
|
||||
telemt start /etc/telemt/config.toml
|
||||
"#
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_systemd_unit_generation() {
|
||||
let opts = ServiceOptions::default();
|
||||
let unit = generate_systemd_unit(&opts);
|
||||
assert!(unit.contains("[Unit]"));
|
||||
assert!(unit.contains("[Service]"));
|
||||
assert!(unit.contains("[Install]"));
|
||||
assert!(unit.contains("ExecReload="));
|
||||
assert!(unit.contains("PIDFile="));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_openrc_script_generation() {
|
||||
let opts = ServiceOptions::default();
|
||||
let script = generate_openrc_script(&opts);
|
||||
assert!(script.contains("#!/sbin/openrc-run"));
|
||||
assert!(script.contains("depend()"));
|
||||
assert!(script.contains("reload()"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_freebsd_rc_script_generation() {
|
||||
let opts = ServiceOptions::default();
|
||||
let script = generate_freebsd_rc_script(&opts);
|
||||
assert!(script.contains("#!/bin/sh"));
|
||||
assert!(script.contains("PROVIDE: telemt"));
|
||||
assert!(script.contains("run_rc_command"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_service_file_paths() {
|
||||
assert_eq!(service_file_path(InitSystem::Systemd), "/etc/systemd/system/telemt.service");
|
||||
assert_eq!(service_file_path(InitSystem::OpenRC), "/etc/init.d/telemt");
|
||||
assert_eq!(service_file_path(InitSystem::FreeBSDRc), "/usr/local/etc/rc.d/telemt");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue