From 1c7d2f5e99b2017ca145224dd72f23e53fd6a3f9 Mon Sep 17 00:00:00 2001 From: Ruediger Birkner Date: Wed, 5 Jun 2024 11:38:25 +0200 Subject: [PATCH] first version --- rs/cli/src/cli.rs | 45 ++++++++++++++++++++++++++++++++++++++ rs/cli/src/ic_admin.rs | 30 +++++++++++++++++++++++--- rs/cli/src/main.rs | 49 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 3 deletions(-) diff --git a/rs/cli/src/cli.rs b/rs/cli/src/cli.rs index caf966f02..506341bde 100644 --- a/rs/cli/src/cli.rs +++ b/rs/cli/src/cli.rs @@ -88,6 +88,9 @@ pub enum Commands { /// Manage nodes Nodes(nodes::Cmd), + /// Manage API boundary nodes + ApiBoundaryNodes(api_boundary_nodes::Cmd), + /// Vote on our proposals Vote { /// Override default accepted proposers @@ -451,6 +454,48 @@ pub mod nodes { } } +pub mod api_boundary_nodes { + use super::*; + + #[derive(Parser, Clone)] + pub struct Cmd { + #[clap(subcommand)] + pub subcommand: Commands, + } + + #[derive(Subcommand, Clone)] + pub enum Commands { + /// Update specified set of nodes to the provided version. + /// The provided "version" must be already elected. + /// The "nodes" list must contain the node IDs where the version should be rolled out. + Update { + /// Node IDs where to rollout the version + #[clap(long, num_args(1..), required = true)] + nodes: Vec, + #[clap(long, required = true)] + version: String, + }, + + /// Turn a set of unassigned nodes into API BNs + Add { + /// Node IDs to turn into API BNs + #[clap(long, num_args(1..), required = true)] + nodes: Vec, + + /// guestOS version + #[clap(long, required = true)] + version: String, + }, + + /// Decommission a set of API BNs and turn them again in unassigned nodes + Remove { + /// Node IDs to turn into API BNs + #[clap(long, num_args(1..), required = true)] + nodes: Vec, + }, + } +} + pub mod proposals { use clap::ValueEnum; use ic_nns_governance::pb::v1::{ProposalStatus as ProposalStatusUpstream, Topic as TopicUpstream}; diff --git a/rs/cli/src/ic_admin.rs b/rs/cli/src/ic_admin.rs index 99692a8e9..03f714423 100644 --- a/rs/cli/src/ic_admin.rs +++ b/rs/cli/src/ic_admin.rs @@ -626,7 +626,7 @@ must be identical, and must match the SHA256 from the payload of the NNS proposa } } - pub async fn update_unassigned_nodes(&self, nns_subned_id: &String, network: &Network, simulate: bool) -> Result<(), Error> { + pub async fn update_unassigned_nodes(&self, nns_subnet_id: &String, network: &Network, simulate: bool) -> Result<(), Error> { let local_registry_path = local_registry_path(network); let local_registry = LocalRegistry::new(local_registry_path, Duration::from_secs(10)) .map_err(|e| anyhow::anyhow!("Error in creating local registry instance: {:?}", e))?; @@ -638,9 +638,9 @@ must be identical, and must match the SHA256 from the payload of the NNS proposa let subnets = local_registry.get_family_entries::()?; - let nns = match subnets.get_key_value(nns_subned_id) { + let nns = match subnets.get_key_value(nns_subnet_id) { Some((_, value)) => value, - None => return Err(anyhow::anyhow!("Couldn't find nns subnet with id '{}'", nns_subned_id)), + None => return Err(anyhow::anyhow!("Couldn't find nns subnet with id '{}'", nns_subnet_id)), }; let registry_state = RegistryState::new(network, true).await; @@ -873,6 +873,17 @@ pub enum ProposeCommand { node_ids: Vec, replica_version: String, }, + AddApiBoundaryNodes { + nodes: Vec, + version: String, + }, + RemoveApiBoundaryNodes { + nodes: Vec, + }, + DeployGuestosToSomeApiBoundaryNodes { + nodes: Vec, + version: String, + }, } impl ProposeCommand { @@ -944,6 +955,19 @@ impl ProposeCommand { Self::DeployGuestosToAllUnassignedNodes { replica_version } => { vec!["--replica-version-id".to_string(), replica_version.clone()] } + Self::AddApiBoundaryNodes { nodes, version } => [ + vec!["--nodes".to_string()], + nodes.iter().map(|n| n.to_string()).collect::>(), + vec!["--version".to_string(), version.to_string()], + ] + .concat(), + Self::RemoveApiBoundaryNodes { nodes } => [vec!["--nodes".to_string()], nodes.iter().map(|n| n.to_string()).collect::>()].concat(), + Self::DeployGuestosToSomeApiBoundaryNodes { nodes, version } => [ + vec!["--nodes".to_string()], + nodes.iter().map(|n| n.to_string()).collect::>(), + vec!["--version".to_string(), version.to_string()], + ] + .concat(), } } } diff --git a/rs/cli/src/main.rs b/rs/cli/src/main.rs index c871e9818..36167223d 100644 --- a/rs/cli/src/main.rs +++ b/rs/cli/src/main.rs @@ -327,6 +327,7 @@ async fn async_main() -> Result<(), anyhow::Error> { } } } + cli::Commands::Nodes(nodes) => match &nodes.subcommand { cli::nodes::Commands::Remove { extra_nodes_filter, @@ -354,6 +355,54 @@ async fn async_main() -> Result<(), anyhow::Error> { } }, + cli::Commands::ApiBoundaryNodes(api_boundary_nodes) => match &api_boundary_nodes.subcommand { + cli::api_boundary_nodes::Commands::Update { nodes, version } => { + runner_instance + .ic_admin + .propose_run( + ic_admin::ProposeCommand::DeployGuestosToSomeApiBoundaryNodes { nodes, version }, + ic_admin::ProposeOptions { + title: Some(format!("Update {} API boundary node(s) to {version}", nodes.clone().len())), + summary: Some(format!("Update {} API boundary node(s) to {version}", nodes.clone().len())), + motivation: None, + }, + simulate, + ) + .await?; + Ok(()) + } + cli::api_boundary_nodes::Commands::Add { nodes, version } => { + runner_instance + .ic_admin + .propose_run( + ic_admin::ProposeCommand::AddApiBoundaryNodes { nodes, version }, + ic_admin::ProposeOptions { + title: Some(format!("Add {} API boundary node(s)", nodes.clone().len())), + summary: Some(format!("Add {} API boundary node(s)", nodes.clone().len())), + motivation: None, + }, + simulate, + ) + .await?; + Ok(()) + } + cli::api_boundary_nodes::Commands::Remove { nodes } => { + runner_instance + .ic_admin + .propose_run( + ic_admin::ProposeCommand::RemoveApiBoundaryNodes { nodes }, + ic_admin::ProposeOptions { + title: Some(format!("Remove {} API boundary node(s)", nodes.clone().len())), + summary: Some(format!("Remove {} API boundary node(s)", nodes.clone().len())), + motivation: None, + }, + simulate, + ) + .await?; + Ok(()) + } + }, + cli::Commands::Vote { accepted_neurons, accepted_topics,