From 30c9c9dd35d79741689e75440c24cde426d63cd2 Mon Sep 17 00:00:00 2001 From: Stan Bondi Date: Tue, 9 Jan 2024 12:50:19 +0400 Subject: [PATCH] refactor(common): allow custom default configs (#6068) Description --- Adds `load_configuration_with_overrides` that exposes the functionality to load configs without including the prompting and compiled in config templates. Motivation and Context --- On the tari-dan repo, we want to customize the default configurations without having to PR to the tari repo. L2-related configs can be managed in the tari-dan repo and can be removed from this repo in a subsequent PR. How Has This Been Tested? --- Manually by starting a new base node and checking the config.toml What process can a PR reviewer use to test or verify this change? --- Base node default config works as before Breaking Changes --- - [x] None - [ ] Requires data directory on base node to be deleted - [ ] Requires hard fork - [ ] Other - Please specify Co-authored-by: SW van Heerden --- common/src/configuration/utils.rs | 60 +++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/common/src/configuration/utils.rs b/common/src/configuration/utils.rs index e67d03ef7a..4985b23c6b 100644 --- a/common/src/configuration/utils.rs +++ b/common/src/configuration/utils.rs @@ -20,6 +20,8 @@ use crate::{ //------------------------------------- Main API functions --------------------------------------// +/// Loads the configuration file from the specified path, or creates a new one with the embedded default presets if it +/// does not. This also prompts the user. pub fn load_configuration, TOverride: ConfigOverrideProvider>( config_path: P, create_if_not_exists: bool, @@ -29,12 +31,26 @@ pub fn load_configuration, TOverride: ConfigOverrideProvider>( debug!( target: LOG_TARGET, "Loading configuration file from {}", - config_path.as_ref().to_str().unwrap_or("[??]") + config_path.as_ref().display() ); if !config_path.as_ref().exists() && create_if_not_exists { - write_default_config_to(&config_path, non_interactive) + let sources = if non_interactive { + get_default_config(false) + } else { + prompt_default_config() + }; + write_config_to(&config_path, &sources) .map_err(|io| ConfigError::new("Could not create default config", Some(io.to_string())))?; } + + load_configuration_with_overrides(config_path, overrides) +} + +/// Loads the config at the given path applying all overrides. +pub fn load_configuration_with_overrides, TOverride: ConfigOverrideProvider>( + config_path: P, + overrides: &TOverride, +) -> Result { let filename = config_path .as_ref() .to_str() @@ -84,27 +100,28 @@ pub fn load_configuration, TOverride: ConfigOverrideProvider>( Ok(cfg) } -/// Installs a new configuration file template, copied from the application type's preset and written to the given path. +/// Returns a new configuration file template in parts from the embedded presets. If non_interactive is false, the user +/// is prompted to select if they would like to select a base node configuration that enables mining or not. /// Also includes the common configuration defined in `config/presets/common.toml`. -pub fn write_default_config_to>(path: P, non_interactive: bool) -> Result<(), std::io::Error> { - // Use the same config file so that all the settings are easier to find, and easier to - // support users over chat channels - let mine = if non_interactive { - false - } else { - prompt( - "Node config does not exist.\nWould you like to mine (Y/n)?\nNOTE: this will enable gprc methods that can \ - leak private info on the node", - ) - }; - let base_node_deny_methods = if mine { +pub fn prompt_default_config() -> [&'static str; 12] { + let mine = prompt( + "Node config does not exist.\nWould you like to mine (Y/n)?\nNOTE: this will enable additional gRPC methods \ + that could be used to monitor and submit blocks from this node.", + ); + get_default_config(mine) +} + +/// Returns the default configuration file template in parts from the embedded presets. If use_mining_config is true, +/// the base node configuration that enables mining is returned, otherwise the non-mining configuration is returned. +pub fn get_default_config(use_mining_config: bool) -> [&'static str; 12] { + let base_node_deny_methods = if use_mining_config { include_str!("../../config/presets/c_base_node_b_mining_deny_methods.toml") } else { include_str!("../../config/presets/c_base_node_b_non_mining_deny_methods.toml") }; let common = include_str!("../../config/presets/a_common.toml"); - let source = [ + [ common, include_str!("../../config/presets/b_peer_seeds.toml"), include_str!("../../config/presets/c_base_node_a.toml"), @@ -118,13 +135,20 @@ pub fn write_default_config_to>(path: P, non_interactive: bool) - include_str!("../../config/presets/i_indexer.toml"), include_str!("../../config/presets/j_dan_wallet_daemon.toml"), ] - .join("\n"); +} +/// Writes a single file concatenating all the provided sources to the specified path. If the parent directory does not +/// exist, it is created. If the file already exists, it is overwritten. +pub fn write_config_to>(path: P, sources: &[&str]) -> Result<(), std::io::Error> { if let Some(d) = path.as_ref().parent() { fs::create_dir_all(d)? }; let mut file = File::create(path)?; - file.write_all(source.as_ref()) + for source in sources { + file.write_all(source.as_bytes())?; + file.write_all(b"\n")?; + } + Ok(()) } pub fn serialize_string(source: &T, ser: S) -> Result