@@ -325,7 +325,7 @@ pub(crate) async fn status(opts: super::cli::StatusOpts) -> Result<()> {
325325 . to_canon_json_writer ( & mut out)
326326 . map_err ( anyhow:: Error :: new) ,
327327 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 ) ,
329329 }
330330 . context ( "Writing to stdout" ) ?;
331331
@@ -359,12 +359,35 @@ fn write_row_name(mut out: impl Write, s: &str, prefix_len: usize) -> Result<()>
359359 Ok ( ( ) )
360360}
361361
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+
362384/// Write the data for a container image based status.
363385fn human_render_slot (
364386 mut out : impl Write ,
365387 slot : Option < Slot > ,
366388 entry : & crate :: spec:: BootEntry ,
367389 image : & crate :: spec:: ImageStatus ,
390+ verbose : bool ,
368391) -> Result < ( ) > {
369392 let transport = & image. image . transport ;
370393 let imagename = & image. image . image ;
@@ -415,6 +438,33 @@ fn human_render_slot(
415438 writeln ! ( out, "yes" ) ?;
416439 }
417440
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+
418468 tracing:: debug!( "pinned={}" , entry. pinned) ;
419469
420470 Ok ( ( ) )
@@ -426,6 +476,7 @@ fn human_render_slot_ostree(
426476 slot : Option < Slot > ,
427477 entry : & crate :: spec:: BootEntry ,
428478 ostree_commit : & str ,
479+ verbose : bool ,
429480) -> Result < ( ) > {
430481 // TODO consider rendering more ostree stuff here like rpm-ostree status does
431482 let prefix = match slot {
@@ -444,11 +495,18 @@ fn human_render_slot_ostree(
444495 writeln ! ( out, "yes" ) ?;
445496 }
446497
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+
447505 tracing:: debug!( "pinned={}" , entry. pinned) ;
448506 Ok ( ( ) )
449507}
450508
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 < ( ) > {
452510 let mut first = true ;
453511 for ( slot_name, status) in [
454512 ( Slot :: Staged , & host. status . staged ) ,
@@ -462,9 +520,15 @@ fn human_readable_output_booted(mut out: impl Write, host: &Host) -> Result<()>
462520 writeln ! ( out) ?;
463521 }
464522 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 ) ?;
466524 } 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+ ) ?;
468532 } else {
469533 writeln ! ( out, "Current {slot_name} state is unknown" ) ?;
470534 }
@@ -476,9 +540,9 @@ fn human_readable_output_booted(mut out: impl Write, host: &Host) -> Result<()>
476540 writeln ! ( out) ?;
477541
478542 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 ) ?;
480544 } 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 ) ?;
482546 }
483547 }
484548 }
@@ -487,9 +551,9 @@ fn human_readable_output_booted(mut out: impl Write, host: &Host) -> Result<()>
487551}
488552
489553/// 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 < ( ) > {
491555 if host. status . booted . is_some ( ) {
492- human_readable_output_booted ( out, host) ?;
556+ human_readable_output_booted ( out, host, verbose ) ?;
493557 } else {
494558 writeln ! ( out, "System is not deployed via bootc." ) ?;
495559 }
@@ -503,7 +567,17 @@ mod tests {
503567 fn human_status_from_spec_fixture ( spec_fixture : & str ) -> Result < String > {
504568 let host: Host = serde_yaml:: from_str ( spec_fixture) . unwrap ( ) ;
505569 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 ( ) ;
507581 let w = String :: from_utf8 ( w) . unwrap ( ) ;
508582 Ok ( w)
509583 }
@@ -634,4 +708,18 @@ mod tests {
634708 " } ;
635709 similar_asserts:: assert_eq!( w, expected) ;
636710 }
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+ }
637725}
0 commit comments