mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
chore(gui-client): fix papercuts (#5792)
Closes #5789 The SIGTERM catching would have helped debug #5790 ```[tasklist] ### Tasks - [x] catch SIGTERM and log when systemd shuts us down gracefully - [x] Log architecture at startup ```
This commit is contained in:
@@ -158,6 +158,7 @@ fn fix_log_filter(settings: &mut AdvancedSettings) -> Result<()> {
|
||||
fn start_logging(directives: &str) -> Result<logging::Handles> {
|
||||
let logging_handles = logging::setup(directives)?;
|
||||
tracing::info!(
|
||||
arch = std::env::consts::ARCH,
|
||||
?directives,
|
||||
?GIT_VERSION,
|
||||
system_uptime_seconds = firezone_headless_client::uptime::get().map(|dur| dur.as_secs()),
|
||||
|
||||
@@ -91,26 +91,40 @@ pub fn run_only_ipc_service() -> Result<()> {
|
||||
|
||||
fn run_debug_ipc_service() -> Result<()> {
|
||||
crate::setup_stdout_logging()?;
|
||||
tracing::info!(
|
||||
arch = std::env::consts::ARCH,
|
||||
git_version = crate::GIT_VERSION,
|
||||
system_uptime_seconds = crate::uptime::get().map(|dur| dur.as_secs()),
|
||||
);
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
let _guard = rt.enter();
|
||||
let mut signals = Signals::new()?;
|
||||
|
||||
// Couldn't get the loop to work here yet, so SIGHUP is not implemented
|
||||
rt.block_on(async {
|
||||
let ipc_service = pin!(ipc_listen());
|
||||
rt.block_on(ipc_listen_with_signals(&mut signals))
|
||||
}
|
||||
|
||||
match future::select(pin!(signals.recv()), ipc_service).await {
|
||||
future::Either::Left((SignalKind::Hangup, _)) => {
|
||||
bail!("Exiting, SIGHUP not implemented for the IPC service");
|
||||
}
|
||||
future::Either::Left((SignalKind::Interrupt, _)) => {
|
||||
tracing::info!("Caught Interrupt signal");
|
||||
Ok(())
|
||||
}
|
||||
future::Either::Right((Ok(impossible), _)) => match impossible {},
|
||||
future::Either::Right((Err(error), _)) => Err(error).context("ipc_listen failed"),
|
||||
/// Run the IPC service, and exit if we catch any signals
|
||||
///
|
||||
/// Shared between the Linux systemd service and the debug subcommand
|
||||
/// TODO: Better name
|
||||
async fn ipc_listen_with_signals(signals: &mut Signals) -> Result<()> {
|
||||
let ipc_service = pin!(ipc_listen());
|
||||
|
||||
match future::select(pin!(signals.recv()), ipc_service).await {
|
||||
future::Either::Left((SignalKind::Hangup, _)) => {
|
||||
bail!("Exiting, SIGHUP not implemented for the IPC service");
|
||||
}
|
||||
})
|
||||
future::Either::Left((SignalKind::Interrupt, _)) => {
|
||||
tracing::info!("Caught SIGINT");
|
||||
Ok(())
|
||||
}
|
||||
future::Either::Left((SignalKind::Terminate, _)) => {
|
||||
tracing::info!("Caught SIGTERM");
|
||||
Ok(())
|
||||
}
|
||||
future::Either::Right((Ok(impossible), _)) => match impossible {},
|
||||
future::Either::Right((Err(error), _)) => Err(error).context("ipc_listen failed"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
@@ -332,6 +346,7 @@ fn setup_logging(log_dir: Option<PathBuf>) -> Result<connlib_client_shared::file
|
||||
let subscriber = Registry::default().with(layer.with_filter(filter));
|
||||
set_global_default(subscriber).context("`set_global_default` should always work)")?;
|
||||
tracing::info!(
|
||||
arch = std::env::consts::ARCH,
|
||||
git_version = crate::GIT_VERSION,
|
||||
system_uptime_seconds = crate::uptime::get().map(|dur| dur.as_secs()),
|
||||
?directives
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::CliCommon;
|
||||
use crate::Signals;
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
/// Cross-platform entry point for systemd / Windows services
|
||||
@@ -10,10 +11,10 @@ pub(crate) fn run_ipc_service(cli: CliCommon) -> Result<()> {
|
||||
anyhow::bail!("This is the IPC service binary, it's not meant to run interactively.");
|
||||
}
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
if let Err(error) = rt.block_on(super::ipc_listen()) {
|
||||
tracing::error!(?error, "`ipc_listen` failed");
|
||||
}
|
||||
Ok(())
|
||||
let _guard = rt.enter();
|
||||
let mut signals = Signals::new()?;
|
||||
|
||||
rt.block_on(super::ipc_listen_with_signals(&mut signals))
|
||||
}
|
||||
|
||||
pub(crate) fn install_ipc_service() -> Result<()> {
|
||||
|
||||
@@ -164,6 +164,10 @@ enum SignalKind {
|
||||
Hangup,
|
||||
/// SIGINT
|
||||
Interrupt,
|
||||
/// SIGTERM
|
||||
///
|
||||
/// Not caught on Windows
|
||||
Terminate,
|
||||
}
|
||||
|
||||
/// Sets up logging for stdout only, with INFO level by default
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use super::{SignalKind, TOKEN_ENV_KEY};
|
||||
use anyhow::{bail, Result};
|
||||
use futures::future::{select, Either};
|
||||
use futures::future::FutureExt as _;
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
pin::pin,
|
||||
@@ -15,22 +15,32 @@ const ROOT_GROUP: u32 = 0;
|
||||
const ROOT_USER: u32 = 0;
|
||||
|
||||
pub(crate) struct Signals {
|
||||
/// For reloading settings in the standalone Client
|
||||
sighup: Signal,
|
||||
/// For Ctrl+C from a terminal
|
||||
sigint: Signal,
|
||||
/// For systemd service stopping
|
||||
sigterm: Signal,
|
||||
}
|
||||
|
||||
impl Signals {
|
||||
pub(crate) fn new() -> Result<Self> {
|
||||
let sighup = signal(TokioSignalKind::hangup())?;
|
||||
let sigint = signal(TokioSignalKind::interrupt())?;
|
||||
let sigterm = signal(TokioSignalKind::terminate())?;
|
||||
|
||||
Ok(Self { sighup, sigint })
|
||||
Ok(Self {
|
||||
sighup,
|
||||
sigint,
|
||||
sigterm,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) async fn recv(&mut self) -> SignalKind {
|
||||
match select(pin!(self.sighup.recv()), pin!(self.sigint.recv())).await {
|
||||
Either::Left((_, _)) => SignalKind::Hangup,
|
||||
Either::Right((_, _)) => SignalKind::Interrupt,
|
||||
futures::select! {
|
||||
_ = pin!(self.sighup.recv().fuse()) => SignalKind::Hangup,
|
||||
_ = pin!(self.sigint.recv().fuse()) => SignalKind::Interrupt,
|
||||
_ = pin!(self.sigterm.recv().fuse()) => SignalKind::Terminate,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,10 @@ pub fn run_only_headless_client() -> Result<()> {
|
||||
.unzip();
|
||||
setup_global_subscriber(layer);
|
||||
|
||||
tracing::info!(git_version = crate::GIT_VERSION);
|
||||
tracing::info!(
|
||||
arch = std::env::consts::ARCH,
|
||||
git_version = crate::GIT_VERSION
|
||||
);
|
||||
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
@@ -174,11 +177,15 @@ pub fn run_only_headless_client() -> Result<()> {
|
||||
loop {
|
||||
match future::select(pin!(signals.recv()), pin!(cb_rx.recv())).await {
|
||||
future::Either::Left((SignalKind::Hangup, _)) => {
|
||||
tracing::info!("Caught Hangup signal");
|
||||
tracing::info!("Caught SIGHUP");
|
||||
session.reconnect();
|
||||
}
|
||||
future::Either::Left((SignalKind::Interrupt, _)) => {
|
||||
tracing::info!("Caught Interrupt signal");
|
||||
tracing::info!("Caught SIGINT");
|
||||
return Ok(());
|
||||
}
|
||||
future::Either::Left((SignalKind::Terminate, _)) => {
|
||||
tracing::info!("Caught SIGTERM");
|
||||
return Ok(());
|
||||
}
|
||||
future::Either::Right((None, _)) => {
|
||||
|
||||
Reference in New Issue
Block a user