aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock20
-rw-r--r--Cargo.toml2
-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
-rw-r--r--ui/backend/Cargo.toml2
7 files changed, 79 insertions, 13 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6fc5514b..eaea585d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -326,6 +326,7 @@ dependencies = [
"atuin-history",
"dashmap",
"eyre",
+ "listenfd",
"prost",
"prost-types",
"rand",
@@ -2081,6 +2082,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
+name = "listenfd"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0500463acd96259d219abb05dc57e5a076ef04b2db9a2112846929b5f174c96"
+dependencies = [
+ "libc",
+ "uuid",
+ "winapi",
+]
+
+[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3975,9 +3987,9 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.34"
+version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
+checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
"deranged",
"itoa",
@@ -3998,9 +4010,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
-version = "0.2.17"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
+checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [
"num-conv",
"time-core",
diff --git a/Cargo.toml b/Cargo.toml
index 250523ca..4a7709fc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,7 +19,7 @@ readme = "README.md"
async-trait = "0.1.58"
base64 = "0.22"
log = "0.4"
-time = { version = "=0.3.34", features = [
+time = { version = "0.3.36", features = [
"serde-human-readable",
"macros",
"local-offset",
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(())
}
diff --git a/ui/backend/Cargo.toml b/ui/backend/Cargo.toml
index 1bc40b02..55bfccaa 100644
--- a/ui/backend/Cargo.toml
+++ b/ui/backend/Cargo.toml
@@ -21,7 +21,7 @@ eyre = "0.6"
tauri = { version = "2.0.0-beta", features = ["tray-icon"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
-time = "0.3.34"
+time = "0.3.36"
uuid = "1.7.0"
syntect = "5.2.0"