diff --git a/src/admin/server/commands.rs b/src/admin/server/commands.rs index 6027a9eb..8c3573f0 100644 --- a/src/admin/server/commands.rs +++ b/src/admin/server/commands.rs @@ -30,10 +30,31 @@ pub(super) async fn show_config(&self) -> Result { #[admin_command] pub(super) async fn reload_config(&self, path: Option) -> 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] diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index c60d3115..5dcaff5c 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -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>, + /// 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 - where - I: Iterator, - { + pub fn load(paths: &[PathBuf]) -> Result { 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) } diff --git a/src/main/server.rs b/src/main/server.rs index b060dc5a..4c1abc25 100644 --- a/src/main/server.rs +++ b/src/main/server.rs @@ -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, 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))?; diff --git a/src/service/config/mod.rs b/src/service/config/mod.rs index 414c22b6..efeed743 100644 --- a/src/service/config/mod.rs +++ b/src/service/config/mod.rs @@ -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> -where - I: Iterator, -{ +pub fn reload(&self, paths: &[PathBuf]) -> Result> { let old = self.server.config.clone(); let new = Config::load(paths).and_then(|raw| Config::new(&raw))?;