fix(reload): Store paths to config files for admin reload
Paths given via --config at startup are now stored inside the config struct at runtime, to make it possible to reload config without setting an env var for the config file location.
This commit is contained in:
parent
64e187e5b4
commit
867d0ab671
4 changed files with 42 additions and 26 deletions
|
|
@ -30,10 +30,31 @@ pub(super) async fn show_config(&self) -> Result {
|
|||
|
||||
#[admin_command]
|
||||
pub(super) async fn reload_config(&self, path: Option<PathBuf>) -> Result {
|
||||
let path = path.as_deref().into_iter();
|
||||
self.services.config.reload(path)?;
|
||||
// The path argument is only what's optionally passed via the admin command,
|
||||
// so we need to merge it with the existing paths if any were given at startup.
|
||||
let mut paths = Vec::new();
|
||||
|
||||
self.write_str("Successfully reconfigured.").await
|
||||
// Add previously saved paths to the argument list
|
||||
self.services
|
||||
.config
|
||||
.config_paths
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.for_each(|p| paths.push(p.to_owned()));
|
||||
|
||||
// If a path is given, and it's not already in the list,
|
||||
// add it last, so that it overrides earlier files
|
||||
if let Some(p) = path {
|
||||
if !paths.contains(&p) {
|
||||
paths.push(p);
|
||||
}
|
||||
}
|
||||
|
||||
self.services.config.reload(&paths)?;
|
||||
|
||||
self.write_str(&format!("Successfully reconfigured from paths: {paths:?}"))
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ pub mod proxy;
|
|||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||
path::{Path, PathBuf},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use conduwuit_macros::config_example_generator;
|
||||
|
|
@ -53,9 +53,13 @@ use crate::{Result, err, error::Error, utils::sys};
|
|||
### For more information, see:
|
||||
### https://continuwuity.org/configuration.html
|
||||
"#,
|
||||
ignore = "catchall well_known tls blurhashing allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure"
|
||||
ignore = "config_paths catchall well_known tls blurhashing allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure"
|
||||
)]
|
||||
pub struct Config {
|
||||
// Paths to config file(s). Not supposed to be set manually in the config file,
|
||||
// only updated dynamically from the --config option given at runtime.
|
||||
pub config_paths: Option<Vec<PathBuf>>,
|
||||
|
||||
/// The server_name is the pretty name of this server. It is used as a
|
||||
/// suffix for user and room IDs/aliases.
|
||||
///
|
||||
|
|
@ -2226,26 +2230,24 @@ const DEPRECATED_KEYS: &[&str; 9] = &[
|
|||
|
||||
impl Config {
|
||||
/// Pre-initialize config
|
||||
pub fn load<'a, I>(paths: I) -> Result<Figment>
|
||||
where
|
||||
I: Iterator<Item = &'a Path>,
|
||||
{
|
||||
pub fn load(paths: &[PathBuf]) -> Result<Figment> {
|
||||
let envs = [
|
||||
Env::var("CONDUIT_CONFIG"),
|
||||
Env::var("CONDUWUIT_CONFIG"),
|
||||
Env::var("CONTINUWUITY_CONFIG"),
|
||||
];
|
||||
|
||||
let config = envs
|
||||
let mut config = envs
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(Toml::file)
|
||||
.chain(paths.map(Toml::file))
|
||||
.chain(paths.iter().cloned().map(Toml::file))
|
||||
.fold(Figment::new(), |config, file| config.merge(file.nested()))
|
||||
.merge(Env::prefixed("CONDUIT_").global().split("__"))
|
||||
.merge(Env::prefixed("CONDUWUIT_").global().split("__"))
|
||||
.merge(Env::prefixed("CONTINUWUITY_").global().split("__"));
|
||||
|
||||
config = config.join(("config_paths", paths));
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{path::PathBuf, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use conduwuit_core::{
|
||||
Error, Result,
|
||||
|
|
@ -38,14 +38,9 @@ impl Server {
|
|||
) -> Result<Arc<Self>, Error> {
|
||||
let _runtime_guard = runtime.map(runtime::Handle::enter);
|
||||
|
||||
let config_paths = args
|
||||
.config
|
||||
.as_deref()
|
||||
.into_iter()
|
||||
.flat_map(<[_]>::iter)
|
||||
.map(PathBuf::as_path);
|
||||
let config_paths = args.config.clone().unwrap_or_default();
|
||||
|
||||
let config = Config::load(config_paths)
|
||||
let config = Config::load(&config_paths)
|
||||
.and_then(|raw| update(raw, args))
|
||||
.and_then(|raw| Config::new(&raw))?;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{iter, ops::Deref, path::Path, sync::Arc};
|
||||
use std::{ops::Deref, path::PathBuf, sync::Arc};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use conduwuit::{
|
||||
|
|
@ -51,7 +51,8 @@ fn handle_reload(&self) -> Result {
|
|||
])
|
||||
.expect("failed to notify systemd of reloading state");
|
||||
|
||||
self.reload(iter::empty())?;
|
||||
let config_paths = self.server.config.config_paths.clone().unwrap_or_default();
|
||||
self.reload(&config_paths)?;
|
||||
|
||||
#[cfg(all(feature = "systemd", target_os = "linux"))]
|
||||
sd_notify::notify(false, &[sd_notify::NotifyState::Ready])
|
||||
|
|
@ -62,10 +63,7 @@ fn handle_reload(&self) -> Result {
|
|||
}
|
||||
|
||||
#[implement(Service)]
|
||||
pub fn reload<'a, I>(&self, paths: I) -> Result<Arc<Config>>
|
||||
where
|
||||
I: Iterator<Item = &'a Path>,
|
||||
{
|
||||
pub fn reload(&self, paths: &[PathBuf]) -> Result<Arc<Config>> {
|
||||
let old = self.server.config.clone();
|
||||
let new = Config::load(paths).and_then(|raw| Config::new(&raw))?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue