diff --git a/Cargo.lock b/Cargo.lock index ea1da06de14e68eeb2101a4531e0773b5ad14755..46b8969fd3988fbd27847602970c20dd4bc14c8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -397,6 +397,7 @@ dependencies = [ "dup-crypto 0.6.0", "durs-common-tools 0.1.0", "durs-module 0.1.0-a0.1", + "envy 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -619,6 +620,14 @@ name = "either" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "envy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "failure" version = "0.1.5" @@ -1627,6 +1636,7 @@ dependencies = [ "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" +"checksum envy 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "261b836bcf13f42a01c70351f56bd7b66db6e6fb58352bd214cb77e9269a34b4" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" diff --git a/lib/core/conf/Cargo.toml b/lib/core/conf/Cargo.toml index 9094937b9d3b69d1d6c03b6a63087bccc9ff5d55..8af117b4aabea6303d20cceca1cde21e4f791bfd 100644 --- a/lib/core/conf/Cargo.toml +++ b/lib/core/conf/Cargo.toml @@ -22,5 +22,6 @@ serde = "1.0.*" serde_derive = "1.0.*" serde_json = "1.0.*" rpassword = "1.0.0" +envy = "0.4.*" [features] diff --git a/lib/core/conf/src/lib.rs b/lib/core/conf/src/lib.rs index 061f15a262dc6eda2f1bf88f87e1796caf6420f3..2d7ee44580afcd177972e0593b6cb1891fae6276 100644 --- a/lib/core/conf/src/lib.rs +++ b/lib/core/conf/src/lib.rs @@ -118,7 +118,8 @@ impl Default for DuRsConfV1 { } } -#[derive(Debug, Copy, Clone, Deserialize, PartialEq, Serialize)] +#[derive(Debug, Copy, Clone, Deserialize, PartialEq)] +#[serde(field_identifier)] /// Ressource usage pub enum ResourceUsage { /// Minimal use of the resource, to the detriment of performance @@ -130,6 +131,21 @@ pub enum ResourceUsage { /// No restrictions on the use of the resource, maximizes performance Infinite, } + +impl Serialize for ResourceUsage { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(match *self { + ResourceUsage::Minimal => "Minimal", + ResourceUsage::Medium => "Medium", + ResourceUsage::Large => "Large", + ResourceUsage::Infinite => "Infinite", + }) + } +} + #[derive(Debug, Copy, Clone, Deserialize, PartialEq, Serialize)] /// Ressources usage pub struct ResourcesUsage { @@ -171,6 +187,57 @@ pub struct DuRsConfV2 { pub enabled: HashSet<ModuleName>, } +impl DuRsConfV2 { + fn apply_env(self, conf: EnvConf) -> DuRsConfV2 { + let ressources_usage = ResourcesUsage { + cpu_usage: conf.cpu_usage.unwrap_or(self.ressources_usage.cpu_usage), + network_usage: conf + .network_usage + .unwrap_or(self.ressources_usage.network_usage), + memory_usage: conf + .memory_usage + .unwrap_or(self.ressources_usage.memory_usage), + disk_space_usage: conf + .disk_space_usage + .unwrap_or(self.ressources_usage.disk_space_usage), + }; + + DuRsConfV2 { + currency: conf.currency.unwrap_or(self.currency), + my_node_id: conf.my_node_id.unwrap_or(self.my_node_id), + default_sync_module: conf.default_sync_module.unwrap_or(self.default_sync_module), + ressources_usage, + disabled: conf.disabled.unwrap_or(self.disabled), + enabled: conf.enabled.unwrap_or(self.enabled), + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq)] +/// Optional configs loaded from environment variables +pub struct EnvConf { + /// Currency name + pub currency: Option<CurrencyName>, + /// Duniter node unique identifier + pub my_node_id: Option<u32>, + /// Name of the module used by default for synchronization + pub default_sync_module: Option<ModuleName>, + /// Cpu usage + pub cpu_usage: Option<ResourceUsage>, + /// Network usage + pub network_usage: Option<ResourceUsage>, + /// Memory usage + pub memory_usage: Option<ResourceUsage>, + /// Disk space usage + pub disk_space_usage: Option<ResourceUsage>, + /// Disabled modules + pub disabled: Option<HashSet<ModuleName>>, + /// Enabled modules + pub enabled: Option<HashSet<ModuleName>>, + /// Config modules in Json + pub modules_conf: Option<ModulesConf>, +} + impl Default for DuRsConfV2 { fn default() -> Self { DuRsConfV2 { @@ -631,6 +698,13 @@ pub fn load_conf_at_path( keypairs }; + let env_conf = envy::from_env::<EnvConf>().unwrap_or_else(|e| { + let err_msg = + format!("Fatal error : fail to parse environment variable : {}", e); + dbg!(&err_msg); + panic!(err_msg); + }); + // Open conf file let mut conf_path = profile_path; conf_path.push(constants::CONF_FILENAME); @@ -641,16 +715,16 @@ pub fn load_conf_at_path( f.read_to_string(&mut contents) .map_err(DursConfFileError::ReadError)?; // Parse conf file - let conf: DuRsConf = + let file_conf: DuRsConf = serde_json::from_str(&contents).map_err(DursConfFileError::ParseError)?; // Upgrade conf to latest version - let (conf, upgraded) = conf.upgrade(); + let (conf, upgraded) = file_conf.upgrade(); // If conf is upgraded, rewrite conf file if upgraded { write_conf_file(conf_path.as_path(), &conf) .map_err(DursConfFileError::WriteError)?; } - conf + merge_env_conf(conf, env_conf) } Err(e) => return Err(DursConfFileError::ReadError(e)), } @@ -666,6 +740,19 @@ pub fn load_conf_at_path( Ok((conf, keypairs)) } +fn merge_env_conf(file_conf: DuRsConf, env_conf: EnvConf) -> DuRsConf { + match file_conf { + DuRsConf::V2 { + global_conf, + modules_conf, + } => DuRsConf::V2 { + modules_conf: env_conf.modules_conf.clone().unwrap_or(modules_conf), + global_conf: global_conf.apply_env(env_conf), + }, + _ => panic!("Should never happen : didn't generate DuRsConf::V2"), + } +} + /// Save keypairs in profile folder // Warning: This function cannot use the macro fatal_error! because the logger is not yet initialized, so it must use panic ! pub fn write_keypairs_file(