aboutsummaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/atuin-client/config.toml5
-rw-r--r--crates/atuin-client/src/settings.rs5
-rw-r--r--crates/atuin-daemon/Cargo.toml3
-rw-r--r--crates/atuin-daemon/src/server.rs55
4 files changed, 61 insertions, 7 deletions
diff --git a/crates/atuin-client/config.toml b/crates/atuin-client/config.toml
index 49e06c45..4938991a 100644
--- a/crates/atuin-client/config.toml
+++ b/crates/atuin-client/config.toml
@@ -223,5 +223,10 @@ records = true
## windows: Not Supported
# socket_path = "~/.local/share/atuin/atuin.sock"
+## Use systemd socket activation rather than opening the given path (the path must still be correct for the client)
+## linux: false
+## mac/windows: Not Supported
+# systemd_socket = false
+
## The port that should be used for TCP on non unix systems
# tcp_port = 8889
diff --git a/crates/atuin-client/src/settings.rs b/crates/atuin-client/src/settings.rs
index a97d05eb..f4434e41 100644
--- a/crates/atuin-client/src/settings.rs
+++ b/crates/atuin-client/src/settings.rs
@@ -350,6 +350,9 @@ pub struct Daemon {
/// The path to the unix socket used by the daemon
pub socket_path: String,
+ /// Use a socket passed via systemd's socket activation protocol, instead of the path
+ pub systemd_socket: bool,
+
/// The port that should be used for TCP on non unix systems
pub tcp_port: u64,
}
@@ -368,6 +371,7 @@ impl Default for Daemon {
enabled: false,
sync_frequency: 300,
socket_path: "".to_string(),
+ systemd_socket: false,
tcp_port: 8889,
}
}
@@ -715,6 +719,7 @@ impl Settings {
.set_default("daemon.sync_frequency", 300)?
.set_default("daemon.enabled", false)?
.set_default("daemon.socket_path", socket_path.to_str())?
+ .set_default("daemon.systemd_socket", false)?
.set_default("daemon.tcp_port", 8889)?
.set_default(
"prefers_reduced_motion",
diff --git a/crates/atuin-daemon/Cargo.toml b/crates/atuin-daemon/Cargo.toml
index 390cb28f..e4c4779b 100644
--- a/crates/atuin-daemon/Cargo.toml
+++ b/crates/atuin-daemon/Cargo.toml
@@ -32,5 +32,8 @@ prost-types = "0.12"
tokio-stream = {version="0.1.14", features=["net"]}
rand.workspace = true
+[target.'cfg(target_os = "linux")'.dependencies]
+listenfd = "1.0.1"
+
[build-dependencies]
tonic-build = "0.11"
diff --git a/crates/atuin-daemon/src/server.rs b/crates/atuin-daemon/src/server.rs
index 77824f60..1cfcef51 100644
--- a/crates/atuin-daemon/src/server.rs
+++ b/crates/atuin-daemon/src/server.rs
@@ -133,7 +133,7 @@ impl HistorySvc for HistoryService {
}
#[cfg(unix)]
-async fn shutdown_signal(socket: PathBuf) {
+async fn shutdown_signal(socket: Option<PathBuf>) {
let mut term = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
.expect("failed to register sigterm handler");
let mut int = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::interrupt())
@@ -145,7 +145,9 @@ async fn shutdown_signal(socket: PathBuf) {
}
eprintln!("Removing socket...");
- std::fs::remove_file(socket).expect("failed to remove socket");
+ if let Some(socket) = socket {
+ std::fs::remove_file(socket).expect("failed to remove socket");
+ }
eprintln!("Shutting down...");
}
@@ -163,15 +165,54 @@ async fn start_server(settings: Settings, history: HistoryService) -> Result<()>
use tokio::net::UnixListener;
use tokio_stream::wrappers::UnixListenerStream;
- let socket = settings.daemon.socket_path.clone();
+ let socket_path = settings.daemon.socket_path;
- let uds = UnixListener::bind(socket.clone())?;
- let uds_stream = UnixListenerStream::new(uds);
+ let (uds, cleanup) = if cfg!(target_os = "linux") && settings.daemon.systemd_socket {
+ #[cfg(target_os = "linux")]
+ {
+ use eyre::OptionExt;
+ tracing::info!("getting systemd socket");
+ let listener = listenfd::ListenFd::from_env()
+ .take_unix_listener(0)?
+ .ok_or_eyre("missing systemd socket")?;
+ listener.set_nonblocking(true)?;
+ let actual_path = listener
+ .local_addr()
+ .context("getting systemd socket's path")
+ .and_then(|addr| {
+ addr.as_pathname()
+ .ok_or_eyre("systemd socket missing path")
+ .map(|path| path.to_owned())
+ });
+ match actual_path {
+ Ok(actual_path) => {
+ tracing::info!("listening on systemd socket: {actual_path:?}");
+ if actual_path != std::path::Path::new(&socket_path) {
+ tracing::warn!(
+ "systemd socket is not at configured client path: {socket_path:?}"
+ );
+ }
+ }
+ Err(err) => {
+ tracing::warn!("could not detect systemd socket path, ensure that it's at the configured path: {socket_path:?}, error: {err:?}");
+ }
+ }
+ (UnixListener::from_std(listener)?, false)
+ }
+ #[cfg(not(target_os = "linux"))]
+ unreachable!()
+ } else {
+ tracing::info!("listening on unix socket {socket_path:?}");
+ (UnixListener::bind(socket_path.clone())?, true)
+ };
- tracing::info!("listening on unix socket {:?}", socket);
+ let uds_stream = UnixListenerStream::new(uds);
Server::builder()
.add_service(HistoryServer::new(history))
- .serve_with_incoming_shutdown(uds_stream, shutdown_signal(socket.into()))
+ .serve_with_incoming_shutdown(
+ uds_stream,
+ shutdown_signal(cleanup.then_some(socket_path.into())),
+ )
.await?;
Ok(())
}