55use crate :: alert:: AlertClass ;
66use crate :: fm:: DiagnosisEngineKind ;
77use crate :: fm:: Ereport ;
8+ use crate :: support_bundle:: BundleDataSelection ;
89use iddqd:: { IdOrdItem , IdOrdMap } ;
9- use omicron_uuid_kinds:: { AlertUuid , CaseEreportUuid , CaseUuid , SitrepUuid } ;
10+ use omicron_uuid_kinds:: {
11+ AlertUuid , CaseEreportUuid , CaseUuid , SitrepUuid , SupportBundleUuid ,
12+ } ;
1013use serde:: { Deserialize , Serialize } ;
1114use std:: fmt;
1215use std:: sync:: Arc ;
@@ -21,6 +24,7 @@ pub struct Case {
2124
2225 pub ereports : IdOrdMap < CaseEreport > ,
2326 pub alerts_requested : IdOrdMap < AlertRequest > ,
27+ pub support_bundles_requested : IdOrdMap < SupportBundleRequest > ,
2428
2529 pub comment : String ,
2630}
@@ -88,6 +92,22 @@ impl iddqd::IdOrdItem for AlertRequest {
8892 iddqd:: id_upcast!( ) ;
8993}
9094
95+ #[ derive( Clone , Debug , Serialize , Deserialize , PartialEq , Eq ) ]
96+ pub struct SupportBundleRequest {
97+ pub id : SupportBundleUuid ,
98+ pub requested_sitrep_id : SitrepUuid ,
99+ pub data_selection : Option < BundleDataSelection > ,
100+ }
101+
102+ impl iddqd:: IdOrdItem for SupportBundleRequest {
103+ type Key < ' a > = & ' a SupportBundleUuid ;
104+ fn key ( & self ) -> Self :: Key < ' _ > {
105+ & self . id
106+ }
107+
108+ iddqd:: id_upcast!( ) ;
109+ }
110+
91111struct DisplayCase < ' a > {
92112 case : & ' a Case ,
93113 indent : usize ,
@@ -120,6 +140,7 @@ impl fmt::Display for DisplayCase<'_> {
120140 ereports,
121141 comment,
122142 alerts_requested,
143+ support_bundles_requested,
123144 } ,
124145 indent,
125146 sitrep_id,
@@ -234,6 +255,44 @@ impl fmt::Display for DisplayCase<'_> {
234255 }
235256 }
236257
258+ if !support_bundles_requested. is_empty ( ) {
259+ writeln ! ( f, "\n {:>indent$}support bundles requested:" , "" ) ?;
260+ writeln ! ( f, "{:>indent$}-------------------------" , "" ) ?;
261+
262+ let indent = indent + 2 ;
263+ for SupportBundleRequest {
264+ id,
265+ requested_sitrep_id,
266+ data_selection,
267+ } in support_bundles_requested. iter ( )
268+ {
269+ const REQUESTED_IN : & str = "requested in:" ;
270+ const DATA : & str = "data:" ;
271+ const WIDTH : usize = const_max_len ( & [ REQUESTED_IN , DATA ] ) ;
272+
273+ writeln ! ( f, "{BULLET:>indent$}bundle {id}" , ) ?;
274+ writeln ! (
275+ f,
276+ "{:>indent$}{REQUESTED_IN:<WIDTH$} {requested_sitrep_id}{}" ,
277+ "" ,
278+ this_sitrep( * requested_sitrep_id)
279+ ) ?;
280+ match data_selection {
281+ None => {
282+ writeln ! (
283+ f,
284+ "{:>indent$}{DATA:<WIDTH$} all (default)\n " ,
285+ "" ,
286+ ) ?;
287+ }
288+ Some ( selection) => {
289+ writeln ! ( f, "{:>indent$}{DATA}" , "" ) ?;
290+ writeln ! ( f, "{}\n " , selection. display( indent + 2 ) ) ?;
291+ }
292+ }
293+ }
294+ }
295+
237296 writeln ! ( f) ?;
238297
239298 Ok ( ( ) )
@@ -244,11 +303,17 @@ impl fmt::Display for DisplayCase<'_> {
244303mod tests {
245304 use super :: * ;
246305 use crate :: fm:: DiagnosisEngineKind ;
306+ use crate :: fm:: ereport:: EreportFilters ;
247307 use crate :: inventory:: SpType ;
308+ use crate :: support_bundle:: {
309+ BundleData , BundleDataSelection , SledSelection ,
310+ } ;
248311 use ereport_types:: { Ena , EreportId } ;
249312 use omicron_uuid_kinds:: {
250313 AlertUuid , CaseUuid , EreporterRestartUuid , OmicronZoneUuid , SitrepUuid ,
314+ SupportBundleUuid ,
251315 } ;
316+ use std:: collections:: HashSet ;
252317 use std:: str:: FromStr ;
253318 use std:: sync:: Arc ;
254319
@@ -276,6 +341,12 @@ mod tests {
276341 let alert2_id =
277342 AlertUuid :: from_str ( "8a6f88ef-c436-44a9-b4cb-cae91d7306c9" )
278343 . unwrap ( ) ;
344+ let bundle1_id =
345+ SupportBundleUuid :: from_str ( "d1a2b3c4-e5f6-7890-abcd-ef1234567890" )
346+ . unwrap ( ) ;
347+ let bundle2_id =
348+ SupportBundleUuid :: from_str ( "a9b8c7d6-e5f4-3210-fedc-ba0987654321" )
349+ . unwrap ( ) ;
279350
280351 // Create some ereports
281352 let mut ereports = IdOrdMap :: new ( ) ;
@@ -349,6 +420,32 @@ mod tests {
349420 } )
350421 . unwrap ( ) ;
351422
423+ let mut bundle1_data = BundleDataSelection :: new ( ) ;
424+ bundle1_data. insert ( BundleData :: Reconfigurator ) ;
425+ bundle1_data. insert ( BundleData :: SpDumps ) ;
426+ bundle1_data
427+ . insert ( BundleData :: HostInfo ( HashSet :: from ( [ SledSelection :: All ] ) ) ) ;
428+ bundle1_data. insert ( BundleData :: Ereports ( EreportFilters {
429+ only_classes : vec ! [ "hw.pwr.*" . to_string( ) ] ,
430+ ..Default :: default ( )
431+ } ) ) ;
432+
433+ let mut support_bundles_requested = IdOrdMap :: new ( ) ;
434+ support_bundles_requested
435+ . insert_unique ( SupportBundleRequest {
436+ id : bundle1_id,
437+ requested_sitrep_id : created_sitrep_id,
438+ data_selection : Some ( bundle1_data) ,
439+ } )
440+ . unwrap ( ) ;
441+ support_bundles_requested
442+ . insert_unique ( SupportBundleRequest {
443+ id : bundle2_id,
444+ requested_sitrep_id : closed_sitrep_id,
445+ data_selection : None ,
446+ } )
447+ . unwrap ( ) ;
448+
352449 // Create the case
353450 let case = Case {
354451 id : case_id,
@@ -357,6 +454,7 @@ mod tests {
357454 de : DiagnosisEngineKind :: PowerShelf ,
358455 ereports,
359456 alerts_requested,
457+ support_bundles_requested,
360458 comment : "Power shelf rectifier added and removed here :-)"
361459 . to_string ( ) ,
362460 } ;
0 commit comments