diff --git a/resources/ansible/start_nodes.yml b/resources/ansible/start_nodes.yml index 8efaf4c0..c1f50783 100644 --- a/resources/ansible/start_nodes.yml +++ b/resources/ansible/start_nodes.yml @@ -2,6 +2,8 @@ - name: ensure all nodes are started using the node manager hosts: all become: True + vars: + interval: "{{ interval }}" tasks: - name: start - ansible.builtin.command: safenode-manager start --interval 2000 + ansible.builtin.command: "safenode-manager start --interval {{ interval }}" diff --git a/resources/ansible/upgrade_faucet.yml b/resources/ansible/upgrade_faucet.yml deleted file mode 100644 index ffd1de88..00000000 --- a/resources/ansible/upgrade_faucet.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- name: upgrade the faucet using the node manager - hosts: all - tasks: - - name: upgrade - ansible.builtin.command: - # The `omit` filter removes arguments without values - argv: "{{ command_args | reject('equalto', omit) | list }}" - vars: - command_args: - - safenode-manager - - faucet - - upgrade - - "{{ '--force' if force_faucet is defined else omit }}" - - "{{ ('--env=' + env_variables) if env_variables is defined else omit }}" - - "{{ ('--version=' + faucet_version) if faucet_version is defined else omit }}" diff --git a/resources/ansible/upgrade_uploaders.yml b/resources/ansible/upgrade_uploaders.yml index 816514ac..a3bd8a81 100644 --- a/resources/ansible/upgrade_uploaders.yml +++ b/resources/ansible/upgrade_uploaders.yml @@ -3,39 +3,46 @@ hosts: all become: True vars: - safe_version: "{{ safe_version }}" - safe_archive_url: "https://autonomi-cli.s3.eu-west-2.amazonaws.com/safe-{{ safe_version }}-x86_64-unknown-linux-musl.tar.gz" + autonomi_version: "{{ autonomi_version }}" + autonomi_archive_url: "https://autonomi-cli.s3.eu-west-2.amazonaws.com/autonomi-{{ autonomi_version }}-x86_64-unknown-linux-musl.tar.gz" tasks: - - name: stop the uploader service + - name: get list of safe users + ansible.builtin.shell: "getent passwd | grep '^safe[0-9]\\+:' | cut -d: -f1" + register: safe_users + changed_when: false + + - name: stop all uploader services systemd: - name: safe_uploader + name: "autonomi_uploader_{{ item | regex_replace('safe([0-9]+)', '\\1') }}" state: stopped + loop: "{{ safe_users.stdout_lines }}" # It is safer to make sure both of these are removed, because Ansible may not re-download and # replace them if they already exist. - - name: remove existing safe binary + - name: remove existing autonomi binary ansible.builtin.file: - path: /usr/local/bin/safe + path: /usr/local/bin/autonomi state: absent - - name: remove existing safe archive + - name: remove existing autonomi archive ansible.builtin.file: - path: /tmp/safe-latest-x86_64-unknown-linux-musl.tar.gz + path: /tmp/autonomi-latest-x86_64-unknown-linux-musl.tar.gz state: absent - - name: download the new safe binary + - name: download the new autonomi binary ansible.builtin.get_url: - url: "{{ safe_archive_url }}" - dest: /tmp/safe-latest-x86_64-unknown-linux-musl.tar.gz + url: "{{ autonomi_archive_url }}" + dest: /tmp/autonomi-latest-x86_64-unknown-linux-musl.tar.gz - - name: extract the new safe binary + - name: extract the new autonomi binary ansible.builtin.unarchive: - src: /tmp/safe-latest-x86_64-unknown-linux-musl.tar.gz + src: /tmp/autonomi-latest-x86_64-unknown-linux-musl.tar.gz dest: /usr/local/bin remote_src: True - - name: start the uploader service + - name: start all uploader services systemd: - name: safe_uploader + name: "autonomi_uploader_{{ item | regex_replace('safe([0-9]+)', '\\1') }}" state: started - enabled: true \ No newline at end of file + enabled: true + loop: "{{ safe_users.stdout_lines }}" \ No newline at end of file diff --git a/src/ansible/inventory.rs b/src/ansible/inventory.rs index ecd2dd87..db6e207f 100644 --- a/src/ansible/inventory.rs +++ b/src/ansible/inventory.rs @@ -120,7 +120,6 @@ impl AnsibleInventoryType { Self::BootstrapNodes, Self::Nodes, Self::PrivateNodes, - Self::EvmNodes, ] .into_iter() } diff --git a/src/ansible/mod.rs b/src/ansible/mod.rs index 3db41c9f..82cb0f0d 100644 --- a/src/ansible/mod.rs +++ b/src/ansible/mod.rs @@ -142,10 +142,6 @@ pub enum AnsiblePlaybook { StopTelegraf, /// This playbook will stop the uploaders on each machine. StopUploaders, - /// The upgrade faucet playbook will upgrade the faucet to the latest version. - /// - /// Use in combination with `AnsibleInventoryType::Genesis`. - UpgradeFaucet, /// The upgrade node manager playbook will upgrade the node manager to the latest version. /// /// Use in combination with `AnsibleInventoryType::Genesis` or `AnsibleInventoryType::Nodes`. @@ -191,7 +187,6 @@ impl AnsiblePlaybook { AnsiblePlaybook::StopFaucet => "stop_faucet.yml".to_string(), AnsiblePlaybook::StopTelegraf => "stop_telegraf.yml".to_string(), AnsiblePlaybook::StopUploaders => "stop_uploaders.yml".to_string(), - AnsiblePlaybook::UpgradeFaucet => "upgrade_faucet.yml".to_string(), AnsiblePlaybook::UpgradeNodeManager => "upgrade_node_manager.yml".to_string(), AnsiblePlaybook::UpgradeNodes => "upgrade_nodes.yml".to_string(), AnsiblePlaybook::UpgradeNodeTelegrafConfig => { diff --git a/src/ansible/provisioning.rs b/src/ansible/provisioning.rs index 9a58ed02..5c42f181 100644 --- a/src/ansible/provisioning.rs +++ b/src/ansible/provisioning.rs @@ -22,7 +22,11 @@ use evmlib::common::U256; use log::{debug, error, trace}; use semver::Version; use sn_service_management::NodeRegistry; -use std::{net::SocketAddr, path::PathBuf, time::Instant}; +use std::{ + net::SocketAddr, + path::PathBuf, + time::{Duration, Instant}, +}; use walkdir::WalkDir; use crate::ansible::extra_vars; @@ -490,12 +494,37 @@ impl AnsibleProvisioner { Ok(()) } - pub fn start_nodes(&self) -> Result<()> { - for node_inv_type in AnsibleInventoryType::iter_node_type() { - self.ansible_runner - .run_playbook(AnsiblePlaybook::StartNodes, node_inv_type, None)?; + pub fn start_nodes( + &self, + environment_name: &str, + interval: Duration, + custom_inventory: Option>, + ) -> Result<()> { + let mut extra_vars = ExtraVarsDocBuilder::default(); + extra_vars.add_variable("interval", &interval.as_millis().to_string()); + + if let Some(custom_inventory) = custom_inventory { + println!("Running the start telegraf playbook with a custom inventory"); + generate_custom_environment_inventory( + &custom_inventory, + environment_name, + &self.ansible_runner.working_directory_path.join("inventory"), + )?; + self.ansible_runner.run_playbook( + AnsiblePlaybook::StartNodes, + AnsibleInventoryType::Custom, + Some(extra_vars.build()), + )?; + return Ok(()); } + for node_inv_type in AnsibleInventoryType::iter_node_type() { + self.ansible_runner.run_playbook( + AnsiblePlaybook::StartNodes, + node_inv_type, + Some(extra_vars.build()), + )?; + } Ok(()) } @@ -665,16 +694,6 @@ impl AnsibleProvisioner { println!("WARNING: the genesis node may not have been upgraded or restarted"); } } - match self.ansible_runner.run_playbook( - AnsiblePlaybook::UpgradeFaucet, - AnsibleInventoryType::Genesis, - Some(options.get_ansible_vars()), - ) { - Ok(()) => println!("The faucet was successfully upgraded"), - Err(_) => { - println!("WARNING: the faucet may not have been upgraded or restarted"); - } - } Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index ae0535ba..397ed1f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -338,14 +338,12 @@ pub struct UpgradeOptions { pub ansible_verbose: bool, pub custom_inventory: Option>, pub env_variables: Option>, - pub faucet_version: Option, - pub force_faucet: bool, - pub force_safenode: bool, + pub force: bool, pub forks: usize, pub interval: Duration, pub name: String, pub provider: CloudProvider, - pub safenode_version: Option, + pub version: Option, } impl UpgradeOptions { @@ -355,16 +353,10 @@ impl UpgradeOptions { if let Some(env_variables) = &self.env_variables { extra_vars.add_env_variable_list("env_variables", env_variables.clone()); } - if self.force_faucet { - extra_vars.add_variable("force_faucet", &self.force_faucet.to_string()); + if self.force { + extra_vars.add_variable("force", &self.force.to_string()); } - if let Some(version) = &self.faucet_version { - extra_vars.add_variable("faucet_version", version); - } - if self.force_safenode { - extra_vars.add_variable("force_safenode", &self.force_safenode.to_string()); - } - if let Some(version) = &self.safenode_version { + if let Some(version) = &self.version { extra_vars.add_variable("safenode_version", version); } extra_vars.build() @@ -640,8 +632,13 @@ impl TestnetDeployer { Ok(()) } - pub fn start(&self) -> Result<()> { - self.ansible_provisioner.start_nodes()?; + pub fn start( + &self, + interval: Duration, + custom_inventory: Option>, + ) -> Result<()> { + self.ansible_provisioner + .start_nodes(&self.environment_name, interval, custom_inventory)?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 4f3d8b4e..db6248ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -560,9 +560,17 @@ enum Commands { /// This can be useful if all nodes did not upgrade successfully. #[clap(name = "start")] Start { + /// Provide a list of VM names to use as a custom inventory. + /// + /// This will start nodes on a particular subset of VMs. + #[clap(name = "custom-inventory", long, use_value_delimiter = true)] + custom_inventory: Option>, /// Maximum number of forks Ansible will use to execute tasks on target hosts. #[clap(long, default_value_t = 50)] forks: usize, + /// The interval between each node start in milliseconds. + #[clap(long, value_parser = |t: &str| -> Result { Ok(t.parse().map(Duration::from_millis)?)}, default_value = "2000")] + interval: Duration, /// The name of the environment. #[arg(short = 'n', long)] name: String, @@ -646,24 +654,11 @@ enum Commands { /// Example: --env SN_LOG=all,RUST_LOG=libp2p=debug #[clap(name = "env", long, use_value_delimiter = true, value_parser = parse_environment_variables)] env_variables: Option>, - /// Optionally supply a version for the faucet binary to be upgraded to. - /// - /// If not provided, the latest version will be used. A lower version number can be - /// specified to downgrade to a known good version. - /// - /// There should be no 'v' prefix. - #[arg(long)] - faucet_version: Option, - /// Set to force the node manager to accept the faucet version provided. - /// - /// This can be used to downgrade the faucet to a known good version. - #[clap(long)] - force_faucet: bool, /// Set to force the node manager to accept the safenode version provided. /// /// This can be used to downgrade safenode to a known good version. #[clap(long)] - force_safenode: bool, + force: bool, /// Maximum number of forks Ansible will use to execute tasks on target hosts. #[clap(long, default_value_t = 2)] forks: usize, @@ -685,7 +680,7 @@ enum Commands { /// specified to downgrade to a known good version. /// /// There should be no 'v' prefix. - safenode_version: Option, + version: Option, }, /// Upgrade the safenode-manager binaries to a particular version. /// @@ -1090,7 +1085,7 @@ enum UploadersCommands { /// /// If not provided, the latest version will be used. #[arg(long)] - safe_version: Option, + version: Option, }, /// Upscale uploaders for an existing network. Upscale { @@ -1403,27 +1398,31 @@ async fn main() -> Result<()> { } Commands::Deploy { ansible_verbose, - branch, bootstrap_node_count, bootstrap_node_vm_count, + bootstrap_node_vm_size, + branch, chunk_size, downloaders_count, - environment_type, env_variables, + environment_type, evm_network_type, + evm_node_vm_size, faucet_version, forks, foundation_pk, + funding_wallet_secret_key, genesis_pk, log_format, logstash_stack_name, + max_archived_log_files, + max_log_files, name, network_contacts_file_name, network_royalties_pk, node_count, node_vm_count, - max_archived_log_files, - max_log_files, + node_vm_size, payment_forward_pk, private_node_count, private_node_vm_count, @@ -1434,15 +1433,11 @@ async fn main() -> Result<()> { rewards_address, safe_version, safenode_features, - safenode_version, safenode_manager_version, - uploaders_count, + safenode_version, uploader_vm_count, - funding_wallet_secret_key, - node_vm_size, - bootstrap_node_vm_size, uploader_vm_size, - evm_node_vm_size, + uploaders_count, } => { let network_keys = validate_and_get_pks( foundation_pk, @@ -1988,7 +1983,9 @@ async fn main() -> Result<()> { Ok(()) } Commands::Start { + custom_inventory, forks, + interval, name, provider, } => { @@ -2009,7 +2006,14 @@ async fn main() -> Result<()> { return Err(eyre!("The {name} environment does not exist")); } - testnet_deployer.start()?; + let custom_inventory = if let Some(custom_inventory) = custom_inventory { + let custom_vms = get_custom_inventory(&inventory, &custom_inventory)?; + Some(custom_vms) + } else { + None + }; + + testnet_deployer.start(interval, custom_inventory)?; Ok(()) } @@ -2146,14 +2150,12 @@ async fn main() -> Result<()> { ansible_verbose, custom_inventory, env_variables, - faucet_version, - force_faucet, - force_safenode, + force, forks, interval, name, provider, - safenode_version, + version, } => { // The upgrade intentionally uses a small value for `forks`, but this is far too slow // for retrieving the inventory from a large deployment. Therefore, we will use 50 @@ -2189,14 +2191,12 @@ async fn main() -> Result<()> { ansible_verbose, custom_inventory, env_variables, - faucet_version, - force_faucet, - force_safenode, + force, forks, interval, name: name.clone(), provider, - safenode_version, + version, })?; // Recreate the deployer with an increased number of forks for retrieving the status. @@ -2330,9 +2330,9 @@ async fn main() -> Result<()> { UploadersCommands::Upgrade { name, provider, - safe_version, + version, } => { - let version = get_version_from_option(safe_version, &ReleaseType::Autonomi).await?; + let version = get_version_from_option(version, &ReleaseType::Autonomi).await?; let testnet_deploy = TestnetDeployBuilder::default() .environment_name(&name) @@ -2349,7 +2349,7 @@ async fn main() -> Result<()> { let ansible_runner = testnet_deploy.ansible_provisioner.ansible_runner; let mut extra_vars = ExtraVarsDocBuilder::default(); - extra_vars.add_variable("safe_version", &version.to_string()); + extra_vars.add_variable("autonomi_version", &version.to_string()); ansible_runner.run_playbook( AnsiblePlaybook::UpgradeUploaders, AnsibleInventoryType::Uploaders,