mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-06-10 08:53:58 +02:00
fix: vpn config discovery
This commit is contained in:
@@ -198,7 +198,12 @@ async fn main() {
|
||||
.required(true)
|
||||
.help("Local SOCKS5 port"),
|
||||
)
|
||||
.arg(Arg::new("action").required(true).help("Action (start)")),
|
||||
.arg(Arg::new("action").required(true).help("Action (start)"))
|
||||
.arg(
|
||||
Arg::new("config-path")
|
||||
.long("config-path")
|
||||
.help("Direct path to the VPN worker config JSON file"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
Command::new("mcp-bridge")
|
||||
@@ -391,6 +396,7 @@ async fn main() {
|
||||
let port = *vpn_matches
|
||||
.get_one::<u16>("port")
|
||||
.expect("port is required");
|
||||
let config_path = vpn_matches.get_one::<String>("config-path");
|
||||
|
||||
if action == "start" {
|
||||
set_high_priority();
|
||||
@@ -398,8 +404,37 @@ async fn main() {
|
||||
log::info!("VPN worker starting, config id: {}", id);
|
||||
log::info!("Process PID: {}", std::process::id());
|
||||
|
||||
// Retry config loading to handle file system race condition
|
||||
let config = {
|
||||
let config = if let Some(path) = config_path {
|
||||
// Load config directly from the provided path
|
||||
log::info!("Loading VPN worker config from: {}", path);
|
||||
match std::fs::read_to_string(path) {
|
||||
Ok(content) => match serde_json::from_str::<
|
||||
donutbrowser_lib::vpn_worker_storage::VpnWorkerConfig,
|
||||
>(&content)
|
||||
{
|
||||
Ok(config) => {
|
||||
log::info!(
|
||||
"Found VPN worker config: id={}, vpn_type={}, vpn_id={}",
|
||||
config.id,
|
||||
config.vpn_type,
|
||||
config.vpn_id
|
||||
);
|
||||
config
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to parse VPN worker config from {}: {}", path, e);
|
||||
process::exit(1);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to read VPN worker config from {}: {}", path, e);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Fallback: discover config by ID with retries
|
||||
let storage_dir = donutbrowser_lib::proxy_storage::get_storage_dir();
|
||||
log::info!("Looking for VPN worker config in: {:?}", storage_dir);
|
||||
let mut attempts = 0;
|
||||
loop {
|
||||
if let Some(config) = donutbrowser_lib::vpn_worker_storage::get_vpn_worker_config(id) {
|
||||
@@ -412,20 +447,21 @@ async fn main() {
|
||||
break config;
|
||||
}
|
||||
attempts += 1;
|
||||
if attempts >= 10 {
|
||||
if attempts >= 50 {
|
||||
log::error!(
|
||||
"VPN worker configuration {} not found after {} attempts",
|
||||
"VPN worker configuration {} not found after {} attempts in {:?}",
|
||||
id,
|
||||
attempts
|
||||
attempts,
|
||||
storage_dir
|
||||
);
|
||||
process::exit(1);
|
||||
}
|
||||
log::info!(
|
||||
"VPN worker config {} not found yet, retrying ({}/10)...",
|
||||
"VPN worker config {} not found yet, retrying ({}/50)...",
|
||||
id,
|
||||
attempts
|
||||
);
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@ use crate::proxy_runner::find_sidecar_executable;
|
||||
use crate::proxy_storage::is_process_running;
|
||||
use crate::vpn_worker_storage::{
|
||||
delete_vpn_worker_config, find_vpn_worker_by_vpn_id, generate_vpn_worker_id,
|
||||
get_vpn_worker_config, list_vpn_worker_configs, save_vpn_worker_config, VpnWorkerConfig,
|
||||
get_vpn_worker_config, list_vpn_worker_configs, save_vpn_worker_config, vpn_worker_config_path,
|
||||
VpnWorkerConfig,
|
||||
};
|
||||
use std::process::Stdio;
|
||||
|
||||
@@ -175,6 +176,8 @@ pub async fn start_vpn_worker(vpn_id: &str) -> Result<VpnWorkerConfig, Box<dyn s
|
||||
);
|
||||
save_vpn_worker_config(&config)?;
|
||||
|
||||
let config_json_path = vpn_worker_config_path(&id);
|
||||
|
||||
// Spawn detached VPN worker process
|
||||
let exe = find_sidecar_executable("donut-proxy")?;
|
||||
|
||||
@@ -190,6 +193,8 @@ pub async fn start_vpn_worker(vpn_id: &str) -> Result<VpnWorkerConfig, Box<dyn s
|
||||
cmd.arg(&id);
|
||||
cmd.arg("--port");
|
||||
cmd.arg(local_port.to_string());
|
||||
cmd.arg("--config-path");
|
||||
cmd.arg(&config_json_path);
|
||||
|
||||
cmd.stdin(Stdio::null());
|
||||
cmd.stdout(Stdio::null());
|
||||
@@ -235,6 +240,8 @@ pub async fn start_vpn_worker(vpn_id: &str) -> Result<VpnWorkerConfig, Box<dyn s
|
||||
cmd.arg(&id);
|
||||
cmd.arg("--port");
|
||||
cmd.arg(local_port.to_string());
|
||||
cmd.arg("--config-path");
|
||||
cmd.arg(&config_json_path);
|
||||
|
||||
cmd.stdin(Stdio::null());
|
||||
cmd.stdout(Stdio::null());
|
||||
@@ -249,7 +256,8 @@ pub async fn start_vpn_worker(vpn_id: &str) -> Result<VpnWorkerConfig, Box<dyn s
|
||||
|
||||
const DETACHED_PROCESS: u32 = 0x00000008;
|
||||
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
||||
cmd.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP);
|
||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||
cmd.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW);
|
||||
|
||||
let child = cmd.spawn()?;
|
||||
let pid = child.id();
|
||||
|
||||
@@ -27,6 +27,10 @@ impl VpnWorkerConfig {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vpn_worker_config_path(id: &str) -> std::path::PathBuf {
|
||||
get_storage_dir().join(format!("vpn_worker_{}.json", id))
|
||||
}
|
||||
|
||||
pub fn save_vpn_worker_config(config: &VpnWorkerConfig) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let storage_dir = get_storage_dir();
|
||||
fs::create_dir_all(&storage_dir)?;
|
||||
|
||||
Reference in New Issue
Block a user