Skip to content

Commit

Permalink
Merge pull request #3846 from nymtech/jon/handle-unable-upgrade-config
Browse files Browse the repository at this point in the history
clients: handle config upgrade failure
  • Loading branch information
tommyv1987 committed Sep 8, 2023
2 parents 2e2d258 + e336b99 commit c4667a6
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 41 deletions.
15 changes: 10 additions & 5 deletions clients/native/src/client/config/old_config_v1_1_20_2.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
// Copyright 2023 - Nym Technologies SA <[email protected]>
// SPDX-License-Identifier: Apache-2.0

use crate::client::config::persistence::ClientPaths;
use crate::client::config::{default_config_filepath, Config, Socket, SocketType};
use crate::{
client::config::{
default_config_filepath, persistence::ClientPaths, Config, Socket, SocketType,
},
error::ClientError,
};

use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
use nym_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as BaseConfigV1_1_20_2;
Expand Down Expand Up @@ -43,18 +48,18 @@ impl ConfigV1_1_20_2 {

// in this upgrade, gateway endpoint configuration was moved out of the config file,
// so its returned to be stored elsewhere.
pub fn upgrade(self) -> (Config, GatewayEndpointConfig) {
pub fn upgrade(self) -> Result<(Config, GatewayEndpointConfig), ClientError> {
let gateway_details = self.base.client.gateway_endpoint.clone().into();
let config = Config {
base: self.base.into(),
socket: self.socket.into(),
storage_paths: ClientPaths {
common_paths: self.storage_paths.common_paths.upgrade_default(),
common_paths: self.storage_paths.common_paths.upgrade_default()?,
},
logging: self.logging,
};

(config, gateway_details)
Ok((config, gateway_details))
}
}

Expand Down
6 changes: 3 additions & 3 deletions clients/native/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> {

let updated_step1: ConfigV1_1_20 = old_config.into();
let updated_step2: ConfigV1_1_20_2 = updated_step1.into();
let (updated, gateway_config) = updated_step2.upgrade();
let (updated, gateway_config) = updated_step2.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand All @@ -177,7 +177,7 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, ClientError> {
info!("It is going to get updated to the current specification.");

let updated_step1: ConfigV1_1_20_2 = old_config.into();
let (updated, gateway_config) = updated_step1.upgrade();
let (updated, gateway_config) = updated_step1.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand All @@ -194,7 +194,7 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, ClientError> {
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, gateway_config) = old_config.upgrade();
let (updated, gateway_config) = old_config.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand Down
6 changes: 3 additions & 3 deletions clients/socks5/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError> {

let updated_step1: ConfigV1_1_20 = old_config.into();
let updated_step2: ConfigV1_1_20_2 = updated_step1.into();
let (updated, gateway_config) = updated_step2.upgrade();
let (updated, gateway_config) = updated_step2.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand All @@ -219,7 +219,7 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, Socks5ClientError> {
info!("It is going to get updated to the current specification.");

let updated_step1: ConfigV1_1_20_2 = old_config.into();
let (updated, gateway_config) = updated_step1.upgrade();
let (updated, gateway_config) = updated_step1.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand All @@ -236,7 +236,7 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, Socks5ClientError> {
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, gateway_config) = old_config.upgrade();
let (updated, gateway_config) = old_config.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand Down
16 changes: 10 additions & 6 deletions clients/socks5/src/config/old_config_v1_1_20_2.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
// Copyright 2023 - Nym Technologies SA <[email protected]>
// SPDX-License-Identifier: Apache-2.0

use crate::config::persistence::SocksClientPaths;
use crate::config::{default_config_filepath, Config};
use crate::{
config::{default_config_filepath, persistence::SocksClientPaths, Config},
error::Socks5ClientError,
};

use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
use nym_client_core::config::GatewayEndpointConfig;
use nym_config::read_config_from_toml_file;
pub use nym_socks5_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as CoreConfigV1_1_20_2;
use serde::{Deserialize, Serialize};
use std::io;
use std::path::Path;

pub use nym_socks5_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as CoreConfigV1_1_20_2;

#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
pub struct SocksClientPathsV1_1_20_2 {
#[serde(flatten)]
Expand Down Expand Up @@ -39,16 +43,16 @@ impl ConfigV1_1_20_2 {

// in this upgrade, gateway endpoint configuration was moved out of the config file,
// so its returned to be stored elsewhere.
pub fn upgrade(self) -> (Config, GatewayEndpointConfig) {
pub fn upgrade(self) -> Result<(Config, GatewayEndpointConfig), Socks5ClientError> {
let gateway_details = self.core.base.client.gateway_endpoint.clone().into();
let config = Config {
core: self.core.into(),
storage_paths: SocksClientPaths {
common_paths: self.storage_paths.common_paths.upgrade_default(),
common_paths: self.storage_paths.common_paths.upgrade_default()?,
},
logging: self.logging,
};

(config, gateway_details)
Ok((config, gateway_details))
}
}
16 changes: 9 additions & 7 deletions common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use crate::config::disk_persistence::keys_paths::ClientKeysPaths;
use crate::config::disk_persistence::{CommonClientPaths, DEFAULT_GATEWAY_DETAILS_FILENAME};
use crate::error::ClientCoreError;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

Expand All @@ -15,16 +16,17 @@ pub struct CommonClientPathsV1_1_20_2 {
}

impl CommonClientPathsV1_1_20_2 {
pub fn upgrade_default(self) -> CommonClientPaths {
let data_dir = self
.reply_surb_database
.parent()
.expect("client paths upgrade failure");
CommonClientPaths {
pub fn upgrade_default(self) -> Result<CommonClientPaths, ClientCoreError> {
let data_dir = self.reply_surb_database.parent().ok_or_else(|| {
ClientCoreError::UnableToUpgradeConfigFile {
new_version: "1.1.20-2".to_string(),
}
})?;
Ok(CommonClientPaths {
keys: self.keys,
gateway_details: data_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME),
credentials_database: self.credentials_database,
reply_surb_database: self.reply_surb_database,
}
})
}
}
3 changes: 3 additions & 0 deletions common/client-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ pub enum ClientCoreError {

#[error("the provided gateway details (for gateway {gateway_id}) do not correspond to the shared keys")]
MismatchedGatewayDetails { gateway_id: String },

#[error("unable to upgrade config file to `{new_version}`")]
UnableToUpgradeConfigFile { new_version: String },
}

/// Set of messages that the client can send to listeners via the task manager
Expand Down
35 changes: 33 additions & 2 deletions nym-connect/desktop/src-tauri/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::error::{BackendError, Result};
use nym_client_core::client::base_client::storage::gateway_details::OnDiskGatewayDetails;
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
use nym_client_core::config::GatewayEndpointConfig;
use nym_client_core::error::ClientCoreError;
use nym_client_core::init::GatewaySetup;
use nym_config::{
must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate,
Expand Down Expand Up @@ -137,6 +138,17 @@ fn init_paths(id: &str) -> io::Result<()> {
fs::create_dir_all(default_config_directory(id))
}

fn try_extract_version_for_upgrade_failure(err: BackendError) -> Option<String> {
if let BackendError::ClientCoreError {
source: ClientCoreError::UnableToUpgradeConfigFile { new_version },
} = err
{
Some(new_version)
} else {
None
}
}

pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: String) -> Result<()> {
log::trace!("Initialising client...");

Expand All @@ -145,10 +157,29 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
let _validated = identity::PublicKey::from_base58_string(&chosen_gateway_id)
.map_err(|_| BackendError::UnableToParseGateway)?;

let already_init = if default_config_filepath(&id).exists() {
let config_path = default_config_filepath(&id);
let already_init = if config_path.exists() {
// in case we're using old config, try to upgrade it
// (if we're using the current version, it's a no-op)
try_upgrade_config(&id)?;
if let Err(err) = try_upgrade_config(&id) {
log::error!(
"Failed to upgrade config file {}: {:?}",
config_path.display(),
err
);
if let Some(failed_at_version) = try_extract_version_for_upgrade_failure(err) {
return Err(
BackendError::CouldNotUpgradeExistingConfigurationFileAtVersion {
file: config_path,
failed_at_version,
},
);
} else {
return Err(BackendError::CouldNotUpgradeExistingConfigurationFile {
file: config_path,
});
}
};
eprintln!("SOCKS5 client \"{id}\" was already initialised before");
true
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use crate::config::persistence::NymConnectPaths;
use crate::config::{default_config_filepath, Config};
use crate::error::Result;
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
use nym_client_core::config::GatewayEndpointConfig;
Expand Down Expand Up @@ -39,16 +40,16 @@ impl ConfigV1_1_20_2 {

// in this upgrade, gateway endpoint configuration was moved out of the config file,
// so its returned to be stored elsewhere.
pub fn upgrade(self) -> (Config, GatewayEndpointConfig) {
pub fn upgrade(self) -> Result<(Config, GatewayEndpointConfig)> {
let gateway_details = self.core.base.client.gateway_endpoint.clone().into();
let config = Config {
core: self.core.into(),
storage_paths: NymConnectPaths {
common_paths: self.storage_paths.common_paths.upgrade_default(),
common_paths: self.storage_paths.common_paths.upgrade_default()?,
},
// logging: self.logging,
};

(config, gateway_details)
Ok((config, gateway_details))
}
}
9 changes: 5 additions & 4 deletions nym-connect/desktop/src-tauri/src/config/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
},
error::{BackendError, Result},
};
use log::info;
use log::{debug, info};
use nym_client_core::{
client::{
base_client::storage::gateway_details::{OnDiskGatewayDetails, PersistedGatewayDetails},
Expand Down Expand Up @@ -52,7 +52,7 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool> {

let updated_step1: ConfigV1_1_20 = old_config.into();
let updated_step2: ConfigV1_1_20_2 = updated_step1.into();
let (updated, gateway_config) = updated_step2.upgrade();
let (updated, gateway_config) = updated_step2.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand All @@ -72,7 +72,7 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool> {
info!("It is going to get updated to the current specification.");

let updated_step1: ConfigV1_1_20_2 = old_config.into();
let (updated, gateway_config) = updated_step1.upgrade();
let (updated, gateway_config) = updated_step1.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand All @@ -89,14 +89,15 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool> {
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, gateway_config) = old_config.upgrade();
let (updated, gateway_config) = old_config.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Ok(true)
}

pub fn try_upgrade_config(id: &str) -> Result<()> {
debug!("Attempting to upgrade config file for \"{id}\"");
if try_upgrade_v1_1_13_config(id)? {
return Ok(());
}
Expand Down
7 changes: 7 additions & 0 deletions nym-connect/desktop/src-tauri/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ pub enum BackendError {
CouldNotGetConfigFilename,
#[error("could not load existing gateway configuration")]
CouldNotLoadExistingGatewayConfiguration(std::io::Error),
#[error("could not upgrade `{file}` to latest version")]
CouldNotUpgradeExistingConfigurationFile { file: std::path::PathBuf },
#[error("could not upgrade `{file}` to latest version (failed at {failed_at_version})")]
CouldNotUpgradeExistingConfigurationFileAtVersion {
file: std::path::PathBuf,
failed_at_version: String,
},

#[error("no gateways found in directory")]
NoGatewaysFoundInDirectory,
Expand Down
6 changes: 3 additions & 3 deletions service-providers/network-requester/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, NetworkRequesterError> {

let updated_step1: ConfigV1_1_20 = old_config.into();
let updated_step2: ConfigV1_1_20_2 = updated_step1.into();
let (updated, gateway_config) = updated_step2.upgrade();
let (updated, gateway_config) = updated_step2.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand All @@ -209,7 +209,7 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, NetworkRequesterError> {
info!("It is going to get updated to the current specification.");

let updated_step1: ConfigV1_1_20_2 = old_config.into();
let (updated, gateway_config) = updated_step1.upgrade();
let (updated, gateway_config) = updated_step1.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand All @@ -228,7 +228,7 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, NetworkRequesterError>
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, gateway_config) = old_config.upgrade();
let (updated, gateway_config) = old_config.upgrade()?;
persist_gateway_details(&updated, gateway_config)?;

updated.save_to_default_location()?;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
// Copyright 2023 - Nym Technologies SA <[email protected]>
// SPDX-License-Identifier: Apache-2.0

use crate::config::persistence::NetworkRequesterPaths;
use crate::config::{default_config_filepath, Config, Debug, NetworkRequester};
use crate::{
config::{
default_config_filepath, persistence::NetworkRequesterPaths, Config, Debug,
NetworkRequester,
},
error::NetworkRequesterError,
};

use log::trace;
use nym_bin_common::logging::LoggingSettings;
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
Expand Down Expand Up @@ -58,7 +64,7 @@ impl ConfigV1_1_20_2 {

// in this upgrade, gateway endpoint configuration was moved out of the config file,
// so its returned to be stored elsewhere.
pub fn upgrade(self) -> (Config, GatewayEndpointConfig) {
pub fn upgrade(self) -> Result<(Config, GatewayEndpointConfig), NetworkRequesterError> {
trace!("Upgrading from v1.1.20_2");
let gateway_details = self.base.client.gateway_endpoint.clone().into();
let nr_description = self
Expand All @@ -72,7 +78,7 @@ impl ConfigV1_1_20_2 {
let config = Config {
base: self.base.into(),
storage_paths: NetworkRequesterPaths {
common_paths: self.storage_paths.common_paths.upgrade_default(),
common_paths: self.storage_paths.common_paths.upgrade_default()?,
allowed_list_location: self.storage_paths.allowed_list_location,
unknown_list_location: self.storage_paths.unknown_list_location,
nr_description,
Expand All @@ -82,7 +88,7 @@ impl ConfigV1_1_20_2 {
network_requester: self.network_requester.into(),
};

(config, gateway_details)
Ok((config, gateway_details))
}
}

Expand Down

0 comments on commit c4667a6

Please sign in to comment.