@@ -325,7 +325,7 @@ pub(crate) async fn status(opts: super::cli::StatusOpts) -> Result<()> {
325
325
. to_canon_json_writer ( & mut out)
326
326
. map_err ( anyhow:: Error :: new) ,
327
327
OutputFormat :: Yaml => serde_yaml:: to_writer ( & mut out, & host) . map_err ( anyhow:: Error :: new) ,
328
- OutputFormat :: HumanReadable => human_readable_output ( & mut out, & host) ,
328
+ OutputFormat :: HumanReadable => human_readable_output ( & mut out, & host, opts . verbose ) ,
329
329
}
330
330
. context ( "Writing to stdout" ) ?;
331
331
@@ -359,12 +359,35 @@ fn write_row_name(mut out: impl Write, s: &str, prefix_len: usize) -> Result<()>
359
359
Ok ( ( ) )
360
360
}
361
361
362
+ /// Helper function to render verbose ostree information
363
+ fn render_verbose_ostree_info (
364
+ mut out : impl Write ,
365
+ ostree : & crate :: spec:: BootEntryOstree ,
366
+ slot : Option < Slot > ,
367
+ prefix_len : usize ,
368
+ ) -> Result < ( ) > {
369
+ write_row_name ( & mut out, "StateRoot" , prefix_len) ?;
370
+ writeln ! ( out, "{}" , ostree. stateroot) ?;
371
+
372
+ // Show deployment serial (similar to Index in rpm-ostree)
373
+ write_row_name ( & mut out, "Deploy serial" , prefix_len) ?;
374
+ writeln ! ( out, "{}" , ostree. deploy_serial) ?;
375
+
376
+ // Show if this is staged
377
+ let is_staged = matches ! ( slot, Some ( Slot :: Staged ) ) ;
378
+ write_row_name ( & mut out, "Staged" , prefix_len) ?;
379
+ writeln ! ( out, "{}" , if is_staged { "yes" } else { "no" } ) ?;
380
+
381
+ Ok ( ( ) )
382
+ }
383
+
362
384
/// Write the data for a container image based status.
363
385
fn human_render_slot (
364
386
mut out : impl Write ,
365
387
slot : Option < Slot > ,
366
388
entry : & crate :: spec:: BootEntry ,
367
389
image : & crate :: spec:: ImageStatus ,
390
+ verbose : bool ,
368
391
) -> Result < ( ) > {
369
392
let transport = & image. image . transport ;
370
393
let imagename = & image. image . image ;
@@ -415,6 +438,33 @@ fn human_render_slot(
415
438
writeln ! ( out, "yes" ) ?;
416
439
}
417
440
441
+ if verbose {
442
+ // Show additional information in verbose mode similar to rpm-ostree
443
+ if let Some ( ostree) = & entry. ostree {
444
+ render_verbose_ostree_info ( & mut out, ostree, slot, prefix_len) ?;
445
+
446
+ // Show the commit (equivalent to Base Commit in rpm-ostree)
447
+ write_row_name ( & mut out, "Commit" , prefix_len) ?;
448
+ writeln ! ( out, "{}" , ostree. checksum) ?;
449
+ }
450
+
451
+ // Show signature information if available
452
+ if let Some ( signature) = & image. image . signature {
453
+ write_row_name ( & mut out, "Signature" , prefix_len) ?;
454
+ match signature {
455
+ crate :: spec:: ImageSignature :: OstreeRemote ( remote) => {
456
+ writeln ! ( out, "ostree-remote:{}" , remote) ?;
457
+ }
458
+ crate :: spec:: ImageSignature :: ContainerPolicy => {
459
+ writeln ! ( out, "container-policy" ) ?;
460
+ }
461
+ crate :: spec:: ImageSignature :: Insecure => {
462
+ writeln ! ( out, "insecure" ) ?;
463
+ }
464
+ }
465
+ }
466
+ }
467
+
418
468
tracing:: debug!( "pinned={}" , entry. pinned) ;
419
469
420
470
Ok ( ( ) )
@@ -426,6 +476,7 @@ fn human_render_slot_ostree(
426
476
slot : Option < Slot > ,
427
477
entry : & crate :: spec:: BootEntry ,
428
478
ostree_commit : & str ,
479
+ verbose : bool ,
429
480
) -> Result < ( ) > {
430
481
// TODO consider rendering more ostree stuff here like rpm-ostree status does
431
482
let prefix = match slot {
@@ -444,11 +495,18 @@ fn human_render_slot_ostree(
444
495
writeln ! ( out, "yes" ) ?;
445
496
}
446
497
498
+ if verbose {
499
+ // Show additional information in verbose mode similar to rpm-ostree
500
+ if let Some ( ostree) = & entry. ostree {
501
+ render_verbose_ostree_info ( & mut out, ostree, slot, prefix_len) ?;
502
+ }
503
+ }
504
+
447
505
tracing:: debug!( "pinned={}" , entry. pinned) ;
448
506
Ok ( ( ) )
449
507
}
450
508
451
- fn human_readable_output_booted ( mut out : impl Write , host : & Host ) -> Result < ( ) > {
509
+ fn human_readable_output_booted ( mut out : impl Write , host : & Host , verbose : bool ) -> Result < ( ) > {
452
510
let mut first = true ;
453
511
for ( slot_name, status) in [
454
512
( Slot :: Staged , & host. status . staged ) ,
@@ -462,9 +520,15 @@ fn human_readable_output_booted(mut out: impl Write, host: &Host) -> Result<()>
462
520
writeln ! ( out) ?;
463
521
}
464
522
if let Some ( image) = & host_status. image {
465
- human_render_slot ( & mut out, Some ( slot_name) , host_status, image) ?;
523
+ human_render_slot ( & mut out, Some ( slot_name) , host_status, image, verbose ) ?;
466
524
} else if let Some ( ostree) = host_status. ostree . as_ref ( ) {
467
- human_render_slot_ostree ( & mut out, Some ( slot_name) , host_status, & ostree. checksum ) ?;
525
+ human_render_slot_ostree (
526
+ & mut out,
527
+ Some ( slot_name) ,
528
+ host_status,
529
+ & ostree. checksum ,
530
+ verbose,
531
+ ) ?;
468
532
} else {
469
533
writeln ! ( out, "Current {slot_name} state is unknown" ) ?;
470
534
}
@@ -476,9 +540,9 @@ fn human_readable_output_booted(mut out: impl Write, host: &Host) -> Result<()>
476
540
writeln ! ( out) ?;
477
541
478
542
if let Some ( image) = & entry. image {
479
- human_render_slot ( & mut out, None , entry, image) ?;
543
+ human_render_slot ( & mut out, None , entry, image, verbose ) ?;
480
544
} else if let Some ( ostree) = entry. ostree . as_ref ( ) {
481
- human_render_slot_ostree ( & mut out, None , entry, & ostree. checksum ) ?;
545
+ human_render_slot_ostree ( & mut out, None , entry, & ostree. checksum , verbose ) ?;
482
546
}
483
547
}
484
548
}
@@ -487,9 +551,9 @@ fn human_readable_output_booted(mut out: impl Write, host: &Host) -> Result<()>
487
551
}
488
552
489
553
/// Implementation of rendering our host structure in a "human readable" way.
490
- fn human_readable_output ( mut out : impl Write , host : & Host ) -> Result < ( ) > {
554
+ fn human_readable_output ( mut out : impl Write , host : & Host , verbose : bool ) -> Result < ( ) > {
491
555
if host. status . booted . is_some ( ) {
492
- human_readable_output_booted ( out, host) ?;
556
+ human_readable_output_booted ( out, host, verbose ) ?;
493
557
} else {
494
558
writeln ! ( out, "System is not deployed via bootc." ) ?;
495
559
}
@@ -503,7 +567,17 @@ mod tests {
503
567
fn human_status_from_spec_fixture ( spec_fixture : & str ) -> Result < String > {
504
568
let host: Host = serde_yaml:: from_str ( spec_fixture) . unwrap ( ) ;
505
569
let mut w = Vec :: new ( ) ;
506
- human_readable_output ( & mut w, & host) . unwrap ( ) ;
570
+ human_readable_output ( & mut w, & host, false ) . unwrap ( ) ;
571
+ let w = String :: from_utf8 ( w) . unwrap ( ) ;
572
+ Ok ( w)
573
+ }
574
+
575
+ /// Helper function to generate human-readable status output with verbose mode enabled
576
+ /// from a YAML fixture string. Used for testing verbose output formatting.
577
+ fn human_status_from_spec_fixture_verbose ( spec_fixture : & str ) -> Result < String > {
578
+ let host: Host = serde_yaml:: from_str ( spec_fixture) . unwrap ( ) ;
579
+ let mut w = Vec :: new ( ) ;
580
+ human_readable_output ( & mut w, & host, true ) . unwrap ( ) ;
507
581
let w = String :: from_utf8 ( w) . unwrap ( ) ;
508
582
Ok ( w)
509
583
}
@@ -634,4 +708,18 @@ mod tests {
634
708
" } ;
635
709
similar_asserts:: assert_eq!( w, expected) ;
636
710
}
711
+
712
+ #[ test]
713
+ fn test_human_readable_verbose_spec ( ) {
714
+ // Test verbose output includes additional fields
715
+ let w =
716
+ human_status_from_spec_fixture_verbose ( include_str ! ( "fixtures/spec-only-booted.yaml" ) )
717
+ . expect ( "No spec found" ) ;
718
+
719
+ // Verbose output should include StateRoot, Deploy serial, Staged, and Commit
720
+ assert ! ( w. contains( "StateRoot:" ) ) ;
721
+ assert ! ( w. contains( "Deploy serial:" ) ) ;
722
+ assert ! ( w. contains( "Staged:" ) ) ;
723
+ assert ! ( w. contains( "Commit:" ) ) ;
724
+ }
637
725
}
0 commit comments