@@ -125,6 +125,10 @@ use nexus_db_queries::db::pagination::Paginator;
125
125
use nexus_db_queries:: db:: pagination:: paginated;
126
126
use nexus_db_queries:: db:: queries:: ALLOW_FULL_TABLE_SCAN_SQL ;
127
127
use nexus_db_queries:: db:: queries:: region_allocation;
128
+ use nexus_sled_agent_shared:: inventory:: BootImageHeader ;
129
+ use nexus_sled_agent_shared:: inventory:: BootPartitionContents ;
130
+ use nexus_sled_agent_shared:: inventory:: BootPartitionDetails ;
131
+ use nexus_sled_agent_shared:: inventory:: ConfigReconcilerInventory ;
128
132
use nexus_sled_agent_shared:: inventory:: ConfigReconcilerInventoryResult ;
129
133
use nexus_sled_agent_shared:: inventory:: ConfigReconcilerInventoryStatus ;
130
134
use nexus_sled_agent_shared:: inventory:: OmicronSledConfig ;
@@ -178,6 +182,7 @@ use std::sync::Arc;
178
182
use std:: sync:: LazyLock ;
179
183
use strum:: IntoEnumIterator ;
180
184
use tabled:: Tabled ;
185
+ use tufaceous_artifact:: ArtifactHash ;
181
186
use uuid:: Uuid ;
182
187
183
188
mod alert;
@@ -7361,34 +7366,41 @@ fn inv_collection_print_sleds(collection: &Collection) {
7361
7366
}
7362
7367
7363
7368
if let Some ( last_reconciliation) = & sled. last_reconciliation {
7364
- if Some ( & last_reconciliation. last_reconciled_config )
7369
+ let ConfigReconcilerInventory {
7370
+ last_reconciled_config,
7371
+ external_disks,
7372
+ datasets,
7373
+ orphaned_datasets,
7374
+ zones,
7375
+ boot_partitions,
7376
+ } = last_reconciliation;
7377
+
7378
+ inv_print_boot_partition_contents ( " " , boot_partitions) ;
7379
+
7380
+ if Some ( last_reconciled_config)
7365
7381
== sled. ledgered_sled_config . as_ref ( )
7366
7382
{
7367
7383
println ! ( " last reconciled config: matches ledgered config" ) ;
7368
7384
} else {
7369
7385
inv_collection_print_sled_config (
7370
7386
"LAST RECONCILED CONFIG" ,
7371
- & last_reconciliation . last_reconciled_config ,
7387
+ & last_reconciled_config,
7372
7388
) ;
7373
7389
}
7374
- if last_reconciliation . orphaned_datasets . is_empty ( ) {
7390
+ if orphaned_datasets. is_empty ( ) {
7375
7391
println ! ( " no orphaned datasets" ) ;
7376
7392
} else {
7377
7393
println ! (
7378
7394
" {} orphaned dataset(s):" ,
7379
- last_reconciliation . orphaned_datasets. len( )
7395
+ orphaned_datasets. len( )
7380
7396
) ;
7381
- for orphan in & last_reconciliation . orphaned_datasets {
7397
+ for orphan in orphaned_datasets {
7382
7398
print_one_orphaned_dataset ( " " , orphan) ;
7383
7399
}
7384
7400
}
7385
- let disk_errs = collect_config_reconciler_errors (
7386
- & last_reconciliation. external_disks ,
7387
- ) ;
7388
- let dataset_errs =
7389
- collect_config_reconciler_errors ( & last_reconciliation. datasets ) ;
7390
- let zone_errs =
7391
- collect_config_reconciler_errors ( & last_reconciliation. zones ) ;
7401
+ let disk_errs = collect_config_reconciler_errors ( & external_disks) ;
7402
+ let dataset_errs = collect_config_reconciler_errors ( & datasets) ;
7403
+ let zone_errs = collect_config_reconciler_errors ( & zones) ;
7392
7404
for ( label, errs) in [
7393
7405
( "disk" , disk_errs) ,
7394
7406
( "dataset" , dataset_errs) ,
@@ -7438,6 +7450,57 @@ fn inv_collection_print_sleds(collection: &Collection) {
7438
7450
}
7439
7451
}
7440
7452
7453
+ fn inv_print_boot_partition_contents (
7454
+ indent : & str ,
7455
+ boot_partitions : & BootPartitionContents ,
7456
+ ) {
7457
+ let BootPartitionContents { boot_disk, slot_a, slot_b } = & boot_partitions;
7458
+ print ! ( "{indent}boot disk slot: " ) ;
7459
+ match boot_disk {
7460
+ Ok ( slot) => println ! ( "{slot:?}" ) ,
7461
+ Err ( err) => println ! ( "FAILED TO DETERMINE: {err}" ) ,
7462
+ }
7463
+ match slot_a {
7464
+ Ok ( details) => {
7465
+ println ! ( "{indent}slot A details:" ) ;
7466
+ inv_print_boot_partition_details ( & format ! ( "{indent} " ) , details) ;
7467
+ }
7468
+ Err ( err) => {
7469
+ println ! ( "{indent}slot A details UNAVAILABLE: {err}" ) ;
7470
+ }
7471
+ }
7472
+ match slot_b {
7473
+ Ok ( details) => {
7474
+ println ! ( "{indent}slot B details:" ) ;
7475
+ inv_print_boot_partition_details ( & format ! ( "{indent} " ) , details) ;
7476
+ }
7477
+ Err ( err) => {
7478
+ println ! ( "{indent}slot B details UNAVAILABLE: {err}" ) ;
7479
+ }
7480
+ }
7481
+ }
7482
+
7483
+ fn inv_print_boot_partition_details (
7484
+ indent : & str ,
7485
+ details : & BootPartitionDetails ,
7486
+ ) {
7487
+ let BootPartitionDetails { header, artifact_hash, artifact_size } = details;
7488
+
7489
+ // Not sure it's useful to print all the header details? We'll omit for now.
7490
+ let BootImageHeader {
7491
+ flags : _,
7492
+ data_size : _,
7493
+ image_size : _,
7494
+ target_size : _,
7495
+ sha256,
7496
+ image_name,
7497
+ } = header;
7498
+
7499
+ println ! ( "{indent}artifact: {artifact_hash} ({artifact_size} bytes)" ) ;
7500
+ println ! ( "{indent}image name: {image_name}" ) ;
7501
+ println ! ( "{indent}phase 2 hash: {}" , ArtifactHash ( * sha256) ) ;
7502
+ }
7503
+
7441
7504
fn inv_collection_print_orphaned_datasets ( collection : & Collection ) {
7442
7505
// Helper for `unwrap_or()` passing borrow check below
7443
7506
static EMPTY_SET : LazyLock < IdOrdMap < OrphanedDataset > > =
0 commit comments