veilid/veilid-server/src/unix.rs

119 lines
3.9 KiB
Rust
Raw Normal View History

2022-05-16 15:52:48 +00:00
use crate::server::*;
2022-01-15 23:50:56 +00:00
use crate::settings::Settings;
2022-06-28 03:46:29 +00:00
use crate::tools::*;
2022-05-16 15:52:48 +00:00
use crate::veilid_logs::*;
2022-07-07 03:15:51 +00:00
use crate::*;
2022-01-15 23:50:56 +00:00
use clap::ArgMatches;
2022-06-29 14:34:23 +00:00
use futures_util::StreamExt;
2022-05-16 15:52:48 +00:00
use signal_hook::consts::signal::*;
use signal_hook_async_std::Signals;
2022-05-28 14:07:57 +00:00
use std::io::Read;
2022-06-10 21:07:10 +00:00
use tracing::*;
2021-11-22 16:28:30 +00:00
2022-06-10 21:07:10 +00:00
#[instrument(skip(signals))]
2022-05-16 15:52:48 +00:00
async fn handle_signals(mut signals: Signals) {
while let Some(signal) = signals.next().await {
match signal {
SIGHUP => {
// XXX: reload configuration?
}
SIGTERM | SIGINT | SIGQUIT => {
// Shutdown the system;
shutdown();
}
_ => unreachable!(),
}
}
}
2022-06-10 21:07:10 +00:00
#[instrument(err)]
2022-07-07 03:15:51 +00:00
pub fn run_daemon(settings: Settings, _matches: ArgMatches) -> EyreResult<()> {
2022-05-16 15:52:48 +00:00
let daemon = {
let mut daemon = daemonize::Daemonize::new();
let s = settings.read();
2022-05-28 14:07:57 +00:00
if let Some(pid_file) = s.daemon.pid_file.clone() {
daemon = daemon.pid_file(pid_file.clone()); //.chown_pid_file(true);
daemon = daemon.exit_action(move || {
// wait for pid file to exist before exiting parent
let pid_path = std::path::Path::new(&pid_file);
loop {
if let Ok(mut f) = std::fs::File::open(pid_path) {
let mut s = String::new();
if f.read_to_string(&mut s).is_ok()
&& !s.is_empty()
&& s.parse::<u32>().is_ok()
{
println!("pidfile found");
break;
}
}
std::thread::sleep(std::time::Duration::from_millis(100));
}
})
2022-05-16 15:52:48 +00:00
}
if let Some(chroot) = &s.daemon.chroot {
daemon = daemon.chroot(chroot);
}
if let Some(working_directory) = &s.daemon.working_directory {
daemon = daemon.working_directory(working_directory);
}
if let Some(user) = &s.daemon.user {
daemon = daemon.user(user.as_str());
}
if let Some(group) = &s.daemon.group {
daemon = daemon.group(group.as_str());
}
let stdout_file = if let Some(stdout_file) = &s.daemon.stdout_file {
2022-07-07 03:15:51 +00:00
Some(std::fs::File::create(stdout_file).wrap_err("Failed to create stdio file")?)
2022-05-16 15:52:48 +00:00
} else {
None
};
if let Some(stderr_file) = &s.daemon.stderr_file {
if Some(stderr_file) == s.daemon.stdout_file.as_ref() {
// same output file for stderr and stdout
daemon = daemon.stderr(
stdout_file
.as_ref()
.unwrap()
.try_clone()
2022-07-07 03:15:51 +00:00
.wrap_err("Failed to clone stdout file")?,
2022-05-16 15:52:48 +00:00
);
} else {
daemon = daemon.stderr(
2022-07-07 03:15:51 +00:00
std::fs::File::create(stderr_file).wrap_err("Failed to create stderr file")?,
2022-05-16 15:52:48 +00:00
);
}
}
if let Some(stdout_file) = stdout_file {
daemon = daemon.stdout(stdout_file);
}
daemon
};
// Now, run the server
2022-06-28 03:46:29 +00:00
block_on(async {
2022-06-11 22:47:58 +00:00
// Init combined console/file logger
2022-07-01 16:13:52 +00:00
let veilid_logs = VeilidLogs::setup(settings.clone())?;
2022-06-11 22:47:58 +00:00
// Daemonize
2022-07-07 03:15:51 +00:00
daemon.start().wrap_err("Failed to daemonize")?;
2022-06-11 22:47:58 +00:00
2022-05-16 15:52:48 +00:00
// Catch signals
2022-07-07 03:15:51 +00:00
let signals =
Signals::new(&[SIGHUP, SIGTERM, SIGINT, SIGQUIT]).wrap_err("failed to init signals")?;
2022-05-16 15:52:48 +00:00
let handle = signals.handle();
2022-06-28 03:46:29 +00:00
let signals_task = spawn(handle_signals(signals));
2022-05-16 15:52:48 +00:00
2022-07-01 16:13:52 +00:00
let res = run_veilid_server(settings, ServerMode::Normal, veilid_logs).await;
2022-05-16 15:52:48 +00:00
// Terminate the signal stream.
handle.close();
2022-06-29 14:13:49 +00:00
let _ = signals_task.await;
2022-05-16 15:52:48 +00:00
res
})
2021-11-22 16:28:30 +00:00
}