From 605f52dee0a90770cd576efef017500309ba7684 Mon Sep 17 00:00:00 2001 From: "Andrew J. Stone" Date: Thu, 26 Jun 2025 22:17:46 +0000 Subject: [PATCH 1/3] Add reconfigurator chicken-switch-history to omdb --- dev-tools/omdb/src/bin/omdb/reconfigurator.rs | 74 +++++++++++++++++++ .../reconfigurator_chicken_switches.rs | 1 + 2 files changed, 75 insertions(+) diff --git a/dev-tools/omdb/src/bin/omdb/reconfigurator.rs b/dev-tools/omdb/src/bin/omdb/reconfigurator.rs index 89e43bcde0..7c293ede41 100644 --- a/dev-tools/omdb/src/bin/omdb/reconfigurator.rs +++ b/dev-tools/omdb/src/bin/omdb/reconfigurator.rs @@ -16,6 +16,7 @@ use diesel::ExpressionMethods; use diesel::QueryDsl; use diesel::SelectableHelper; use nexus_db_model::BpTarget; +use nexus_db_model::SqlU32; use nexus_db_queries::authz; use nexus_db_queries::context::OpContext; use nexus_db_queries::db::DataStore; @@ -23,6 +24,7 @@ use nexus_db_queries::db::datastore::SQL_BATCH_SIZE; use nexus_db_queries::db::pagination::Paginator; use nexus_types::deployment::Blueprint; use nexus_types::deployment::BlueprintMetadata; +use nexus_types::deployment::ReconfiguratorChickenSwitches; use nexus_types::deployment::UnstableReconfiguratorState; use omicron_common::api::external::Error; use omicron_common::api::external::LookupType; @@ -30,6 +32,8 @@ use omicron_uuid_kinds::BlueprintUuid; use omicron_uuid_kinds::GenericUuid; use slog::Logger; use std::collections::BTreeMap; +use std::num::NonZeroU32; +use tabled::Tabled; /// Arguments to the "omdb reconfigurator" subcommand #[derive(Debug, Args)] @@ -53,6 +57,8 @@ enum ReconfiguratorCommands { Archive(ExportArgs), /// Show recent history of blueprints History(HistoryArgs), + /// Show the recent history of chicken switch settings + ChickenSwitchesHistory(ChickenSwitchesHistoryArgs), } #[derive(Debug, Args, Clone)] @@ -61,6 +67,13 @@ struct ExportArgs { output_file: Utf8PathBuf, } +#[derive(Debug, Args, Clone)] +struct ChickenSwitchesHistoryArgs { + /// how far back in the history to show (number of targets) + #[clap(long, default_value_t = 128)] + limit: u32, +} + #[derive(Debug, Args, Clone)] struct HistoryArgs { /// how far back in the history to show (number of targets) @@ -111,6 +124,12 @@ impl ReconfiguratorArgs { ) .await } + ReconfiguratorCommands::ChickenSwitchesHistory(args) => { + cmd_reconfigurator_chicken_switches_history( + &opctx, &datastore, args, + ) + .await + } }, ) .await @@ -352,6 +371,61 @@ async fn cmd_reconfigurator_history( Ok(()) } +/// Show recent history of chicken switches +async fn cmd_reconfigurator_chicken_switches_history( + opctx: &OpContext, + datastore: &DataStore, + history_args: &ChickenSwitchesHistoryArgs, +) -> anyhow::Result<()> { + let mut history = vec![]; + let limit = history_args.limit; + let batch_size = NonZeroU32::min(limit.try_into().unwrap(), SQL_BATCH_SIZE); + let mut paginator = Paginator::::new(batch_size); + while let Some(p) = paginator.next() { + if history.len() >= limit as usize { + break; + } + let batch = datastore + .reconfigurator_chicken_switches_list(opctx, &p.current_pagparams()) + .await + .context("batch of chicken switches")?; + paginator = p.found_batch(&batch, &|b| SqlU32::new(b.version)); + history.extend(batch.into_iter()); + } + + #[derive(Tabled)] + #[tabled(rename_all = "SCREAMING_SNAKE_CASE")] + struct SwitchesRow { + version: String, + planner_enabled: String, + time_modified: String, + } + + let rows: Vec<_> = history + .into_iter() + .map(|s| { + let ReconfiguratorChickenSwitches { + version, + planner_enabled, + time_modified, + } = s; + SwitchesRow { + version: version.to_string(), + planner_enabled: planner_enabled.to_string(), + time_modified: time_modified.to_string(), + } + }) + .collect(); + + let table = tabled::Table::new(rows) + .with(tabled::settings::Style::empty()) + .with(tabled::settings::Padding::new(0, 1, 0, 0)) + .to_string(); + + println!("{}", table); + + Ok(()) +} async fn blueprint_load( opctx: &OpContext, diff --git a/nexus/db-queries/src/db/datastore/reconfigurator_chicken_switches.rs b/nexus/db-queries/src/db/datastore/reconfigurator_chicken_switches.rs index d7ac528dd7..dc4f12e529 100644 --- a/nexus/db-queries/src/db/datastore/reconfigurator_chicken_switches.rs +++ b/nexus/db-queries/src/db/datastore/reconfigurator_chicken_switches.rs @@ -42,6 +42,7 @@ impl DataStore { reconfigurator_chicken_switches::version, pagparams, ) + .order_by(reconfigurator_chicken_switches::dsl::version.desc()) .select(DbReconfiguratorChickenSwitches::as_select()) .get_results_async(&*self.pool_connection_authorized(opctx).await?) .await From 72a659136efe70aab348ba2bafafbec8f2269e66 Mon Sep 17 00:00:00 2001 From: "Andrew J. Stone" Date: Tue, 1 Jul 2025 22:46:50 +0000 Subject: [PATCH 2/3] Make pagination descending --- dev-tools/omdb/src/bin/omdb/reconfigurator.rs | 5 ++++- .../src/db/datastore/reconfigurator_chicken_switches.rs | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dev-tools/omdb/src/bin/omdb/reconfigurator.rs b/dev-tools/omdb/src/bin/omdb/reconfigurator.rs index 7c293ede41..f3a254e588 100644 --- a/dev-tools/omdb/src/bin/omdb/reconfigurator.rs +++ b/dev-tools/omdb/src/bin/omdb/reconfigurator.rs @@ -380,7 +380,10 @@ async fn cmd_reconfigurator_chicken_switches_history( let mut history = vec![]; let limit = history_args.limit; let batch_size = NonZeroU32::min(limit.try_into().unwrap(), SQL_BATCH_SIZE); - let mut paginator = Paginator::::new(batch_size); + let mut paginator = Paginator::::new( + batch_size, + dropshot::PaginationOrder::Descending, + ); while let Some(p) = paginator.next() { if history.len() >= limit as usize { break; diff --git a/nexus/db-queries/src/db/datastore/reconfigurator_chicken_switches.rs b/nexus/db-queries/src/db/datastore/reconfigurator_chicken_switches.rs index dc4f12e529..d7ac528dd7 100644 --- a/nexus/db-queries/src/db/datastore/reconfigurator_chicken_switches.rs +++ b/nexus/db-queries/src/db/datastore/reconfigurator_chicken_switches.rs @@ -42,7 +42,6 @@ impl DataStore { reconfigurator_chicken_switches::version, pagparams, ) - .order_by(reconfigurator_chicken_switches::dsl::version.desc()) .select(DbReconfiguratorChickenSwitches::as_select()) .get_results_async(&*self.pool_connection_authorized(opctx).await?) .await From 02f2842daa8af15f3439af289824fc784b8d4e11 Mon Sep 17 00:00:00 2001 From: "Andrew J. Stone" Date: Wed, 2 Jul 2025 17:35:11 +0000 Subject: [PATCH 3/3] expectorate --- dev-tools/omdb/tests/usage_errors.out | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dev-tools/omdb/tests/usage_errors.out b/dev-tools/omdb/tests/usage_errors.out index 10ec70f1e4..e057f99ac1 100644 --- a/dev-tools/omdb/tests/usage_errors.out +++ b/dev-tools/omdb/tests/usage_errors.out @@ -1176,11 +1176,12 @@ Interact with the Reconfigurator system Usage: omdb reconfigurator [OPTIONS] Commands: - export Save the current Reconfigurator state to a file - archive Save the current Reconfigurator state to a file and remove historical artifacts from the - live system (e.g., non-target blueprints) - history Show recent history of blueprints - help Print this message or the help of the given subcommand(s) + export Save the current Reconfigurator state to a file + archive Save the current Reconfigurator state to a file and remove historical + artifacts from the live system (e.g., non-target blueprints) + history Show recent history of blueprints + chicken-switches-history Show the recent history of chicken switch settings + help Print this message or the help of the given subcommand(s) Options: --log-level log level filter [env: LOG_LEVEL=] [default: warn]