@@ -26,6 +26,7 @@ use nexus_sled_agent_shared::inventory::{
2626use omicron_uuid_kinds:: {
2727 DatasetUuid , OmicronZoneUuid , PhysicalDiskUuid , ZpoolUuid ,
2828} ;
29+ use std:: collections:: HashMap ;
2930use strum:: IntoEnumIterator ;
3031use tabled:: Tabled ;
3132use tufaceous_artifact:: ArtifactHash ;
@@ -43,6 +44,7 @@ pub struct CollectionDisplay<'a> {
4344 include_sleds : bool ,
4445 include_orphaned_datasets : bool ,
4546 include_clickhouse_keeper_membership : bool ,
47+ include_cockroach_status : bool ,
4648 long_string_formatter : LongStringFormatter ,
4749}
4850
@@ -55,6 +57,7 @@ impl<'a> CollectionDisplay<'a> {
5557 include_sleds : true ,
5658 include_orphaned_datasets : true ,
5759 include_clickhouse_keeper_membership : true ,
60+ include_cockroach_status : true ,
5861 long_string_formatter : LongStringFormatter :: new ( ) ,
5962 }
6063 }
@@ -95,6 +98,15 @@ impl<'a> CollectionDisplay<'a> {
9598 self
9699 }
97100
101+ /// Control display of Cockroach cluster information (defaults to true).
102+ pub fn include_cockroach_status (
103+ & mut self ,
104+ include_cockroach_status : bool ,
105+ ) -> & mut Self {
106+ self . include_cockroach_status = include_cockroach_status;
107+ self
108+ }
109+
98110 /// Show long strings (defaults to false).
99111 pub fn show_long_strings ( & mut self , show_long_strings : bool ) -> & mut Self {
100112 self . long_string_formatter . show_long_strings = show_long_strings;
@@ -112,6 +124,7 @@ impl<'a> CollectionDisplay<'a> {
112124 . include_clickhouse_keeper_membership (
113125 filter. include_keeper_membership ( ) ,
114126 )
127+ . include_cockroach_status ( filter. include_cockroach_status ( ) )
115128 }
116129}
117130
@@ -135,6 +148,9 @@ impl fmt::Display for CollectionDisplay<'_> {
135148 if self . include_clickhouse_keeper_membership {
136149 display_keeper_membership ( & self . collection , f) ?;
137150 }
151+ if self . include_cockroach_status {
152+ display_cockroach_status ( & self . collection , f) ?;
153+ }
138154
139155 if nerrors > 0 {
140156 writeln ! (
@@ -200,6 +216,14 @@ impl CollectionDisplayCliFilter {
200216 Self :: OrphanedDatasets => false ,
201217 }
202218 }
219+
220+ fn include_cockroach_status ( & self ) -> bool {
221+ match self {
222+ Self :: All => true ,
223+ Self :: Sp { .. } => false ,
224+ Self :: OrphanedDatasets => false ,
225+ }
226+ }
203227}
204228
205229/// Which SPs within a collection to display.
@@ -1024,6 +1048,53 @@ fn display_keeper_membership(
10241048 Ok ( ( ) )
10251049}
10261050
1051+ fn display_cockroach_status (
1052+ collection : & Collection ,
1053+ f : & mut dyn fmt:: Write ,
1054+ ) -> fmt:: Result {
1055+ writeln ! ( f, "\n COCKROACH STATUS" ) ?;
1056+
1057+ // Under normal conditions, cockroach nodes will report the same data. For
1058+ // brevity, we will map "status" -> "nodes reporting that status", to avoid
1059+ // emitting the same information repeatedly for each node.
1060+ let mut status_to_node: HashMap < _ , Vec < _ > > = HashMap :: new ( ) ;
1061+
1062+ for ( node, status) in & collection. cockroach_status {
1063+ status_to_node. entry ( status) . or_default ( ) . push ( node) ;
1064+ }
1065+
1066+ for ( status, nodes) in & status_to_node {
1067+ writeln ! (
1068+ f,
1069+ "\n status from nodes: {}" ,
1070+ nodes. iter( ) . map( |n| n. to_string( ) ) . join( ", " )
1071+ ) ?;
1072+
1073+ writeln ! (
1074+ f,
1075+ "\n ranges underreplicated: {}" ,
1076+ status
1077+ . ranges_underreplicated
1078+ . map( |r| r. to_string( ) )
1079+ . unwrap_or_else( || "<cOULD NOT BE PARSED>" . to_string( ) )
1080+ ) ?;
1081+ writeln ! (
1082+ f,
1083+ "\n live nodes: {}" ,
1084+ status
1085+ . liveness_live_nodes
1086+ . map( |r| r. to_string( ) )
1087+ . unwrap_or_else( || "<COULD NOT BE PARSED>" . to_string( ) )
1088+ ) ?;
1089+ }
1090+ if status_to_node. is_empty ( ) {
1091+ writeln ! ( f, " no cockroach status retrieved" ) ?;
1092+ }
1093+ writeln ! ( f) ?;
1094+
1095+ Ok ( ( ) )
1096+ }
1097+
10271098#[ derive( Debug ) ]
10281099struct LongStringFormatter {
10291100 show_long_strings : bool ,
0 commit comments