@@ -253,6 +253,15 @@ pub(crate) fn get_status(
253
253
. map ( |d| boot_entry_from_deployment ( sysroot, d) )
254
254
. transpose ( )
255
255
. context ( "Rollback deployment" ) ?;
256
+ let pinned = deployments
257
+ . other
258
+ . iter ( )
259
+ . filter_map ( |d| {
260
+ d. is_pinned ( )
261
+ . then ( || boot_entry_from_deployment ( sysroot, d) . ok ( ) )
262
+ } )
263
+ . collect :: < Option < Vec < _ > > > ( )
264
+ . filter ( |v| !v. is_empty ( ) ) ;
256
265
let spec = staged
257
266
. as_ref ( )
258
267
. or ( booted. as_ref ( ) )
@@ -280,6 +289,7 @@ pub(crate) fn get_status(
280
289
booted,
281
290
rollback,
282
291
rollback_queued,
292
+ pinned,
283
293
ty,
284
294
} ;
285
295
Ok ( ( deployments, host) )
@@ -336,6 +346,7 @@ pub enum Slot {
336
346
Staged ,
337
347
Booted ,
338
348
Rollback ,
349
+ Pinned ,
339
350
}
340
351
341
352
impl std:: fmt:: Display for Slot {
@@ -344,6 +355,7 @@ impl std::fmt::Display for Slot {
344
355
Slot :: Staged => "staged" ,
345
356
Slot :: Booted => "booted" ,
346
357
Slot :: Rollback => "rollback" ,
358
+ Slot :: Pinned => "pinned" ,
347
359
} ;
348
360
f. write_str ( s)
349
361
}
@@ -359,10 +371,11 @@ fn write_row_name(mut out: impl Write, s: &str, prefix_len: usize) -> Result<()>
359
371
}
360
372
361
373
/// Write the data for a container image based status.
362
- fn human_render_imagestatus (
374
+ fn human_render_image_deployment (
363
375
mut out : impl Write ,
364
376
slot : Slot ,
365
377
image : & crate :: spec:: ImageStatus ,
378
+ host_status : & crate :: spec:: HostStatus ,
366
379
) -> Result < ( ) > {
367
380
let transport = & image. image . transport ;
368
381
let imagename = & image. image . image ;
@@ -377,6 +390,7 @@ fn human_render_imagestatus(
377
390
Slot :: Staged => " Staged image" . into ( ) ,
378
391
Slot :: Booted => format ! ( "{} Booted image" , crate :: glyph:: Glyph :: BlackCircle ) ,
379
392
Slot :: Rollback => " Rollback image" . into ( ) ,
393
+ Slot :: Pinned => " Pinned image" . into ( ) ,
380
394
} ;
381
395
let prefix_len = prefix. chars ( ) . count ( ) ;
382
396
writeln ! ( out, "{prefix}: {imageref}" ) ?;
@@ -407,20 +421,37 @@ fn human_render_imagestatus(
407
421
writeln ! ( out, "{timestamp}" ) ?;
408
422
}
409
423
424
+ if host_status. is_pinned ( slot) {
425
+ write_row_name ( & mut out, "Pinned" , prefix_len) ?;
426
+ writeln ! ( out, "yes" ) ?;
427
+ }
428
+
410
429
Ok ( ( ) )
411
430
}
412
431
413
- fn human_render_ostree ( mut out : impl Write , slot : Slot , ostree_commit : & str ) -> Result < ( ) > {
432
+ fn human_render_ostree_deployment (
433
+ mut out : impl Write ,
434
+ slot : Slot ,
435
+ ostree_commit : & str ,
436
+ host_status : & crate :: spec:: HostStatus ,
437
+ ) -> Result < ( ) > {
414
438
// TODO consider rendering more ostree stuff here like rpm-ostree status does
415
439
let prefix = match slot {
416
440
Slot :: Staged => " Staged ostree" . into ( ) ,
417
441
Slot :: Booted => format ! ( "{} Booted ostree" , crate :: glyph:: Glyph :: BlackCircle ) ,
418
442
Slot :: Rollback => " Rollback ostree" . into ( ) ,
443
+ Slot :: Pinned => " Pinned ostree" . into ( ) ,
419
444
} ;
420
445
let prefix_len = prefix. len ( ) ;
421
446
writeln ! ( out, "{prefix}" ) ?;
422
447
write_row_name ( & mut out, "Commit" , prefix_len) ?;
423
448
writeln ! ( out, "{ostree_commit}" ) ?;
449
+
450
+ if host_status. is_pinned ( slot) {
451
+ write_row_name ( & mut out, "Pinned" , prefix_len) ?;
452
+ writeln ! ( out, "yes" ) ?;
453
+ }
454
+
424
455
Ok ( ( ) )
425
456
}
426
457
@@ -438,14 +469,36 @@ fn human_readable_output_booted(mut out: impl Write, host: &Host) -> Result<()>
438
469
writeln ! ( out) ?;
439
470
}
440
471
if let Some ( image) = & host_status. image {
441
- human_render_imagestatus ( & mut out, slot_name, image) ?;
472
+ human_render_image_deployment ( & mut out, slot_name, image, & host . status ) ?;
442
473
} else if let Some ( ostree) = host_status. ostree . as_ref ( ) {
443
- human_render_ostree ( & mut out, slot_name, & ostree. checksum ) ?;
474
+ human_render_ostree_deployment (
475
+ & mut out,
476
+ slot_name,
477
+ & ostree. checksum ,
478
+ & host. status ,
479
+ ) ?;
444
480
} else {
445
481
writeln ! ( out, "Current {slot_name} state is unknown" ) ?;
446
482
}
447
483
}
448
484
}
485
+
486
+ if let Some ( pinned) = & host. status . pinned {
487
+ writeln ! ( out) ?;
488
+ for entry in pinned {
489
+ if let Some ( image) = & entry. image {
490
+ human_render_image_deployment ( & mut out, Slot :: Pinned , image, & host. status ) ?;
491
+ } else if let Some ( ostree) = entry. ostree . as_ref ( ) {
492
+ human_render_ostree_deployment (
493
+ & mut out,
494
+ Slot :: Pinned ,
495
+ & ostree. checksum ,
496
+ & host. status ,
497
+ ) ?;
498
+ }
499
+ }
500
+ }
501
+
449
502
Ok ( ( ) )
450
503
}
451
504
@@ -480,7 +533,7 @@ mod tests {
480
533
Staged image: quay.io/example/someimage:latest
481
534
Digest: sha256:16dc2b6256b4ff0d2ec18d2dbfb06d117904010c8cf9732cdb022818cf7a7566 (arm64)
482
535
Version: nightly (2023-10-14T19:22:15Z)
483
-
536
+
484
537
● Booted image: quay.io/example/someimage:latest
485
538
Digest: sha256:736b359467c9437c1ac915acaae952aad854e07eb4a16a94999a48af08c83c34 (arm64)
486
539
Version: nightly (2023-09-30T19:22:16Z)
@@ -498,7 +551,7 @@ mod tests {
498
551
let expected = indoc:: indoc! { r"
499
552
Staged ostree
500
553
Commit: 1c24260fdd1be20f72a4a97a75c582834ee3431fbb0fa8e4f482bb219d633a45
501
-
554
+
502
555
● Booted ostree
503
556
Commit: f9fa3a553ceaaaf30cf85bfe7eed46a822f7b8fd7e14c1e3389cbc3f6d27f791
504
557
" } ;
@@ -514,7 +567,7 @@ mod tests {
514
567
Staged image: quay.io/centos-bootc/centos-bootc:stream9
515
568
Digest: sha256:47e5ed613a970b6574bfa954ab25bb6e85656552899aa518b5961d9645102b38 (s390x)
516
569
Version: stream9.20240807.0
517
-
570
+
518
571
● Booted ostree
519
572
Commit: f9fa3a553ceaaaf30cf85bfe7eed46a822f7b8fd7e14c1e3389cbc3f6d27f791
520
573
" } ;
@@ -534,6 +587,25 @@ mod tests {
534
587
similar_asserts:: assert_eq!( w, expected) ;
535
588
}
536
589
590
+ #[ test]
591
+ fn test_human_readable_booted_pinned_spec ( ) {
592
+ // booted image, no staged/rollback
593
+ let w = human_status_from_spec_fixture ( include_str ! ( "fixtures/spec-booted-pinned.yaml" ) )
594
+ . expect ( "No spec found" ) ;
595
+ let expected = indoc:: indoc! { r"
596
+ ● Booted image: quay.io/centos-bootc/centos-bootc:stream9
597
+ Digest: sha256:47e5ed613a970b6574bfa954ab25bb6e85656552899aa518b5961d9645102b38 (arm64)
598
+ Version: stream9.20240807.0
599
+ Pinned: yes
600
+
601
+ Pinned image: quay.io/centos-bootc/centos-bootc:stream9
602
+ Digest: sha256:47e5ed613a970b6574bfa954ab25bb6e85656552899aa518b5961d9645102b37 (arm64)
603
+ Version: stream9.20240807.0
604
+ Pinned: yes
605
+ " } ;
606
+ similar_asserts:: assert_eq!( w, expected) ;
607
+ }
608
+
537
609
#[ test]
538
610
fn test_human_readable_staged_rollback_spec ( ) {
539
611
// staged/rollback image, no booted
0 commit comments