mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-17 15:51:23 +01:00
Reload TLS config on SIGHUP
This commit is contained in:
parent
39880cc6ac
commit
94d523ebcb
4 changed files with 78 additions and 15 deletions
|
|
@ -144,7 +144,7 @@ trust-dns-resolver = "0.23.2"
|
||||||
xdg = "2.5.2"
|
xdg = "2.5.2"
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
nix = { version = "0.29", features = ["resource"] }
|
nix = { version = "0.29", features = ["resource", "time"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["rocksdb", "sqlite", "systemd"]
|
default = ["rocksdb", "sqlite", "systemd"]
|
||||||
|
|
|
||||||
|
|
@ -251,3 +251,6 @@ This will be the first release of Grapevine since it was forked from Conduit
|
||||||
20. Include the [`traceresponse` header](https://w3c.github.io/trace-context/#traceresponse-header)
|
20. Include the [`traceresponse` header](https://w3c.github.io/trace-context/#traceresponse-header)
|
||||||
if OpenTelemetry Tracing is in use.
|
if OpenTelemetry Tracing is in use.
|
||||||
([!112](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/112))
|
([!112](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/112))
|
||||||
|
21. Sending SIGHUP to the grapevine process now reloads TLS certificates from
|
||||||
|
disk.
|
||||||
|
([!97](https://gitlab.computer.surgery/matrix/grapevine-fork/-/merge_requests/97))
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,7 @@ async fn run_server() -> Result<(), error::Serve> {
|
||||||
|
|
||||||
set_application_state(ApplicationState::Ready);
|
set_application_state(ApplicationState::Ready);
|
||||||
|
|
||||||
tokio::spawn(shutdown_signal(handles));
|
tokio::spawn(handle_signals(tls_config, handles));
|
||||||
|
|
||||||
while let Some(result) = servers.join_next().await {
|
while let Some(result) = servers.join_next().await {
|
||||||
let (listen, result) =
|
let (listen, result) =
|
||||||
|
|
@ -540,28 +540,72 @@ fn routes(config: &Config, components: &HashSet<ListenComponent>) -> Router {
|
||||||
router.route("/", get(it_works)).fallback(not_found)
|
router.route("/", get(it_works)).fallback(not_found)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn shutdown_signal(handles: Vec<ServerHandle>) {
|
async fn reload_tls_config(
|
||||||
let ctrl_c = async {
|
tls_config: &RustlsConfig,
|
||||||
signal::ctrl_c().await.expect("failed to install Ctrl+C handler");
|
) -> Result<(), error::Serve> {
|
||||||
};
|
let config = services()
|
||||||
|
.globals
|
||||||
|
.config
|
||||||
|
.tls
|
||||||
|
.as_ref()
|
||||||
|
.expect("TLS config should exist if TLS listener exists");
|
||||||
|
|
||||||
|
tls_config.reload_from_pem_file(&config.certs, &config.key).await.map_err(
|
||||||
|
|err| error::Serve::LoadCerts {
|
||||||
|
certs: config.certs.clone(),
|
||||||
|
key: config.key.clone(),
|
||||||
|
err,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_signals(
|
||||||
|
tls_config: Option<RustlsConfig>,
|
||||||
|
handles: Vec<ServerHandle>,
|
||||||
|
) {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
let terminate = async {
|
async fn wait_signal(sig: signal::unix::SignalKind) {
|
||||||
signal::unix::signal(signal::unix::SignalKind::terminate())
|
signal::unix::signal(sig)
|
||||||
.expect("failed to install signal handler")
|
.expect("failed to install signal handler")
|
||||||
.recv()
|
.recv()
|
||||||
.await;
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
let terminate = || wait_signal(signal::unix::SignalKind::terminate());
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
let terminate = || std::future::pending::<()>();
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
let sighup = || wait_signal(signal::unix::SignalKind::hangup());
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
let sighup = || std::future::pending::<()>();
|
||||||
|
|
||||||
|
let ctrl_c = || async {
|
||||||
|
signal::ctrl_c().await.expect("failed to install Ctrl+C handler");
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
let sig = loop {
|
||||||
let terminate = std::future::pending::<()>();
|
|
||||||
|
|
||||||
let sig: &str;
|
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
() = ctrl_c => { sig = "Ctrl+C"; },
|
() = sighup() => {
|
||||||
() = terminate => { sig = "SIGTERM"; },
|
info!("Received reload request");
|
||||||
|
|
||||||
|
set_application_state(ApplicationState::Reloading);
|
||||||
|
|
||||||
|
if let Some(tls_config) = tls_config.as_ref() {
|
||||||
|
if let Err(error) = reload_tls_config(tls_config).await {
|
||||||
|
error!(?error, "Failed to reload TLS config");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_application_state(ApplicationState::Ready);
|
||||||
|
},
|
||||||
|
() = terminate() => { break "SIGTERM"; },
|
||||||
|
() = ctrl_c() => { break "Ctrl+C"; },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
warn!(signal = %sig, "Shutting down due to signal");
|
warn!(signal = %sig, "Shutting down due to signal");
|
||||||
|
|
||||||
|
|
|
||||||
16
src/main.rs
16
src/main.rs
|
|
@ -44,6 +44,7 @@ fn version() -> String {
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum ApplicationState {
|
enum ApplicationState {
|
||||||
Ready,
|
Ready,
|
||||||
|
Reloading,
|
||||||
Stopping,
|
Stopping,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,6 +62,21 @@ fn set_application_state(state: ApplicationState) {
|
||||||
|
|
||||||
match state {
|
match state {
|
||||||
ApplicationState::Ready => notify(&[NotifyState::Ready]),
|
ApplicationState::Ready => notify(&[NotifyState::Ready]),
|
||||||
|
ApplicationState::Reloading => {
|
||||||
|
let timespec = nix::time::clock_gettime(
|
||||||
|
nix::time::ClockId::CLOCK_MONOTONIC,
|
||||||
|
)
|
||||||
|
.expect("CLOCK_MONOTONIC should be usable");
|
||||||
|
let monotonic_usec =
|
||||||
|
timespec.tv_sec() * 1_000_000 + timespec.tv_nsec() / 1000;
|
||||||
|
|
||||||
|
notify(&[
|
||||||
|
NotifyState::Reloading,
|
||||||
|
NotifyState::Custom(&format!(
|
||||||
|
"MONOTONIC_USEC={monotonic_usec}",
|
||||||
|
)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
ApplicationState::Stopping => notify(&[NotifyState::Stopping]),
|
ApplicationState::Stopping => notify(&[NotifyState::Stopping]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue