Config file support for myceliumd-private + slight optimization to merge_configs function

This commit is contained in:
Maxime Van Hees
2024-07-12 13:10:44 +02:00
committed by Lee Smet
parent 3d9ad65704
commit 74a9fb2e81
5 changed files with 531 additions and 42 deletions
+4
View File
@@ -9,3 +9,7 @@ disable_peer_discovery = false
no_tun = false
#metrics_api_address = 0.0.0.0:9999
#firewall_mark = 30
## Options below only apply when myceliumd-private is used
#network_name = "private network name"
#network_key_file = "path_to_key_file"
+337 -7
View File
@@ -230,6 +230,12 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
@@ -247,6 +253,9 @@ name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
dependencies = [
"serde",
]
[[package]]
name = "bitvec"
@@ -273,6 +282,15 @@ dependencies = [
"constant_time_eq",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "borsh"
version = "1.5.1"
@@ -442,12 +460,61 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "config"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7328b20597b53c2454f0b1919720c25c7339051c02b72b7e05409e00b14132be"
dependencies = [
"async-trait",
"convert_case",
"json5",
"lazy_static",
"nom",
"pathdiff",
"ron",
"rust-ini",
"serde",
"serde_json",
"toml",
"yaml-rust",
]
[[package]]
name = "const-random"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
dependencies = [
"const-random-macro",
]
[[package]]
name = "const-random-macro"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
"getrandom",
"once_cell",
"tiny-keccak",
]
[[package]]
name = "constant_time_eq"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
[[package]]
name = "convert_case"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core-foundation"
version = "0.9.4"
@@ -473,6 +540,12 @@ dependencies = [
"libc",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "crypto-common"
version = "0.1.6"
@@ -549,6 +622,25 @@ dependencies = [
"powerfmt",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "dirs"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-next"
version = "2.0.0"
@@ -559,6 +651,18 @@ dependencies = [
"dirs-sys-next",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.48.0",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
@@ -581,6 +685,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "dlv-list"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f"
dependencies = [
"const-random",
]
[[package]]
name = "encode_unicode"
version = "1.0.0"
@@ -830,6 +943,12 @@ dependencies = [
"ahash",
]
[[package]]
name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
[[package]]
name = "hashbrown"
version = "0.14.5"
@@ -1020,6 +1139,17 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "json5"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
dependencies = [
"pest",
"pest_derive",
"serde",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -1062,6 +1192,12 @@ dependencies = [
"libc",
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
@@ -1139,6 +1275,12 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.7.3"
@@ -1200,7 +1342,7 @@ name = "mycelium-api"
version = "0.5.3"
dependencies = [
"axum",
"base64",
"base64 0.22.1",
"mycelium",
"mycelium-metrics",
"serde",
@@ -1212,7 +1354,7 @@ dependencies = [
name = "mycelium-cli"
version = "0.5.3"
dependencies = [
"base64",
"base64 0.22.1",
"byte-unit",
"mycelium",
"mycelium-api",
@@ -1240,8 +1382,10 @@ dependencies = [
name = "myceliumd-private"
version = "0.5.3"
dependencies = [
"base64",
"base64 0.22.1",
"clap",
"config",
"dirs",
"mycelium",
"mycelium-api",
"mycelium-cli",
@@ -1375,6 +1519,16 @@ dependencies = [
"memoffset",
]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
@@ -1479,6 +1633,22 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "ordered-multimap"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ed8acf08e98e744e5384c8bc63ceb0364e68a6854187221c18df61c4797690e"
dependencies = [
"dlv-list",
"hashbrown 0.13.2",
]
[[package]]
name = "overload"
version = "0.1.1"
@@ -1514,13 +1684,19 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pathdiff"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
[[package]]
name = "pem"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae"
dependencies = [
"base64",
"base64 0.22.1",
"serde",
]
@@ -1530,6 +1706,51 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
version = "2.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95"
dependencies = [
"memchr",
"thiserror",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "pest_meta"
version = "2.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f"
dependencies = [
"once_cell",
"pest",
"sha2",
]
[[package]]
name = "pin-project"
version = "1.1.5"
@@ -1612,7 +1833,7 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
dependencies = [
"toml_edit",
"toml_edit 0.21.1",
]
[[package]]
@@ -1890,7 +2111,7 @@ version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37"
dependencies = [
"base64",
"base64 0.22.1",
"bytes",
"futures-core",
"futures-util",
@@ -1963,6 +2184,18 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "ron"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
dependencies = [
"base64 0.21.7",
"bitflags 2.5.0",
"serde",
"serde_derive",
]
[[package]]
name = "rtnetlink"
version = "0.14.1"
@@ -1981,6 +2214,16 @@ dependencies = [
"tokio",
]
[[package]]
name = "rust-ini"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e2a3bcec1f113553ef1c88aae6c020a369d03d55b58de9869a0908930385091"
dependencies = [
"cfg-if",
"ordered-multimap",
]
[[package]]
name = "rust_decimal"
version = "1.35.0"
@@ -2139,6 +2382,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@@ -2151,6 +2403,17 @@ dependencies = [
"serde",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
@@ -2363,6 +2626,15 @@ dependencies = [
"time-core",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@@ -2456,11 +2728,26 @@ dependencies = [
"tokio",
]
[[package]]
name = "toml"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.22.15",
]
[[package]]
name = "toml_datetime"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
@@ -2470,7 +2757,20 @@ checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
dependencies = [
"indexmap",
"toml_datetime",
"winnow",
"winnow 0.5.40",
]
[[package]]
name = "toml_edit"
version = "0.22.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow 0.6.13",
]
[[package]]
@@ -2602,6 +2902,12 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ucd-trie"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
[[package]]
name = "unicode-bidi"
version = "0.3.15"
@@ -2623,6 +2929,12 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode-width"
version = "0.1.13"
@@ -3006,6 +3318,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "winnow"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.52.0"
@@ -3063,6 +3384,15 @@ dependencies = [
"zeroize",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "yasna"
version = "0.5.2"
+2
View File
@@ -31,3 +31,5 @@ tokio = { version = "1.37.0", features = [
] }
reqwest = { version = "0.12.4", default-features = false, features = ["json"] }
base64 = "0.22.1"
config = "0.14.0"
dirs = "5.0.1"
+184 -21
View File
@@ -9,11 +9,12 @@ use std::{
use std::{fmt::Display, str::FromStr};
use clap::{Args, Parser, Subcommand};
use serde::{Deserialize, Deserializer};
use tokio::fs::File;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[cfg(target_family = "unix")]
use tokio::signal::{self, unix::SignalKind};
use tracing::{debug, error, warn};
use tracing::{debug, error, info, warn};
use crypto::PublicKey;
use mycelium::endpoint::Endpoint;
@@ -81,6 +82,10 @@ struct Cli {
#[arg(short = 'k', long = "key-file", global = true)]
key_file: Option<PathBuf>,
// Configuration file
#[arg(short = 'c', long = "config-file", global = true)]
config_file: Option<PathBuf>,
/// Enable debug logging. Does nothing if `--silent` is set.
#[arg(short = 'd', long = "debug", default_value_t = false)]
debug: bool,
@@ -285,10 +290,83 @@ pub struct NodeArguments {
firewall_mark: Option<u32>,
}
#[derive(Debug, Deserialize, Default)]
struct MyceliumConfig {
#[serde(deserialize_with = "deserialize_optional_endpoint_str_from_toml")]
peers: Option<Vec<Endpoint>>,
tcp_listen_port: Option<u16>,
quic_listen_port: Option<u16>,
no_tun: Option<bool>,
tun_name: Option<String>,
disable_peer_discovery: Option<bool>,
peer_discovery_port: Option<u16>,
api_addr: Option<SocketAddr>,
metrics_api_address: Option<SocketAddr>,
network_name: Option<String>,
network_key_file: Option<PathBuf>,
firewall_mark: Option<u32>,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let cli = Cli::parse();
// Init default configuration
let mut mycelium_config = MyceliumConfig::default();
// Load configuration file
if let Some(config_file_path) = &cli.config_file {
if Path::new(config_file_path).exists() {
let config = config::Config::builder()
.add_source(config::File::new(
config_file_path.to_str().unwrap(),
config::FileFormat::Toml,
))
.build()?;
mycelium_config = config.try_deserialize()?;
} else {
let error_msg = format!("Config file {:?} not found", config_file_path);
return Err(io::Error::new(io::ErrorKind::NotFound, error_msg).into());
}
} else if let Some(mut conf) = dirs::config_dir() {
// Windows: %APPDATA%/ThreeFold Tech/Mycelium/mycelium.conf
#[cfg(target_os = "windows")]
{
conf = conf
.join("ThreeFold Tech")
.join("Mycelium")
.join("mycelium.toml")
};
// Linux: $HOME/.config/mycelium/mycelium.conf
#[cfg(target_os = "linux")]
{
conf = conf.join("mycelium").join("mycelium.toml")
};
// MacOS: $HOME/Library/Application Support/ThreeFold Tech/Mycelium/mycelium.conf
#[cfg(target_os = "macos")]
{
conf = conf
.join("ThreeFold Tech")
.join("Mycelium")
.join("mycelium.toml")
};
if conf.exists() {
info!(
conf_dir = conf.to_str().unwrap(),
"Mycelium is starting with configuration file",
);
let config = config::Config::builder()
.add_source(config::File::new(
conf.to_str().unwrap(),
config::FileFormat::Toml,
))
.build()?;
mycelium_config = config.try_deserialize()?;
}
}
let level = if cli.silent {
tracing::Level::ERROR
} else if cli.debug {
@@ -317,8 +395,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
match cli.command {
None => {
let merged_config = merge_config(cli.node_args, mycelium_config);
let private_network_config =
match (cli.node_args.network_name, cli.node_args.network_key_file) {
match (merged_config.network_name, merged_config.network_key_file) {
(Some(network_name), Some(network_key_file)) => {
let net_key = load_key_file(&network_key_file).await?;
@@ -337,46 +417,46 @@ async fn main() -> Result<(), Box<dyn Error>> {
secret_key
};
let _api = if let Some(metrics_api_addr) = cli.node_args.metrics_api_address {
let _api = if let Some(metrics_api_addr) = merged_config.metrics_api_address {
let metrics = mycelium_metrics::PrometheusExporter::new();
let config = mycelium::Config {
node_key: node_secret_key,
peers: cli.node_args.static_peers,
no_tun: cli.node_args.no_tun,
tcp_listen_port: cli.node_args.tcp_listen_port,
quic_listen_port: Some(cli.node_args.quic_listen_port),
peer_discovery_port: if cli.node_args.disable_peer_discovery {
peers: merged_config.static_peers,
no_tun: merged_config.no_tun,
tcp_listen_port: merged_config.tcp_listen_port,
quic_listen_port: Some(merged_config.quic_listen_port),
peer_discovery_port: if merged_config.disable_peer_discovery {
None
} else {
Some(cli.node_args.peer_discovery_port)
Some(merged_config.peer_discovery_port)
},
tun_name: cli.node_args.tun_name,
tun_name: merged_config.tun_name,
private_network_config,
metrics: metrics.clone(),
firewall_mark: cli.node_args.firewall_mark,
firewall_mark: merged_config.firewall_mark,
};
metrics.spawn(metrics_api_addr);
let node = Node::new(config).await?;
mycelium_api::Http::spawn(node, cli.node_args.api_addr)
mycelium_api::Http::spawn(node, merged_config.api_addr)
} else {
let config = mycelium::Config {
node_key: node_secret_key,
peers: cli.node_args.static_peers,
no_tun: cli.node_args.no_tun,
tcp_listen_port: cli.node_args.tcp_listen_port,
quic_listen_port: Some(cli.node_args.quic_listen_port),
peer_discovery_port: if cli.node_args.disable_peer_discovery {
peers: merged_config.static_peers,
no_tun: merged_config.no_tun,
tcp_listen_port: merged_config.tcp_listen_port,
quic_listen_port: Some(merged_config.quic_listen_port),
peer_discovery_port: if merged_config.disable_peer_discovery {
None
} else {
Some(cli.node_args.peer_discovery_port)
Some(merged_config.peer_discovery_port)
},
tun_name: cli.node_args.tun_name,
tun_name: merged_config.tun_name,
private_network_config,
metrics: mycelium_metrics::NoMetrics,
firewall_mark: cli.node_args.firewall_mark,
firewall_mark: merged_config.firewall_mark,
};
let node = Node::new(config).await?;
mycelium_api::Http::spawn(node, cli.node_args.api_addr)
mycelium_api::Http::spawn(node, merged_config.api_addr)
};
// TODO: put in dedicated file so we can only rely on certain signals on unix platforms
@@ -527,3 +607,86 @@ async fn save_key_file(key: &crypto::SecretKey, path: &Path) -> io::Result<()> {
Ok(())
}
fn merge_config(cli_args: NodeArguments, file_config: MyceliumConfig) -> NodeArguments {
NodeArguments {
static_peers: if !cli_args.static_peers.is_empty() {
cli_args.static_peers
} else {
file_config.peers.unwrap_or_default()
},
tcp_listen_port: if cli_args.tcp_listen_port != DEFAULT_TCP_LISTEN_PORT {
cli_args.tcp_listen_port
} else {
file_config
.tcp_listen_port
.unwrap_or(DEFAULT_TCP_LISTEN_PORT)
},
quic_listen_port: if cli_args.quic_listen_port != DEFAULT_QUIC_LISTEN_PORT {
cli_args.quic_listen_port
} else {
file_config
.quic_listen_port
.unwrap_or(DEFAULT_QUIC_LISTEN_PORT)
},
peer_discovery_port: if cli_args.peer_discovery_port != DEFAULT_PEER_DISCOVERY_PORT {
cli_args.peer_discovery_port
} else {
file_config
.peer_discovery_port
.unwrap_or(DEFAULT_PEER_DISCOVERY_PORT)
},
disable_peer_discovery: cli_args.disable_peer_discovery
|| file_config.disable_peer_discovery.unwrap_or(false),
api_addr: if cli_args.api_addr != DEFAULT_HTTP_API_SERVER_ADDRESS {
cli_args.api_addr
} else {
file_config
.api_addr
.unwrap_or(DEFAULT_HTTP_API_SERVER_ADDRESS)
},
no_tun: cli_args.no_tun || file_config.no_tun.unwrap_or(false),
tun_name: if cli_args.tun_name != *TUN_NAME {
cli_args.tun_name
} else {
file_config.tun_name.unwrap_or_else(|| TUN_NAME.to_string())
},
metrics_api_address: cli_args
.metrics_api_address
.or(file_config.metrics_api_address),
network_name: cli_args.network_name.or(file_config.network_name),
network_key_file: cli_args.network_key_file.or(file_config.network_key_file),
firewall_mark: cli_args.firewall_mark.or(file_config.firewall_mark),
}
}
/// Deserialize an optional list of endpoints from TOML format. The endpoints can be provided
/// either as a list `[...]`, or in case there is only 1 endpoint, it can also be provided as a
/// single string element. If no value is provided, it returns None.
fn deserialize_optional_endpoint_str_from_toml<'de, D>(
deserializer: D,
) -> Result<Option<Vec<Endpoint>>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum StringOrVec {
String(String),
Vec(Vec<String>),
}
Ok(match Option::<StringOrVec>::deserialize(deserializer)? {
Some(StringOrVec::Vec(v)) => Some(
v.into_iter()
.map(|s| {
<Endpoint as std::str::FromStr>::from_str(&s).map_err(serde::de::Error::custom)
})
.collect::<Result<Vec<_>, _>>()?,
),
Some(StringOrVec::String(s)) => Some(vec![
<Endpoint as std::str::FromStr>::from_str(&s).map_err(serde::de::Error::custom)?
]),
None => None,
})
}
+4 -14
View File
@@ -622,20 +622,10 @@ fn merge_config(cli_args: NodeArguments, file_config: MyceliumConfig) -> NodeArg
} else {
file_config.tun_name.unwrap_or_else(|| TUN_NAME.to_string())
},
metrics_api_address: if cli_args.metrics_api_address.is_some() {
cli_args.metrics_api_address
} else if file_config.metrics_api_address.is_some() {
file_config.metrics_api_address
} else {
None
},
firewall_mark: if cli_args.firewall_mark.is_some() {
cli_args.firewall_mark
} else if file_config.firewall_mark.is_some() {
file_config.firewall_mark
} else {
None
},
metrics_api_address: cli_args
.metrics_api_address
.or(file_config.metrics_api_address),
firewall_mark: cli_args.firewall_mark.or(file_config.firewall_mark),
}
}