feat: add bundled WireGuard tools support for macOS desktop client with fallback path resolution

Add wg and wg-quick bundling to build-tunnel-helper.sh for aarch64-apple-darwin target. Check for wireguard-tools installation and copy binaries to output directory with execute permissions.

Implement find_wg_quick helper with bundled tool detection and standard path fallbacks. Add bundled_macos_tool to check for tools in current executable directory. Update connect_direct and disconnect_direct to use explicit
This commit is contained in:
2026-03-18 14:31:37 +01:00
parent 5233e90dce
commit 8eb293e01e
2 changed files with 73 additions and 2 deletions

View File

@@ -529,7 +529,9 @@ fn connect_direct(profile: &Path) -> Result<(), String> {
#[cfg(target_os = "macos")]
{
let command = format!("wg-quick up '{}'", profile.display());
let wg_quick = find_wg_quick()?;
let path_prefix = macos_command_path_prefix(&wg_quick);
let command = format!("PATH='{}:$PATH' '{}' up '{}'", path_prefix, wg_quick.display(), profile.display());
let status = Command::new("osascript")
.arg("-e")
.arg(format!("do shell script \"{}\" with administrator privileges", command))
@@ -567,7 +569,9 @@ fn disconnect_direct(profile: &Path) -> Result<(), String> {
#[cfg(target_os = "macos")]
{
let command = format!("wg-quick down '{}'", profile.display());
let wg_quick = find_wg_quick()?;
let path_prefix = macos_command_path_prefix(&wg_quick);
let command = format!("PATH='{}:$PATH' '{}' down '{}'", path_prefix, wg_quick.display(), profile.display());
let status = Command::new("osascript")
.arg("-e")
.arg(format!("do shell script \"{}\" with administrator privileges", command))
@@ -808,9 +812,59 @@ fn find_wg_cli() -> Result<PathBuf, String> {
#[cfg(target_os = "macos")]
fn find_wg_cli() -> Result<PathBuf, String> {
if let Some(path) = bundled_macos_tool("wg") {
return Ok(path);
}
let candidates = [
PathBuf::from("/opt/homebrew/bin/wg"),
PathBuf::from("/usr/local/bin/wg"),
PathBuf::from("/usr/bin/wg"),
];
if let Some(path) = candidates.into_iter().find(|path| path.exists()) {
return Ok(path);
}
Ok(PathBuf::from("wg"))
}
#[cfg(target_os = "macos")]
fn find_wg_quick() -> Result<PathBuf, String> {
if let Some(path) = bundled_macos_tool("wg-quick") {
return Ok(path);
}
let candidates = [
PathBuf::from("/opt/homebrew/bin/wg-quick"),
PathBuf::from("/usr/local/bin/wg-quick"),
PathBuf::from("/usr/bin/wg-quick"),
];
candidates
.into_iter()
.find(|path| path.exists())
.or_else(|| Some(PathBuf::from("wg-quick")))
.ok_or_else(|| "required macOS tunnel runtime is not available".to_string())
}
#[cfg(target_os = "macos")]
fn bundled_macos_tool(name: &str) -> Option<PathBuf> {
let current_exe = std::env::current_exe().ok()?;
let dir = current_exe.parent()?;
let path = dir.join(name);
path.exists().then_some(path)
}
#[cfg(target_os = "macos")]
fn macos_command_path_prefix(tool_path: &Path) -> String {
let parent = tool_path
.parent()
.map(|path| path.display().to_string())
.unwrap_or_else(|| "/opt/homebrew/bin".to_string());
format!("{parent}:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin")
}
#[cfg(target_os = "windows")]
fn find_windows_wireguard() -> Result<PathBuf, String> {
let candidates = [