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,48 @@ 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 ! (
291+ f,
292+ "{}\n " ,
293+ selection. display( indent + 2 )
294+ ) ?;
295+ }
296+ }
297+ }
298+ }
299+
237300 writeln ! ( f) ?;
238301
239302 Ok ( ( ) )
@@ -244,11 +307,17 @@ impl fmt::Display for DisplayCase<'_> {
244307mod tests {
245308 use super :: * ;
246309 use crate :: fm:: DiagnosisEngineKind ;
310+ use crate :: fm:: ereport:: EreportFilters ;
247311 use crate :: inventory:: SpType ;
312+ use crate :: support_bundle:: {
313+ BundleData , BundleDataSelection , SledSelection ,
314+ } ;
248315 use ereport_types:: { Ena , EreportId } ;
249316 use omicron_uuid_kinds:: {
250317 AlertUuid , CaseUuid , EreporterRestartUuid , OmicronZoneUuid , SitrepUuid ,
318+ SupportBundleUuid ,
251319 } ;
320+ use std:: collections:: HashSet ;
252321 use std:: str:: FromStr ;
253322 use std:: sync:: Arc ;
254323
@@ -276,6 +345,12 @@ mod tests {
276345 let alert2_id =
277346 AlertUuid :: from_str ( "8a6f88ef-c436-44a9-b4cb-cae91d7306c9" )
278347 . unwrap ( ) ;
348+ let bundle1_id =
349+ SupportBundleUuid :: from_str ( "d1a2b3c4-e5f6-7890-abcd-ef1234567890" )
350+ . unwrap ( ) ;
351+ let bundle2_id =
352+ SupportBundleUuid :: from_str ( "a9b8c7d6-e5f4-3210-fedc-ba0987654321" )
353+ . unwrap ( ) ;
279354
280355 // Create some ereports
281356 let mut ereports = IdOrdMap :: new ( ) ;
@@ -349,6 +424,32 @@ mod tests {
349424 } )
350425 . unwrap ( ) ;
351426
427+ let mut bundle1_data = BundleDataSelection :: new ( ) ;
428+ bundle1_data. insert ( BundleData :: Reconfigurator ) ;
429+ bundle1_data. insert ( BundleData :: SpDumps ) ;
430+ bundle1_data
431+ . insert ( BundleData :: HostInfo ( HashSet :: from ( [ SledSelection :: All ] ) ) ) ;
432+ bundle1_data. insert ( BundleData :: Ereports ( EreportFilters {
433+ only_classes : vec ! [ "hw.pwr.*" . to_string( ) ] ,
434+ ..Default :: default ( )
435+ } ) ) ;
436+
437+ let mut support_bundles_requested = IdOrdMap :: new ( ) ;
438+ support_bundles_requested
439+ . insert_unique ( SupportBundleRequest {
440+ id : bundle1_id,
441+ requested_sitrep_id : created_sitrep_id,
442+ data_selection : Some ( bundle1_data) ,
443+ } )
444+ . unwrap ( ) ;
445+ support_bundles_requested
446+ . insert_unique ( SupportBundleRequest {
447+ id : bundle2_id,
448+ requested_sitrep_id : closed_sitrep_id,
449+ data_selection : None ,
450+ } )
451+ . unwrap ( ) ;
452+
352453 // Create the case
353454 let case = Case {
354455 id : case_id,
@@ -357,6 +458,7 @@ mod tests {
357458 de : DiagnosisEngineKind :: PowerShelf ,
358459 ereports,
359460 alerts_requested,
461+ support_bundles_requested,
360462 comment : "Power shelf rectifier added and removed here :-)"
361463 . to_string ( ) ,
362464 } ;
0 commit comments