From ebd1eeb38df1fd5e95d4b79e08b6fdc13806a718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 26 Mar 2024 11:26:49 +0000 Subject: [PATCH] allow gateways to migrate configs of embedded NR/IPR --- gateway/src/commands/init.rs | 2 +- gateway/src/commands/node_details.rs | 2 +- gateway/src/commands/run.rs | 2 +- gateway/src/node/helpers.rs | 38 ++++- gateway/src/node/mod.rs | 4 +- .../ip-packet-router/src/cli/mod.rs | 39 +---- .../ip-packet-router/src/config/helpers.rs | 48 ++++++ .../ip-packet-router/src/config/mod.rs | 1 + .../network-requester/src/cli/mod.rs | 141 +--------------- .../network-requester/src/config/helpers.rs | 155 ++++++++++++++++++ .../network-requester/src/config/mod.rs | 1 + .../src/config/old_config_v1_1_20_2.rs | 1 + .../src/config/old_config_v1_1_33.rs | 1 + 13 files changed, 251 insertions(+), 184 deletions(-) create mode 100644 service-providers/ip-packet-router/src/config/helpers.rs create mode 100644 service-providers/network-requester/src/config/helpers.rs diff --git a/gateway/src/commands/init.rs b/gateway/src/commands/init.rs index b65cc062d2..010d270222 100644 --- a/gateway/src/commands/init.rs +++ b/gateway/src/commands/init.rs @@ -265,7 +265,7 @@ pub async fn execute(args: Init) -> anyhow::Result<()> { ); eprintln!("Gateway configuration completed.\n\n\n"); - output.to_stdout(&node_details(&config)?); + output.to_stdout(&node_details(&config).await?); Ok(()) } diff --git a/gateway/src/commands/node_details.rs b/gateway/src/commands/node_details.rs index 02c0ca9875..72840a8a7a 100644 --- a/gateway/src/commands/node_details.rs +++ b/gateway/src/commands/node_details.rs @@ -18,7 +18,7 @@ pub struct NodeDetails { pub async fn execute(args: NodeDetails) -> anyhow::Result<()> { let config = try_load_current_config(&args.id)?; - args.output.to_stdout(&node_details(&config)?); + args.output.to_stdout(&node_details(&config).await?); Ok(()) } diff --git a/gateway/src/commands/run.rs b/gateway/src/commands/run.rs index 3418c216ac..34c1b6be8d 100644 --- a/gateway/src/commands/run.rs +++ b/gateway/src/commands/run.rs @@ -248,7 +248,7 @@ pub async fn execute(args: Run) -> anyhow::Result<()> { show_binding_warning(config.gateway.listening_address); } - let node_details = node_details(&config)?; + let node_details = node_details(&config).await?; let gateway = crate::node::create_gateway(config, Some(nr_opts), Some(ip_opts), custom_mixnet).await?; eprintln!( diff --git a/gateway/src/node/helpers.rs b/gateway/src/node/helpers.rs index b6765cc7bb..3e2d54417a 100644 --- a/gateway/src/node/helpers.rs +++ b/gateway/src/node/helpers.rs @@ -23,7 +23,9 @@ fn display_path>(path: P) -> String { path.as_ref().display().to_string() } -pub(crate) fn node_details(config: &Config) -> Result { +pub(crate) async fn node_details( + config: &Config, +) -> Result { let gateway_identity_public_key: identity::PublicKey = load_public_key( &config.storage_paths.keys.public_identity_key_file, "gateway identity", @@ -36,7 +38,7 @@ pub(crate) fn node_details(config: &Config) -> Result Result Result>( +pub(crate) async fn load_network_requester_config>( + id: &str, + path: P, +) -> Result { + let path = path.as_ref(); + if let Ok(cfg) = read_network_requester_config(id, path) { + return Ok(cfg); + } + + nym_network_requester::config::helpers::try_upgrade_config(path).await?; + read_network_requester_config(id, path) +} + +pub(crate) async fn load_ip_packet_router_config>( + id: &str, + path: P, +) -> Result { + let path = path.as_ref(); + if let Ok(cfg) = read_ip_packet_router_config(id, path) { + return Ok(cfg); + } + + nym_ip_packet_router::config::helpers::try_upgrade_config(path).await?; + read_ip_packet_router_config(id, path) +} + +fn read_network_requester_config>( id: &str, path: P, ) -> Result { @@ -134,7 +162,7 @@ pub(crate) fn load_network_requester_config>( }) } -pub(crate) fn load_ip_packet_router_config>( +fn read_ip_packet_router_config>( id: &str, path: P, ) -> Result { diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 30e1302d1a..26ad47b689 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -62,7 +62,7 @@ pub(crate) async fn create_gateway( // don't attempt to read config if NR is disabled let network_requester_config = if config.network_requester.enabled { if let Some(path) = &config.storage_paths.network_requester_config { - let cfg = load_network_requester_config(&config.gateway.id, path)?; + let cfg = load_network_requester_config(&config.gateway.id, path).await?; Some(override_network_requester_config(cfg, nr_config_override)) } else { // if NR is enabled, the config path must be specified @@ -75,7 +75,7 @@ pub(crate) async fn create_gateway( // don't attempt to read config if NR is disabled let ip_packet_router_config = if config.ip_packet_router.enabled { if let Some(path) = &config.storage_paths.ip_packet_router_config { - let cfg = load_ip_packet_router_config(&config.gateway.id, path)?; + let cfg = load_ip_packet_router_config(&config.gateway.id, path).await?; Some(override_ip_packet_router_config(cfg, ip_config_override)) } else { // if IPR is enabled, the config path must be specified diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index dc04d7e3cb..912c13cc7a 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -1,11 +1,10 @@ use clap::{CommandFactory, Parser, Subcommand}; -use log::{error, info, trace}; +use log::error; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::{bin_info, version_checker}; use nym_client_core::cli_helpers::client_import_credential::CommonClientImportCredentialArgs; use nym_client_core::cli_helpers::CliClient; -use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; -use nym_ip_packet_router::config::old_config_v1::ConfigV1; +use nym_ip_packet_router::config::helpers::try_upgrade_config; use nym_ip_packet_router::config::{BaseClientConfig, Config}; use nym_ip_packet_router::error::IpPacketRouterError; use std::sync::OnceLock; @@ -136,40 +135,6 @@ pub(crate) async fn execute(args: Cli) -> Result<(), IpPacketRouterError> { Ok(()) } -async fn try_upgrade_v1_config(id: &str) -> Result { - // explicitly load it as v1 (which is incompatible with the current one) - let Ok(old_config) = ConfigV1::read_from_default_path(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - info!("It seems the client is using v1 config template."); - info!("It is going to get updated to the current specification."); - - let old_paths = old_config.storage_paths.clone(); - let updated = old_config.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - None, - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_config(id: &str) -> Result<(), IpPacketRouterError> { - trace!("Attempting to upgrade config"); - - if try_upgrade_v1_config(id).await? { - return Ok(()); - } - - Ok(()) -} - async fn try_load_current_config(id: &str) -> Result { // try to load the config as is if let Ok(cfg) = Config::read_from_default_path(id) { diff --git a/service-providers/ip-packet-router/src/config/helpers.rs b/service-providers/ip-packet-router/src/config/helpers.rs new file mode 100644 index 0000000000..5c965e8951 --- /dev/null +++ b/service-providers/ip-packet-router/src/config/helpers.rs @@ -0,0 +1,48 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::default_config_filepath; +use crate::config::old_config_v1::ConfigV1; +use crate::error::IpPacketRouterError; +use log::{info, trace}; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; +use std::path::Path; + +async fn try_upgrade_v1_config>( + config_path: P, +) -> Result { + // explicitly load it as v1 (which is incompatible with the current one) + let Ok(old_config) = ConfigV1::read_from_toml_file(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using v1 config template."); + info!("It is going to get updated to the current specification."); + + let old_paths = old_config.storage_paths.clone(); + let updated = old_config.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +pub async fn try_upgrade_config>(config_path: P) -> Result<(), IpPacketRouterError> { + trace!("Attempting to upgrade config"); + if try_upgrade_v1_config(config_path).await? { + return Ok(()); + } + + Ok(()) +} + +pub async fn try_upgrade_config_by_id(id: &str) -> Result<(), IpPacketRouterError> { + try_upgrade_config(default_config_filepath(id)).await +} diff --git a/service-providers/ip-packet-router/src/config/mod.rs b/service-providers/ip-packet-router/src/config/mod.rs index 88f6b32e68..048fcd67f8 100644 --- a/service-providers/ip-packet-router/src/config/mod.rs +++ b/service-providers/ip-packet-router/src/config/mod.rs @@ -20,6 +20,7 @@ use crate::config::persistence::IpPacketRouterPaths; use self::template::CONFIG_TEMPLATE; +pub mod helpers; pub mod old_config_v1; mod persistence; mod template; diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 29057aa523..7ba2462c61 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -1,22 +1,18 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::config::old_config_v1_1_13::OldConfigV1_1_13; -use crate::config::old_config_v1_1_20::ConfigV1_1_20; -use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; -use crate::config::old_config_v1_1_33::ConfigV1_1_33; +use crate::config::helpers::try_upgrade_config_by_id; use crate::{ config::{BaseClientConfig, Config}, error::NetworkRequesterError, }; use clap::{CommandFactory, Parser, Subcommand}; -use log::{error, info, trace}; +use log::error; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::version_checker; use nym_client_core::cli_helpers::client_import_credential::CommonClientImportCredentialArgs; use nym_client_core::cli_helpers::CliClient; -use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_config::OptionalSet; use std::sync::OnceLock; @@ -36,7 +32,7 @@ impl CliClient for CliNetworkRequesterClient { type Config = Config; async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id).await + try_upgrade_config_by_id(id).await } async fn try_load_current_config(id: &str) -> Result { @@ -190,135 +186,6 @@ pub(crate) async fn execute(args: Cli) -> Result<(), NetworkRequesterError> { Ok(()) } -async fn try_upgrade_v1_1_13_config(id: &str) -> Result { - trace!("Trying to load as v1.1.13 config"); - use nym_config::legacy_helpers::nym_config::MigrationNymConfig; - - // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) - let Ok(old_config) = OldConfigV1_1_13::load_from_file(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - info!("It seems the client is using <= v1.1.13 config template."); - info!("It is going to get updated to the current specification."); - - let updated_step1: ConfigV1_1_20 = old_config.into(); - let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); - let (updated_step3, gateway_config) = updated_step2.upgrade()?; - let old_paths = updated_step3.storage_paths.clone(); - let updated = updated_step3.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - Some(gateway_config), - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_v1_1_20_config(id: &str) -> Result { - trace!("Trying to load as v1.1.20 config"); - use nym_config::legacy_helpers::nym_config::MigrationNymConfig; - - // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) - let Ok(old_config) = ConfigV1_1_20::load_from_file(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - - info!("It seems the client is using <= v1.1.20 config template."); - info!("It is going to get updated to the current specification."); - - let updated_step1: ConfigV1_1_20_2 = old_config.into(); - let (updated_step2, gateway_config) = updated_step1.upgrade()?; - let old_paths = updated_step2.storage_paths.clone(); - let updated = updated_step2.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - Some(gateway_config), - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_v1_1_20_2_config(id: &str) -> Result { - trace!("Trying to load as v1.1.20_2 config"); - - // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) - let Ok(old_config) = ConfigV1_1_20_2::read_from_default_path(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - info!("It seems the client is using <= v1.1.20_2 config template."); - info!("It is going to get updated to the current specification."); - - let (updated_step1, gateway_config) = old_config.upgrade()?; - let old_paths = updated_step1.storage_paths.clone(); - let updated = updated_step1.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - Some(gateway_config), - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_v1_1_33_config(id: &str) -> Result { - // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) - let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - info!("It seems the client is using <= v1.1.33 config template."); - info!("It is going to get updated to the current specification."); - - let old_paths = old_config.storage_paths.clone(); - let updated = old_config.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - None, - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_config(id: &str) -> Result<(), NetworkRequesterError> { - trace!("Attempting to upgrade config"); - if try_upgrade_v1_1_13_config(id).await? { - return Ok(()); - } - if try_upgrade_v1_1_20_config(id).await? { - return Ok(()); - } - if try_upgrade_v1_1_20_2_config(id).await? { - return Ok(()); - } - if try_upgrade_v1_1_33_config(id).await? { - return Ok(()); - } - - Ok(()) -} - async fn try_load_current_config(id: &str) -> Result { // try to load the config as is if let Ok(cfg) = Config::read_from_default_path(id) { @@ -330,7 +197,7 @@ async fn try_load_current_config(id: &str) -> Result cfg, diff --git a/service-providers/network-requester/src/config/helpers.rs b/service-providers/network-requester/src/config/helpers.rs new file mode 100644 index 0000000000..5ef027d078 --- /dev/null +++ b/service-providers/network-requester/src/config/helpers.rs @@ -0,0 +1,155 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::default_config_filepath; +use crate::config::old_config_v1_1_13::OldConfigV1_1_13; +use crate::config::old_config_v1_1_20::ConfigV1_1_20; +use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; +use crate::config::old_config_v1_1_33::ConfigV1_1_33; +use crate::error::NetworkRequesterError; +use log::{info, trace}; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; +use std::path::Path; + +async fn try_upgrade_v1_1_13_config>( + config_path: P, +) -> Result { + trace!("Trying to load as v1.1.13 config"); + use nym_config::legacy_helpers::nym_config::MigrationNymConfig; + + // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) + let Ok(old_config) = OldConfigV1_1_13::load_from_filepath(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.13 config template."); + info!("It is going to get updated to the current specification."); + + let updated_step1: ConfigV1_1_20 = old_config.into(); + let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); + let (updated_step3, gateway_config) = updated_step2.upgrade()?; + let old_paths = updated_step3.storage_paths.clone(); + let updated = updated_step3.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +async fn try_upgrade_v1_1_20_config>( + config_path: P, +) -> Result { + trace!("Trying to load as v1.1.20 config"); + use nym_config::legacy_helpers::nym_config::MigrationNymConfig; + + // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) + let Ok(old_config) = ConfigV1_1_20::load_from_filepath(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + + info!("It seems the client is using <= v1.1.20 config template."); + info!("It is going to get updated to the current specification."); + + let updated_step1: ConfigV1_1_20_2 = old_config.into(); + let (updated_step2, gateway_config) = updated_step1.upgrade()?; + let old_paths = updated_step2.storage_paths.clone(); + let updated = updated_step2.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +async fn try_upgrade_v1_1_20_2_config>( + config_path: P, +) -> Result { + trace!("Trying to load as v1.1.20_2 config"); + + // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) + let Ok(old_config) = ConfigV1_1_20_2::read_from_toml_file(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.20_2 config template."); + info!("It is going to get updated to the current specification."); + + let (updated_step1, gateway_config) = old_config.upgrade()?; + let old_paths = updated_step1.storage_paths.clone(); + let updated = updated_step1.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +async fn try_upgrade_v1_1_33_config>( + config_path: P, +) -> Result { + // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) + let Ok(old_config) = ConfigV1_1_33::read_from_toml_file(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.33 config template."); + info!("It is going to get updated to the current specification."); + + let old_paths = old_config.storage_paths.clone(); + let updated = old_config.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +pub async fn try_upgrade_config>( + config_path: P, +) -> Result<(), NetworkRequesterError> { + trace!("Attempting to upgrade config"); + if try_upgrade_v1_1_13_config(config_path.as_ref()).await? { + return Ok(()); + } + if try_upgrade_v1_1_20_config(config_path.as_ref()).await? { + return Ok(()); + } + if try_upgrade_v1_1_20_2_config(config_path.as_ref()).await? { + return Ok(()); + } + if try_upgrade_v1_1_33_config(config_path).await? { + return Ok(()); + } + + Ok(()) +} + +pub async fn try_upgrade_config_by_id(id: &str) -> Result<(), NetworkRequesterError> { + try_upgrade_config(default_config_filepath(id)).await +} diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index a45180b200..cba8253039 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -23,6 +23,7 @@ use url::Url; pub use nym_client_core::config::Config as BaseClientConfig; +pub mod helpers; pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; pub mod old_config_v1_1_20_2; diff --git a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs b/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs index 642270911b..8fe4c90232 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs +++ b/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs @@ -55,6 +55,7 @@ impl ConfigV1_1_20_2 { read_config_from_toml_file(path) } + #[allow(dead_code)] pub fn read_from_default_path>(id: P) -> io::Result { Self::read_from_toml_file(default_config_filepath(id)) } diff --git a/service-providers/network-requester/src/config/old_config_v1_1_33.rs b/service-providers/network-requester/src/config/old_config_v1_1_33.rs index b49bb514d1..e211256643 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_33.rs +++ b/service-providers/network-requester/src/config/old_config_v1_1_33.rs @@ -54,6 +54,7 @@ impl ConfigV1_1_33 { read_config_from_toml_file(path) } + #[allow(dead_code)] pub fn read_from_default_path>(id: P) -> io::Result { Self::read_from_toml_file(default_config_filepath(id)) }