Skip to content

Commit 9c05593

Browse files
committed
chore: streamline config reload
1 parent d44599f commit 9c05593

File tree

4 files changed

+60
-19
lines changed

4 files changed

+60
-19
lines changed

docs/errors.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
- Configuration errors:
3434
- [Missing or invalid TLS configuration](#config-missing-or-invalid-tls)
35+
- [Network configuration change requires restart](#config-network-change-requires-restart)
36+
3537
<!-- ---------------------------------------------------------------------------------------------------- -->
3638

3739
<!-- ---------------------------------------------------------------------------------------------------- -->
@@ -651,3 +653,35 @@ Check that the certificate and private key are valid.
651653

652654

653655
<!-- ---------------------------------------------------------------------------------------------------- -->
656+
657+
658+
## Network configuration change requires restart <a id='config-network-change-requires-restart'></a>
659+
660+
A configuration reload was attempted with network-level changes that require a full restart.
661+
662+
### Error message
663+
664+
```
665+
Network configuration change requires restart
666+
```
667+
668+
### Notes
669+
670+
When receiving a SIGHUP signal, CipherStash Proxy attempts to reload application-level configuration without disrupting active connections. However, certain network-related configuration changes require stopping and restarting the proxy service to take effect.
671+
672+
The following settings require a restart when changed:
673+
- `server.host` - The host address the proxy listens on
674+
- `server.port` - The port the proxy listens on
675+
- `server.require_tls` - TLS requirement setting
676+
- `server.worker_threads` - Number of worker threads
677+
- `tls` - Any TLS certificate or key configuration
678+
679+
### How to fix
680+
681+
1. Stop the CipherStash Proxy service
682+
2. Update the configuration as needed
683+
3. Restart the CipherStash Proxy service
684+
685+
Application-level configuration changes (database, auth, encrypt, log, prometheus, development) can be reloaded without restart using SIGHUP.
686+
687+
<!-- ---------------------------------------------------------------------------------------------------- -->

packages/cipherstash-proxy/src/config/tls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{error::TlsConfigError, log::CONFIG};
1010
/// Server TLS Configuration
1111
/// This is listener/inbound connection config
1212
///
13-
#[derive(Clone, Debug, Deserialize)]
13+
#[derive(Clone, Debug, Deserialize, PartialEq)]
1414
#[serde(untagged)]
1515
pub enum TlsConfig {
1616
Pem {

packages/cipherstash-proxy/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ pub enum ConfigError {
176176
#[error("Expected an Encrypt configuration table")]
177177
MissingEncryptConfigTable,
178178

179+
#[error("Network configuration change requires restart For help visit {}#config-network-change-requires-restart", ERROR_DOC_BASE_URL)]
180+
NetworkConfigurationChangeRequiresRestart,
181+
179182
#[error(transparent)]
180183
Parse(#[from] serde_json::Error),
181184

packages/cipherstash-proxy/src/main.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use cipherstash_proxy::config::TandemConfig;
22
use cipherstash_proxy::connect::{self, AsyncStream};
3-
use cipherstash_proxy::error::Error;
3+
use cipherstash_proxy::error::{ConfigError, Error};
44
use cipherstash_proxy::prometheus::CLIENTS_ACTIVE_CONNECTIONS;
55
use cipherstash_proxy::proxy::Proxy;
66
use cipherstash_proxy::{cli, log, postgresql as pg, prometheus, tls, Args};
77
use clap::Parser;
88
use metrics::gauge;
9-
use tokio::net::TcpListener;
109
use tokio::signal::unix::{signal, SignalKind};
1110
use tokio_util::task::TaskTracker;
1211
use tracing::{error, info, warn};
@@ -55,7 +54,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
5554

5655
let mut proxy = init(config).await;
5756

58-
let mut listener = connect::bind_with_retry(&proxy.config.server).await;
57+
let listener = connect::bind_with_retry(&proxy.config.server).await;
5958
let tracker = TaskTracker::new();
6059

6160
let mut client_id = 0;
@@ -81,13 +80,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
8180
break;
8281
},
8382
_ = sighup() => {
84-
info!(msg = "Received SIGHUP. Reloading configuration");
85-
(listener, proxy) = match reload_config(listener, &args).await {
86-
Ok((listener, proxy)) => (listener, proxy),
87-
Err(_) => todo!(),
88-
};
89-
90-
info!(msg = "Reloaded configuration");
83+
info!(msg = "Received SIGHUP. Reloading application configuration");
84+
proxy = reload_application_config(&proxy.config, &args).await.unwrap_or(proxy);
9185
},
9286
_ = sigterm() => {
9387
info!(msg = "Received SIGTERM");
@@ -264,7 +258,15 @@ async fn sighup() -> std::io::Result<()> {
264258
Ok(())
265259
}
266260

267-
async fn reload_config(listener: TcpListener, args: &Args) -> Result<(TcpListener, Proxy), Error> {
261+
fn has_network_config_changed(current: &TandemConfig, new: &TandemConfig) -> bool {
262+
current.server.host != new.server.host
263+
|| current.server.port != new.server.port
264+
|| current.server.require_tls != new.server.require_tls
265+
|| current.server.worker_threads != new.server.worker_threads
266+
|| current.tls != new.tls
267+
}
268+
269+
async fn reload_application_config(config: &TandemConfig, args: &Args) -> Result<Proxy, Error> {
268270
let new_config = match TandemConfig::load(args) {
269271
Ok(config) => config,
270272
Err(err) => {
@@ -276,13 +278,15 @@ async fn reload_config(listener: TcpListener, args: &Args) -> Result<(TcpListene
276278
}
277279
};
278280

279-
let new_proxy = init(new_config).await;
281+
// Check for network config changes that require restart
282+
if has_network_config_changed(config, &new_config) {
283+
let err = ConfigError::NetworkConfigurationChangeRequiresRestart;
284+
warn!(msg = err.to_string());
280285

281-
// Explicit drop needed here to free the network resources before binding if using the same address & port
282-
std::mem::drop(listener);
286+
return Err(err.into());
287+
}
283288

284-
Ok((
285-
connect::bind_with_retry(&new_proxy.config.server).await,
286-
new_proxy,
287-
))
289+
info!(msg = "Configuration reloaded");
290+
let proxy = init(new_config).await;
291+
Ok(proxy)
288292
}

0 commit comments

Comments
 (0)