flexible installation path #32

Merged
lbrndnr merged 2 commits from main into main 2026-04-07 03:28:30 +08:00
3 changed files with 18 additions and 20 deletions

View File

@@ -6,7 +6,7 @@
<string>com.numa.dns</string> <string>com.numa.dns</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/usr/local/bin/numa</string> <string>{{exe_path}}</string>
</array> </array>
<key>RunAtLoad</key> <key>RunAtLoad</key>
<true/> <true/>

View File

@@ -5,7 +5,7 @@ Wants=network-online.target
[Service] [Service]
Type=simple Type=simple
ExecStart=/usr/local/bin/numa ExecStart={{exe_path}}
Restart=always Restart=always
RestartSec=2 RestartSec=2
StandardOutput=journal StandardOutput=journal

View File

@@ -903,9 +903,12 @@ pub fn uninstall_service() -> Result<(), String> {
/// Restart the service (kill process, launchd/systemd auto-restarts with new binary). /// Restart the service (kill process, launchd/systemd auto-restarts with new binary).
pub fn restart_service() -> Result<(), String> { pub fn restart_service() -> Result<(), String> {
let exe_path =
std::env::current_exe().map_err(|e| format!("failed to get current exe: {}", e))?;
#[cfg(any(target_os = "macos", target_os = "linux"))] #[cfg(any(target_os = "macos", target_os = "linux"))]
let version = { let version = {
match std::process::Command::new("/usr/local/bin/numa") match std::process::Command::new(&exe_path)
.arg("--version") .arg("--version")
.output() .output()
{ {
@@ -916,6 +919,7 @@ pub fn restart_service() -> Result<(), String> {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
let exe_path = exe_path.to_string_lossy();
let output = std::process::Command::new("launchctl") let output = std::process::Command::new("launchctl")
.args(["list", PLIST_LABEL]) .args(["list", PLIST_LABEL])
.output(); .output();
@@ -926,11 +930,11 @@ pub fn restart_service() -> Result<(), String> {
// This will kill us too (we ARE /usr/local/bin/numa), so // This will kill us too (we ARE /usr/local/bin/numa), so
// codesign and print output first. // codesign and print output first.
let _ = std::process::Command::new("codesign") let _ = std::process::Command::new("codesign")
.args(["-f", "-s", "-", "/usr/local/bin/numa"]) .args(["-f", "-s", "-", &exe_path])
.output(); // use output() to suppress codesign stderr .output(); // use output() to suppress codesign stderr
eprintln!(" Service restarting → {}\n", version); eprintln!(" Service restarting → {}\n", version);
let _ = std::process::Command::new("pkill") let _ = std::process::Command::new("pkill")
.args(["-f", "/usr/local/bin/numa"]) .args(["-f", &exe_path])
.status(); .status();
Ok(()) Ok(())
} }
@@ -965,19 +969,22 @@ pub fn service_status() -> Result<(), String> {
} }
} }
#[cfg(target_os = "macos")] fn replace_exe_path(service: &str) -> Result<String, String> {
fn install_service_macos() -> Result<(), String> { let exe_path =
// Check binary exists std::env::current_exe().map_err(|e| format!("failed to get current exe: {}", e))?;
if !std::path::Path::new("/usr/local/bin/numa").exists() { Ok(service.replace("{{exe_path}}", &exe_path.to_string_lossy()))
return Err("numa binary not found at /usr/local/bin/numa. Run: sudo cp target/release/numa /usr/local/bin/numa".to_string());
} }
#[cfg(target_os = "macos")]
fn install_service_macos() -> Result<(), String> {
// Create log directory // Create log directory
std::fs::create_dir_all("/usr/local/var/log") std::fs::create_dir_all("/usr/local/var/log")
.map_err(|e| format!("failed to create log dir: {}", e))?; .map_err(|e| format!("failed to create log dir: {}", e))?;
// Write plist // Write plist
let plist = include_str!("../com.numa.dns.plist"); let plist = include_str!("../com.numa.dns.plist");
let plist = replace_exe_path(plist)?;
std::fs::write(PLIST_DEST, plist) std::fs::write(PLIST_DEST, plist)
.map_err(|e| format!("failed to write {}: {}", PLIST_DEST, e))?; .map_err(|e| format!("failed to write {}: {}", PLIST_DEST, e))?;
@@ -1179,19 +1186,10 @@ fn uninstall_linux() -> Result<(), String> {
Ok(()) Ok(())
} }
#[cfg(target_os = "linux")]
fn ensure_binary_installed() -> Result<(), String> {
if !std::path::Path::new("/usr/local/bin/numa").exists() {
return Err("numa binary not found at /usr/local/bin/numa. Run: sudo cp target/release/numa /usr/local/bin/numa".to_string());
}
Ok(())
}
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn install_service_linux() -> Result<(), String> { fn install_service_linux() -> Result<(), String> {
ensure_binary_installed()?;
let unit = include_str!("../numa.service"); let unit = include_str!("../numa.service");
let unit = replace_exe_path(unit)?;
std::fs::write(SYSTEMD_UNIT, unit) std::fs::write(SYSTEMD_UNIT, unit)
.map_err(|e| format!("failed to write {}: {}", SYSTEMD_UNIT, e))?; .map_err(|e| format!("failed to write {}: {}", SYSTEMD_UNIT, e))?;