updated config load logic
This commit is contained in:
@@ -77,15 +77,12 @@ impl Args {
|
||||
}
|
||||
|
||||
pub(crate) fn execute(args: Args) -> Result<(), NymvisorError> {
|
||||
let mut env = Env::try_read()?;
|
||||
let env = Env::try_read()?;
|
||||
|
||||
let tmp_daemon = Daemon::new(&args.daemon_binary);
|
||||
tmp_daemon.verify_binary()?;
|
||||
|
||||
let bin_info = tmp_daemon.get_build_information()?;
|
||||
if env.daemon_name.is_none() {
|
||||
env.daemon_name = Some(bin_info.binary_name.clone());
|
||||
}
|
||||
let config = try_load_current_config(&env)?;
|
||||
|
||||
let upgrade_info_path = config.upgrade_info_filepath(&args.upgrade_name);
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::config::{default_config_filepath, Config};
|
||||
use crate::config::{default_config_filepath, default_instances_directory, Config};
|
||||
use crate::env::{setup_env, Env};
|
||||
use crate::error::NymvisorError;
|
||||
use clap::{Parser, Subcommand};
|
||||
use lazy_static::lazy_static;
|
||||
use nym_bin_common::bin_info;
|
||||
use std::path::Path;
|
||||
use tracing::error;
|
||||
use nym_config::{DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME};
|
||||
use std::path::{Path, PathBuf};
|
||||
use tracing::{debug, error};
|
||||
|
||||
mod add_upgrade;
|
||||
mod build_info;
|
||||
@@ -77,12 +78,19 @@ pub(crate) enum Commands {
|
||||
fn open_config_file(env: &Env) -> Result<Config, NymvisorError> {
|
||||
let config_load_location = if let Some(config_path) = &env.nymvisor_config_path {
|
||||
config_path.clone()
|
||||
} else if let Some(nymvisor_id) = &env.nymvisor_id {
|
||||
// if no explicit path was provided in the environment, try to use the default one based on the nymvisor id
|
||||
default_config_filepath(nymvisor_id)
|
||||
} else {
|
||||
// if no explicit path was provided in the environment, try to infer it with other vars
|
||||
let id = env.try_nymvisor_id()?;
|
||||
default_config_filepath(id)
|
||||
// finally, if all else fails, see if this is a singleton -> if so try to load the only instance
|
||||
try_get_singleton_nymvisor_config_path()?
|
||||
};
|
||||
|
||||
debug!(
|
||||
"attempting to load configuration file from {}",
|
||||
config_load_location.display()
|
||||
);
|
||||
|
||||
if let Ok(cfg) = Config::read_from_toml_file(&config_load_location) {
|
||||
return Ok(cfg);
|
||||
}
|
||||
@@ -95,7 +103,7 @@ fn open_config_file(env: &Env) -> Result<Config, NymvisorError> {
|
||||
Err(source) => {
|
||||
error!("Failed to load config from {}. Are you sure you have run `init` before? (Error was: {source})", config_load_location.display());
|
||||
Err(NymvisorError::ConfigLoadFailure {
|
||||
id: env.try_nymvisor_id().unwrap_or_default(),
|
||||
id: env.nymvisor_id.clone().unwrap_or("UNKNOWN".to_string()),
|
||||
path: config_load_location,
|
||||
source,
|
||||
})
|
||||
@@ -103,6 +111,40 @@ fn open_config_file(env: &Env) -> Result<Config, NymvisorError> {
|
||||
}
|
||||
}
|
||||
|
||||
// attempt to get a path to nymvisor's config path if there is only a single instance
|
||||
pub(crate) fn try_get_singleton_nymvisor_config_path() -> Result<PathBuf, NymvisorError> {
|
||||
let instances_dir = default_instances_directory();
|
||||
let mut instances = instances_dir
|
||||
.read_dir()
|
||||
.map_err(|source| NymvisorError::InstancesReadFailure {
|
||||
source,
|
||||
path: instances_dir.clone(),
|
||||
})?
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if instances.len() != 1 {
|
||||
return Err(NymvisorError::NotSingleton {
|
||||
instances: instances.len(),
|
||||
});
|
||||
}
|
||||
|
||||
// safety: that unwrap is fine as we've just checked we have 1 entry in the vector
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let instance_dir = instances
|
||||
.pop()
|
||||
.unwrap()
|
||||
.map_err(|source| NymvisorError::InstancesReadFailure {
|
||||
source,
|
||||
path: instances_dir,
|
||||
})?
|
||||
.path();
|
||||
|
||||
// join the instance directory with `/config/config.toml`
|
||||
Ok(instance_dir
|
||||
.join(DEFAULT_CONFIG_DIR)
|
||||
.join(DEFAULT_CONFIG_FILENAME))
|
||||
}
|
||||
|
||||
pub(crate) fn try_load_current_config(env: &Env) -> Result<Config, NymvisorError> {
|
||||
let mut config = open_config_file(env)?;
|
||||
env.override_config(&mut config);
|
||||
|
||||
@@ -40,13 +40,19 @@ pub(crate) const UPGRADES_DIR: &str = "upgrades";
|
||||
pub(crate) const DEFAULT_NYMVISORS_DIR: &str = "nymvisors";
|
||||
pub(crate) const DEFAULT_NYMVISORS_INSTANCES_DIR: &str = "instances";
|
||||
|
||||
/// Derive default path to the nymvisor's config directory.
|
||||
/// It should get resolved to `$HOME/.nym/nymvisor/instances/<id>/config`
|
||||
pub fn default_config_directory<P: AsRef<Path>>(id: P) -> PathBuf {
|
||||
/// Derive default path top the nymvisors instance directory.
|
||||
/// It should get resolved to `$HOME/.nym/nymvisor/instances`
|
||||
pub fn default_instances_directory() -> PathBuf {
|
||||
must_get_home()
|
||||
.join(NYM_DIR)
|
||||
.join(DEFAULT_NYMVISORS_DIR)
|
||||
.join(DEFAULT_NYMVISORS_INSTANCES_DIR)
|
||||
}
|
||||
|
||||
/// Derive default path to the nymvisor's config directory.
|
||||
/// It should get resolved to `$HOME/.nym/nymvisor/instances/<id>/config`
|
||||
pub fn default_config_directory<P: AsRef<Path>>(id: P) -> PathBuf {
|
||||
default_instances_directory()
|
||||
.join(id)
|
||||
.join(DEFAULT_CONFIG_DIR)
|
||||
}
|
||||
|
||||
@@ -123,16 +123,6 @@ impl Env {
|
||||
config.daemon.debug.unsafe_skip_backup = daemon_unsafe_skip_backup;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn try_nymvisor_id(&self) -> Result<String, NymvisorError> {
|
||||
if let Some(nymvisor_id) = &self.nymvisor_id {
|
||||
Ok(nymvisor_id.clone())
|
||||
} else if let Some(daemon_name) = &self.daemon_name {
|
||||
Ok(Config::default_id(daemon_name))
|
||||
} else {
|
||||
Err(NymvisorError::UnknownNymvisorInstance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: all of those seem like they could be moved to some common crate if we ever needed similar functionality elsewhere
|
||||
|
||||
@@ -282,9 +282,6 @@ While the stored info point to:\n{stored_info:#?}"
|
||||
#[error("the value of daemon home has to be provided by either `--daemon-home` flag or `$DAEMON_HOME` environmental variable")]
|
||||
DaemonHomeUnavailable,
|
||||
|
||||
#[error("could not identify nymvisor instance. please specify either $NYMVISOR_CONFIG_PATH, $NYMVISOR_ID or $DAEMON_NAME")]
|
||||
UnknownNymvisorInstance,
|
||||
|
||||
#[error("failed to obtain build information from the daemon executable ('{}'): {source}", binary_path.display())]
|
||||
DaemonBuildInformationFailure {
|
||||
binary_path: PathBuf,
|
||||
@@ -409,6 +406,16 @@ While the stored info point to:\n{stored_info:#?}"
|
||||
|
||||
#[error("the daemon restart on failure is disabled")]
|
||||
DisabledRestartOnFailure,
|
||||
|
||||
#[error("failed to read directory content of nymvisor instances at {}: {source}", path.display())]
|
||||
InstancesReadFailure {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
source: io::Error,
|
||||
},
|
||||
|
||||
#[error("could not load the default config file as there isn't a single nymvisor instance initiated (there are {instances}). please specify either $NYMVISOR_CONFIG_PATH or $NYMVISOR_ID")]
|
||||
NotSingleton { instances: usize },
|
||||
}
|
||||
|
||||
impl From<ExitStatus> for NymvisorError {
|
||||
|
||||
Reference in New Issue
Block a user