feat: socket-activate the hive-c0re admin socket
Add a systemd.sockets.hive-c0re unit that holds /run/hyperhive/host.sock before hive-c0re starts. hive-c0re serve() detects LISTEN_FDS via the listenfd crate and accepts the systemd-handed fd instead of calling bind(). Falls back to the existing bind path when LISTEN_FDS is absent so direct invocation and CI are unaffected. Benefits: hivectl can connect the moment the socket unit activates (no racy window), and a hive-c0re restart never drops the socket inode.
This commit is contained in:
parent
19e7d8d5d3
commit
f8c0f64fd4
3 changed files with 54 additions and 10 deletions
|
|
@ -11,16 +11,33 @@ use crate::coordinator::Coordinator;
|
|||
use crate::lifecycle;
|
||||
|
||||
pub async fn serve(socket: &Path, coord: Arc<Coordinator>) -> Result<()> {
|
||||
if let Some(parent) = socket.parent() {
|
||||
std::fs::create_dir_all(parent)
|
||||
.with_context(|| format!("create socket parent {}", parent.display()))?;
|
||||
}
|
||||
if socket.exists() {
|
||||
std::fs::remove_file(socket).context("remove stale socket")?;
|
||||
}
|
||||
|
||||
let listener = UnixListener::bind(socket)
|
||||
.with_context(|| format!("bind admin socket {}", socket.display()))?;
|
||||
// Prefer a socket passed by systemd socket-activation (LISTEN_FDS).
|
||||
// When running under a `.socket` unit, systemd has already created,
|
||||
// bound, and chmod-ed the socket for us — we just accept on it.
|
||||
// Fall back to the traditional bind path when not socket-activated
|
||||
// (direct invocation, dev, tests).
|
||||
let listener = {
|
||||
let mut listenfd = listenfd::ListenFd::from_env();
|
||||
if let Some(std_listener) = listenfd
|
||||
.take_unix_listener(0)
|
||||
.context("take socket-activated unix listener")?
|
||||
{
|
||||
std_listener.set_nonblocking(true)?;
|
||||
UnixListener::from_std(std_listener)
|
||||
.context("convert socket-activated listener to tokio")?
|
||||
} else {
|
||||
// Standalone: create parent dir, remove any stale socket, bind.
|
||||
if let Some(parent) = socket.parent() {
|
||||
std::fs::create_dir_all(parent)
|
||||
.with_context(|| format!("create socket parent {}", parent.display()))?;
|
||||
}
|
||||
if socket.exists() {
|
||||
std::fs::remove_file(socket).context("remove stale socket")?;
|
||||
}
|
||||
UnixListener::bind(socket)
|
||||
.with_context(|| format!("bind admin socket {}", socket.display()))?
|
||||
}
|
||||
};
|
||||
tracing::info!(socket = %socket.display(), hyperhive_flake = %coord.hyperhive_flake, "hive-c0re admin listening");
|
||||
|
||||
loop {
|
||||
|
|
|
|||
Loading…
Reference in a new issue