From 45336addd1f51b109b2fbe6b19fbd4f50df973b4 Mon Sep 17 00:00:00 2001 From: Lautaro Mazzitelli Date: Tue, 5 Nov 2024 17:32:38 +0100 Subject: [PATCH] feat(launchpad): upgrade nodes version --- node-launchpad/.config/config.json5 | 2 + node-launchpad/src/action.rs | 4 + node-launchpad/src/app.rs | 4 +- node-launchpad/src/components/options.rs | 73 ++++--- node-launchpad/src/components/popup.rs | 1 + .../src/components/popup/rewards_address.rs | 1 - .../src/components/popup/upgrade_nodes.rs | 182 ++++++++++++++++++ node-launchpad/src/components/status.rs | 124 ++++++++++-- node-launchpad/src/mode.rs | 1 + node-launchpad/src/node_mgmt.rs | 54 ++++++ sn_node_manager/src/cmd/mod.rs | 8 +- sn_node_manager/src/cmd/node.rs | 4 +- 12 files changed, 414 insertions(+), 44 deletions(-) create mode 100644 node-launchpad/src/components/popup/upgrade_nodes.rs diff --git a/node-launchpad/.config/config.json5 b/node-launchpad/.config/config.json5 index c630bfdc7f..ac376945d3 100644 --- a/node-launchpad/.config/config.json5 +++ b/node-launchpad/.config/config.json5 @@ -54,6 +54,8 @@ "": {"OptionsActions":"TriggerAccessLogs"}, "": {"OptionsActions":"TriggerAccessLogs"}, "": {"OptionsActions":"TriggerAccessLogs"}, + "": {"OptionsActions":"TriggerUpdateNodes"}, + "": {"OptionsActions":"TriggerUpdateNodes"}, "": {"OptionsActions":"TriggerResetNodes"}, "": {"OptionsActions":"TriggerResetNodes"}, "": {"OptionsActions":"TriggerResetNodes"}, diff --git a/node-launchpad/src/action.rs b/node-launchpad/src/action.rs index 60c6cd618d..2cc81ca675 100644 --- a/node-launchpad/src/action.rs +++ b/node-launchpad/src/action.rs @@ -48,6 +48,7 @@ pub enum StatusActions { StartNodesCompleted, StopNodesCompleted, ResetNodesCompleted { trigger_start_node: bool }, + UpdateNodesCompleted, SuccessfullyDetectedNatStatus, ErrorWhileRunningNatDetection, ErrorLoadingNodeRegistry { raw_error: String }, @@ -55,6 +56,7 @@ pub enum StatusActions { ErrorScalingUpNodes { raw_error: String }, ErrorStoppingNodes { raw_error: String }, ErrorResettingNodes { raw_error: String }, + ErrorUpdatingNodes { raw_error: String }, NodesStatsObtained(NodeStats), TriggerManageNodes, @@ -67,11 +69,13 @@ pub enum StatusActions { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Display, Deserialize)] pub enum OptionsActions { ResetNodes, + UpdateNodes, TriggerChangeDrive, TriggerChangeConnectionMode, TriggerChangePortRange, TriggerRewardsAddress, + TriggerUpdateNodes, TriggerResetNodes, TriggerAccessLogs, UpdateConnectionMode(ConnectionMode), diff --git a/node-launchpad/src/app.rs b/node-launchpad/src/app.rs index 7c191b1abe..f4247b114b 100644 --- a/node-launchpad/src/app.rs +++ b/node-launchpad/src/app.rs @@ -16,7 +16,7 @@ use crate::{ popup::{ change_drive::ChangeDrivePopup, connection_mode::ChangeConnectionModePopUp, manage_nodes::ManageNodes, port_range::PortRangePopUp, reset_nodes::ResetNodesPopup, - rewards_address::RewardsAddress, + rewards_address::RewardsAddress, upgrade_nodes::UpgradeNodesPopUp, }, status::{Status, StatusConfig}, Component, @@ -120,6 +120,7 @@ impl App { let change_connection_mode = ChangeConnectionModePopUp::new(connection_mode)?; let port_range = PortRangePopUp::new(connection_mode, port_from, port_to); let rewards_address = RewardsAddress::new(app_data.discord_username.clone()); + let upgrade_nodes = UpgradeNodesPopUp::default(); Ok(Self { config, @@ -146,6 +147,7 @@ impl App { Box::new(rewards_address), Box::new(reset_nodes), Box::new(manage_nodes), + Box::new(upgrade_nodes), ], should_quit: false, should_suspend: false, diff --git a/node-launchpad/src/components/options.rs b/node-launchpad/src/components/options.rs index a631d41b5e..4f59a89f3c 100644 --- a/node-launchpad/src/components/options.rs +++ b/node-launchpad/src/components/options.rs @@ -1,6 +1,6 @@ -use std::path::PathBuf; +use std::{cmp::max, path::PathBuf}; -use color_eyre::eyre::{eyre, Result}; +use color_eyre::eyre::{eyre, Ok, Result}; use ratatui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Style, Stylize}, @@ -74,7 +74,7 @@ impl Component for Options { Constraint::Length(7), Constraint::Length(3), Constraint::Length(3), - Constraint::Length(3), + Constraint::Length(4), Constraint::Length(3), ] .as_ref(), @@ -271,35 +271,58 @@ impl Component for Options { .block(block3) .style(Style::default().fg(GHOST_WHITE)); - // Reset All Nodes + // Update Nodes let reset_legend = " Begin Reset "; let reset_key = " [Ctrl+R] "; + let upgrade_legend = " Begin Upgrade "; + let upgrade_key = " [Ctrl+U] "; let block4 = Block::default() - .title(" Reset All Nodes ") + .title(" Update Nodes ") .title_style(Style::default().bold().fg(GHOST_WHITE)) .style(Style::default().fg(GHOST_WHITE)) .borders(Borders::ALL) .border_style(Style::default().fg(EUCALYPTUS)); let reset_nodes = Table::new( - vec![Row::new(vec![ - Cell::from( - Line::from(vec![Span::styled( - " Remove and Reset all Nodes on this device ", - Style::default().fg(LIGHT_PERIWINKLE), - )]) - .alignment(Alignment::Left), - ), - Cell::from( - Line::from(vec![ - Span::styled(reset_legend, Style::default().fg(EUCALYPTUS)), - Span::styled(reset_key, Style::default().fg(GHOST_WHITE)), - ]) - .alignment(Alignment::Right), - ), - ])], + vec![ + Row::new(vec![ + Cell::from( + Line::from(vec![Span::styled( + " Upgrade all Nodes ", + Style::default().fg(LIGHT_PERIWINKLE), + )]) + .alignment(Alignment::Left), + ), + Cell::from( + Line::from(vec![ + Span::styled(upgrade_legend, Style::default().fg(EUCALYPTUS)), + Span::styled(upgrade_key, Style::default().fg(GHOST_WHITE)), + ]) + .alignment(Alignment::Right), + ), + ]), + Row::new(vec![ + Cell::from( + Line::from(vec![Span::styled( + " Reset all Nodes on this device ", + Style::default().fg(LIGHT_PERIWINKLE), + )]) + .alignment(Alignment::Left), + ), + Cell::from( + Line::from(vec![ + Span::styled(reset_legend, Style::default().fg(EUCALYPTUS)), + Span::styled(reset_key, Style::default().fg(GHOST_WHITE)), + ]) + .alignment(Alignment::Right), + ), + ]), + ], &[ Constraint::Fill(1), - Constraint::Length((reset_legend.len() + reset_key.len()) as u16), + Constraint::Length( + (max(reset_legend.len(), upgrade_legend.len()) + + max(reset_key.len(), upgrade_key.len())) as u16, + ), ], ) .block(block4) @@ -355,7 +378,8 @@ impl Component for Options { | Scene::ChangeConnectionModePopUp | Scene::ChangePortsPopUp { .. } | Scene::OptionsRewardsAddressPopUp - | Scene::ResetNodesPopUp => { + | Scene::ResetNodesPopUp + | Scene::UpgradeNodesPopUp => { self.active = true; // make sure we're in navigation mode return Ok(Some(Action::SwitchInputMode(InputMode::Navigation))); @@ -402,6 +426,9 @@ impl Component for Options { error!("Failed to open folder: {}", e); } } + OptionsActions::TriggerUpdateNodes => { + return Ok(Some(Action::SwitchScene(Scene::UpgradeNodesPopUp))); + } OptionsActions::TriggerResetNodes => { return Ok(Some(Action::SwitchScene(Scene::ResetNodesPopUp))) } diff --git a/node-launchpad/src/components/popup.rs b/node-launchpad/src/components/popup.rs index 4c0c37a1c7..964dbe8a8d 100644 --- a/node-launchpad/src/components/popup.rs +++ b/node-launchpad/src/components/popup.rs @@ -12,3 +12,4 @@ pub mod manage_nodes; pub mod port_range; pub mod reset_nodes; pub mod rewards_address; +pub mod upgrade_nodes; diff --git a/node-launchpad/src/components/popup/rewards_address.rs b/node-launchpad/src/components/popup/rewards_address.rs index 8ec3741034..a4dd4f0f44 100644 --- a/node-launchpad/src/components/popup/rewards_address.rs +++ b/node-launchpad/src/components/popup/rewards_address.rs @@ -34,7 +34,6 @@ pub struct RewardsAddress { can_save: bool, } -#[allow(dead_code)] enum RewardsAddressState { RewardsAddressAlreadySet, ShowTCs, diff --git a/node-launchpad/src/components/popup/upgrade_nodes.rs b/node-launchpad/src/components/popup/upgrade_nodes.rs new file mode 100644 index 0000000000..d658970867 --- /dev/null +++ b/node-launchpad/src/components/popup/upgrade_nodes.rs @@ -0,0 +1,182 @@ +// Copyright 2024 MaidSafe.net limited. +// +// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3. +// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed +// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. Please review the Licences for the specific language governing +// permissions and limitations relating to use of the SAFE Network Software. + +use super::super::utils::centered_rect_fixed; +use super::super::Component; +use crate::{ + action::{Action, OptionsActions}, + mode::{InputMode, Scene}, + style::{clear_area, EUCALYPTUS, GHOST_WHITE, LIGHT_PERIWINKLE, VIVID_SKY_BLUE}, +}; +use color_eyre::Result; +use crossterm::event::{KeyCode, KeyEvent}; +use ratatui::{prelude::*, widgets::*}; + +pub struct UpgradeNodesPopUp { + /// Whether the component is active right now, capturing keystrokes + draw things. + active: bool, +} + +impl UpgradeNodesPopUp { + pub fn new() -> Self { + Self { active: false } + } +} + +impl Default for UpgradeNodesPopUp { + fn default() -> Self { + Self::new() + } +} + +impl Component for UpgradeNodesPopUp { + fn handle_key_events(&mut self, key: KeyEvent) -> Result> { + if !self.active { + return Ok(vec![]); + } + // while in entry mode, keybinds are not captured, so gotta exit entry mode from here + let send_back = match key.code { + KeyCode::Enter => { + debug!("Got Enter, Upgrading nodes..."); + vec![ + Action::OptionsActions(OptionsActions::UpdateNodes), + Action::SwitchScene(Scene::Status), + ] + } + KeyCode::Esc => { + debug!("Got Esc, Not upgrading nodes."); + vec![Action::SwitchScene(Scene::Options)] + } + _ => vec![], + }; + Ok(send_back) + } + + fn update(&mut self, action: Action) -> Result> { + let send_back = match action { + Action::SwitchScene(scene) => match scene { + Scene::UpgradeNodesPopUp => { + self.active = true; + Some(Action::SwitchInputMode(InputMode::Entry)) + } + _ => { + self.active = false; + None + } + }, + _ => None, + }; + Ok(send_back) + } + + fn draw(&mut self, f: &mut crate::tui::Frame<'_>, area: Rect) -> Result<()> { + if !self.active { + return Ok(()); + } + + let layer_zero = centered_rect_fixed(52, 15, area); + + let layer_one = Layout::new( + Direction::Vertical, + [ + // for the pop_up_border + Constraint::Length(2), + // for the input field + Constraint::Min(1), + // for the pop_up_border + Constraint::Length(1), + ], + ) + .split(layer_zero); + + // layer zero + let pop_up_border = Paragraph::new("").block( + Block::default() + .borders(Borders::ALL) + .title(" Upgrade all nodes ") + .bold() + .title_style(Style::new().fg(VIVID_SKY_BLUE)) + .padding(Padding::uniform(2)) + .border_style(Style::new().fg(VIVID_SKY_BLUE)), + ); + clear_area(f, layer_zero); + + // split the area into 3 parts, for the lines, hypertext, buttons + let layer_two = Layout::new( + Direction::Vertical, + [ + // for the text + Constraint::Length(9), + // gap + Constraint::Length(4), + // for the buttons + Constraint::Length(1), + ], + ) + .split(layer_one[1]); + + let text = Paragraph::new(vec![ + Line::from(Span::styled("\n\n", Style::default())), + Line::from(vec![ + Span::styled("This will ", Style::default().fg(LIGHT_PERIWINKLE)), + Span::styled( + "stop and upgrade all nodes. ", + Style::default().fg(GHOST_WHITE), + ), + ]), + Line::from(Span::styled( + "No data will be lost.", + Style::default().fg(LIGHT_PERIWINKLE), + )), + Line::from(Span::styled("\n\n", Style::default())), + Line::from(Span::styled("\n\n", Style::default())), + Line::from(vec![ + Span::styled("You’ll need to ", Style::default().fg(LIGHT_PERIWINKLE)), + Span::styled("Start ", Style::default().fg(GHOST_WHITE)), + Span::styled( + "them again afterwards.", + Style::default().fg(LIGHT_PERIWINKLE), + ), + ]), + Line::from(Span::styled( + "Are you sure you want to continue?", + Style::default(), + )), + ]) + .block(Block::default().padding(Padding::horizontal(2))) + .alignment(Alignment::Center) + .wrap(Wrap { trim: true }); + + f.render_widget(text, layer_two[0]); + + let dash = Block::new() + .borders(Borders::BOTTOM) + .border_style(Style::new().fg(GHOST_WHITE)); + f.render_widget(dash, layer_two[1]); + + let buttons_layer = + Layout::horizontal(vec![Constraint::Percentage(45), Constraint::Percentage(55)]) + .split(layer_two[2]); + + let button_no = Line::from(vec![Span::styled( + " No, Cancel [Esc]", + Style::default().fg(LIGHT_PERIWINKLE), + )]); + f.render_widget(button_no, buttons_layer[0]); + + let button_yes = Paragraph::new(Line::from(vec![Span::styled( + "Yes, Upgrade [Enter] ", + Style::default().fg(EUCALYPTUS), + )])) + .alignment(Alignment::Right); + f.render_widget(button_yes, buttons_layer[1]); + f.render_widget(pop_up_border, layer_zero); + + Ok(()) + } +} diff --git a/node-launchpad/src/components/status.rs b/node-launchpad/src/components/status.rs index 3c82045f7b..1847ef1ee5 100644 --- a/node-launchpad/src/components/status.rs +++ b/node-launchpad/src/components/status.rs @@ -17,7 +17,7 @@ use crate::components::popup::port_range::PORT_ALLOCATION; use crate::config::get_launchpad_nodes_data_dir_path; use crate::connection_mode::ConnectionMode; use crate::error::ErrorPopup; -use crate::node_mgmt::MaintainNodesArgs; +use crate::node_mgmt::{upgrade_nodes, MaintainNodesArgs, UpgradeNodesArgs}; use crate::node_mgmt::{PORT_MAX, PORT_MIN}; use crate::style::{COOL_GREY, INDIGO}; use crate::tui::Event; @@ -111,6 +111,7 @@ pub enum LockRegistryState { StartingNodes, StoppingNodes, ResettingNodes, + UpdatingNodes, } pub struct StatusConfig { @@ -167,7 +168,7 @@ impl Status<'_> { Ok(status) } - fn update_node_items(&mut self) -> Result<()> { + fn update_node_items(&mut self, new_status: Option) -> Result<()> { // Iterate over existing node services and update their corresponding NodeItem if let Some(ref mut items) = self.items { for node_item in self.node_services.iter() { @@ -177,21 +178,27 @@ impl Status<'_> { .iter_mut() .find(|i| i.name == node_item.service_name) { - // Update status based on current node status - item.status = match node_item.status { - ServiceStatus::Running => { + if let Some(status) = new_status { + item.status = status; + } else { + // Update status based on current node status + item.status = match node_item.status { + ServiceStatus::Running => { + NodeItem::update_spinner_state(&mut item.spinner_state); + NodeStatus::Running + } + ServiceStatus::Stopped => NodeStatus::Stopped, + ServiceStatus::Added => NodeStatus::Added, + ServiceStatus::Removed => NodeStatus::Removed, + }; + + // Starting is not part of ServiceStatus so we do it manually + if let Some(LockRegistryState::StartingNodes) = self.lock_registry { NodeItem::update_spinner_state(&mut item.spinner_state); - NodeStatus::Running + if item.status != NodeStatus::Running { + item.status = NodeStatus::Starting; + } } - ServiceStatus::Stopped => NodeStatus::Stopped, - ServiceStatus::Added => NodeStatus::Added, - ServiceStatus::Removed => NodeStatus::Removed, - }; - - // Starting is not part of ServiceStatus so we do it manually - if let Some(LockRegistryState::StartingNodes) = self.lock_registry { - NodeItem::update_spinner_state(&mut item.spinner_state); - item.status = NodeStatus::Starting; } // Update peers count @@ -332,6 +339,21 @@ impl Status<'_> { }) .collect() } + + fn get_service_names_and_peer_ids(&self) -> (Vec, Vec) { + let mut service_names = Vec::new(); + let mut peers_ids = Vec::new(); + + for node in &self.node_services { + // Only include nodes with a valid peer_id + if let Some(peer_id) = &node.peer_id { + service_names.push(node.service_name.clone()); + peers_ids.push(peer_id.to_string().clone()); + } + } + + (service_names, peers_ids) + } } impl Component for Status<'_> { @@ -361,7 +383,7 @@ impl Component for Status<'_> { match action { Action::Tick => { self.try_update_node_stats(false)?; - let _ = self.update_node_items(); + let _ = self.update_node_items(None); } Action::SwitchScene(scene) => match scene { Scene::Status | Scene::StatusRewardsAddressPopUp => { @@ -431,6 +453,13 @@ impl Component for Status<'_> { self.lock_registry = None; self.load_node_registry_and_update_states()?; } + StatusActions::UpdateNodesCompleted => { + self.lock_registry = None; + self.clear_node_items(); + self.load_node_registry_and_update_states()?; + let _ = self.update_node_items(None); + debug!("Update nodes completed"); + } StatusActions::ResetNodesCompleted { trigger_start_node } => { self.lock_registry = None; self.load_node_registry_and_update_states()?; @@ -492,6 +521,18 @@ impl Component for Status<'_> { // Switch back to entry mode so we can handle key events return Ok(Some(Action::SwitchInputMode(InputMode::Entry))); } + StatusActions::ErrorUpdatingNodes { raw_error } => { + self.error_popup = Some(ErrorPopup::new( + "Error".to_string(), + "Error upgrading nodes".to_string(), + raw_error, + )); + if let Some(error_popup) = &mut self.error_popup { + error_popup.show(); + } + // Switch back to entry mode so we can handle key events + return Ok(Some(Action::SwitchInputMode(InputMode::Entry))); + } StatusActions::ErrorResettingNodes { raw_error } => { self.error_popup = Some(ErrorPopup::new( "Error".to_string(), @@ -591,6 +632,40 @@ impl Component for Status<'_> { } } }, + Action::OptionsActions(OptionsActions::UpdateNodes) => { + debug!("Got action to Update Nodes"); + self.load_node_registry_and_update_states()?; + if self.lock_registry.is_some() { + error!( + "Registry is locked ({:?}) Cannot Update nodes now. Stop them first.", + self.lock_registry + ); + return Ok(None); + } else { + debug!("Lock registry ({:?})", self.lock_registry); + }; + debug!("Setting lock_registry to UpdatingNodes"); + self.lock_registry = Some(LockRegistryState::UpdatingNodes); + let action_sender = self.get_actions_sender()?; + info!("Got action to update nodes"); + let _ = self.update_node_items(Some(NodeStatus::Updating)); + let (service_names, peer_ids) = self.get_service_names_and_peer_ids(); + + let upgrade_nodes_args = UpgradeNodesArgs { + action_sender, + connection_timeout_s: 5, + do_not_start: true, + custom_bin_path: None, + force: false, + fixed_interval: None, + peer_ids, + provided_env_variables: None, + service_names, + url: None, + version: None, + }; + upgrade_nodes(upgrade_nodes_args); + } Action::OptionsActions(OptionsActions::ResetNodes) => { debug!("Got action to reset nodes"); if self.lock_registry.is_some() { @@ -919,6 +994,9 @@ impl Component for Status<'_> { Line::raw("Resetting nodes..."), ] } + LockRegistryState::UpdatingNodes => { + return Ok(()); + } }; if !popup_text.is_empty() { let popup_area = centered_rect_fixed(50, 12, area); @@ -1027,6 +1105,7 @@ enum NodeStatus { Starting, Stopped, Removed, + Updating, } impl fmt::Display for NodeStatus { @@ -1037,6 +1116,7 @@ impl fmt::Display for NodeStatus { NodeStatus::Starting => write!(f, "Starting"), NodeStatus::Stopped => write!(f, "Stopped"), NodeStatus::Removed => write!(f, "Removed"), + NodeStatus::Updating => write!(f, "Updating"), } } } @@ -1100,6 +1180,18 @@ impl NodeItem<'_> { .throbber_set(throbber_widgets_tui::BRAILLE_SIX_DOUBLE) .use_type(throbber_widgets_tui::WhichUse::Full); } + NodeStatus::Updating => { + self.spinner = self + .spinner + .clone() + .throbber_style( + Style::default() + .fg(GHOST_WHITE) + .add_modifier(Modifier::BOLD), + ) + .throbber_set(throbber_widgets_tui::VERTICAL_BLOCK) + .use_type(throbber_widgets_tui::WhichUse::Full); + } _ => {} }; diff --git a/node-launchpad/src/mode.rs b/node-launchpad/src/mode.rs index b6cc6c4a40..a74047e7dc 100644 --- a/node-launchpad/src/mode.rs +++ b/node-launchpad/src/mode.rs @@ -25,6 +25,7 @@ pub enum Scene { OptionsRewardsAddressPopUp, ManageNodesPopUp, ResetNodesPopUp, + UpgradeNodesPopUp, } #[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/node-launchpad/src/node_mgmt.rs b/node-launchpad/src/node_mgmt.rs index 5b7c2ae769..5875997190 100644 --- a/node-launchpad/src/node_mgmt.rs +++ b/node-launchpad/src/node_mgmt.rs @@ -128,8 +128,62 @@ pub fn reset_nodes(action_sender: UnboundedSender, start_nodes_after_res }); } +pub struct UpgradeNodesArgs { + pub action_sender: UnboundedSender, + pub connection_timeout_s: u64, + pub do_not_start: bool, + pub custom_bin_path: Option, + pub force: bool, + pub fixed_interval: Option, + pub peer_ids: Vec, + pub provided_env_variables: Option>, + pub service_names: Vec, + pub url: Option, + pub version: Option, +} + +pub fn upgrade_nodes(args: UpgradeNodesArgs) { + tokio::task::spawn_local(async move { + if let Err(err) = sn_node_manager::cmd::node::upgrade( + args.connection_timeout_s, + args.do_not_start, + args.custom_bin_path, + args.force, + args.fixed_interval, + args.peer_ids, + args.provided_env_variables, + args.service_names, + args.url, + args.version, + VerbosityLevel::Minimal, + ) + .await + { + error!("Error while updating services {err:?}"); + send_action( + args.action_sender, + Action::StatusActions(StatusActions::ErrorUpdatingNodes { + raw_error: err.to_string(), + }), + ); + } else { + info!("Successfully updated services"); + send_action( + args.action_sender, + Action::StatusActions(StatusActions::UpdateNodesCompleted), + ); + } + }); +} + // --- Helper functions --- +fn send_action(action_sender: UnboundedSender, action: Action) { + if let Err(err) = action_sender.send(action) { + error!("Error while sending action: {err:?}"); + } +} + /// Load the node registry and handle errors async fn load_node_registry( action_sender: &UnboundedSender, diff --git a/sn_node_manager/src/cmd/mod.rs b/sn_node_manager/src/cmd/mod.rs index 9e6af9351d..fa8ec6be78 100644 --- a/sn_node_manager/src/cmd/mod.rs +++ b/sn_node_manager/src/cmd/mod.rs @@ -73,10 +73,14 @@ pub async fn download_and_get_upgrade_bin_path( .await?; Ok((upgrade_bin_path, Version::parse(&version)?)) } else { - println!("Retrieving latest version of {release_type}..."); + if verbosity != VerbosityLevel::Minimal { + println!("Retrieving latest version of {release_type}..."); + } debug!("Retrieving latest version of {release_type}..."); let latest_version = release_repo.get_latest_version(&release_type).await?; - println!("Latest version is {latest_version}"); + if verbosity != VerbosityLevel::Minimal { + println!("Latest version is {latest_version}"); + } debug!("Download latest version {latest_version} of {release_type}"); let (upgrade_bin_path, _) = download_and_extract_release( diff --git a/sn_node_manager/src/cmd/node.rs b/sn_node_manager/src/cmd/node.rs index 454295e514..049a1d2337 100644 --- a/sn_node_manager/src/cmd/node.rs +++ b/sn_node_manager/src/cmd/node.rs @@ -593,7 +593,9 @@ pub async fn upgrade( } } - print_upgrade_summary(upgrade_summary.clone()); + if verbosity != VerbosityLevel::Minimal { + print_upgrade_summary(upgrade_summary.clone()); + } if upgrade_summary.iter().any(|(_, r)| { matches!(r, UpgradeResult::Error(_))