@@ -63,19 +63,47 @@ impl From<ImageSignature> for ostree_container::SignatureSource {
63
63
}
64
64
}
65
65
66
+ /// A parsed composefs command line
67
+ pub ( crate ) struct ComposefsCmdline {
68
+ #[ allow( dead_code) ]
69
+ pub insecure : bool ,
70
+ pub digest : Box < str > ,
71
+ }
72
+
73
+ impl ComposefsCmdline {
74
+ pub ( crate ) fn new ( s : & str ) -> Self {
75
+ let ( insecure, digest_str) = s
76
+ . strip_prefix ( '?' )
77
+ . map ( |v| ( true , v) )
78
+ . unwrap_or_else ( || ( false , s) ) ;
79
+ ComposefsCmdline {
80
+ insecure,
81
+ digest : digest_str. into ( ) ,
82
+ }
83
+ }
84
+ }
85
+
86
+ impl std:: fmt:: Display for ComposefsCmdline {
87
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
88
+ let insecure = if self . insecure { "?" } else { "" } ;
89
+ write ! ( f, "{}={}{}" , COMPOSEFS_CMDLINE , insecure, self . digest)
90
+ }
91
+ }
92
+
66
93
/// Detect if we have composefs=<digest> in /proc/cmdline
67
- pub ( crate ) fn composefs_booted ( ) -> Result < Option < & ' static str > > {
68
- static CACHED_DIGEST_VALUE : OnceLock < Option < String > > = OnceLock :: new ( ) ;
94
+ pub ( crate ) fn composefs_booted ( ) -> Result < Option < & ' static ComposefsCmdline > > {
95
+ static CACHED_DIGEST_VALUE : OnceLock < Option < ComposefsCmdline > > = OnceLock :: new ( ) ;
69
96
if let Some ( v) = CACHED_DIGEST_VALUE . get ( ) {
70
- return Ok ( v. as_deref ( ) ) ;
97
+ return Ok ( v. as_ref ( ) ) ;
71
98
}
72
99
let cmdline = Cmdline :: from_proc ( ) ?;
73
100
let Some ( kv) = cmdline. find_str ( COMPOSEFS_CMDLINE ) else {
74
101
return Ok ( None ) ;
75
102
} ;
76
103
let Some ( v) = kv. value else { return Ok ( None ) } ;
77
- let r = CACHED_DIGEST_VALUE . get_or_init ( || Some ( v. to_owned ( ) ) ) ;
78
- Ok ( r. as_deref ( ) )
104
+ let v = ComposefsCmdline :: new ( v) ;
105
+ let r = CACHED_DIGEST_VALUE . get_or_init ( || Some ( v) ) ;
106
+ Ok ( r. as_ref ( ) )
79
107
}
80
108
81
109
/// Fixme lower serializability into ostree-ext
@@ -461,13 +489,9 @@ async fn boot_entry_from_composefs_deployment(
461
489
462
490
#[ context( "Getting composefs deployment status" ) ]
463
491
pub ( crate ) async fn composefs_deployment_status ( ) -> Result < Host > {
464
- let cmdline = Cmdline :: from_proc ( ) ?;
465
- let composefs_arg = cmdline
466
- . find_str ( COMPOSEFS_CMDLINE )
492
+ let composefs_state = composefs_booted ( ) ?
467
493
. ok_or_else ( || anyhow:: anyhow!( "Failed to find composefs parameter in kernel cmdline" ) ) ?;
468
- let booted_image_verity = composefs_arg
469
- . value
470
- . ok_or_else ( || anyhow:: anyhow!( "Missing value for composefs" ) ) ?;
494
+ let composefs_digest = & composefs_state. digest ;
471
495
472
496
let sysroot = cap_std:: fs:: Dir :: open_ambient_dir ( "/sysroot" , cap_std:: ambient_authority ( ) )
473
497
. context ( "Opening sysroot" ) ?;
@@ -532,7 +556,7 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
532
556
}
533
557
} ;
534
558
535
- if depl. file_name ( ) == booted_image_verity {
559
+ if depl. file_name ( ) == composefs_digest . as_ref ( ) {
536
560
host. spec . image = boot_entry. image . as_ref ( ) . map ( |x| x. image . clone ( ) ) ;
537
561
host. status . booted = Some ( boot_entry) ;
538
562
continue ;
@@ -563,7 +587,7 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
563
587
. options
564
588
. as_ref ( )
565
589
. ok_or ( anyhow:: anyhow!( "options key not found in bls config" ) ) ?
566
- . contains ( composefs_arg . as_ref ( ) ) ;
590
+ . contains ( composefs_digest . as_ref ( ) ) ;
567
591
}
568
592
569
593
BootType :: Uki => {
@@ -574,7 +598,7 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
574
598
. ok_or ( anyhow:: anyhow!( "First boot entry not found" ) ) ?
575
599
. body
576
600
. chainloader
577
- . contains ( composefs_arg . as_ref ( ) )
601
+ . contains ( composefs_digest . as_ref ( ) )
578
602
}
579
603
} ;
580
604
@@ -1083,4 +1107,15 @@ mod tests {
1083
1107
assert ! ( w. contains( "Commit:" ) ) ;
1084
1108
assert ! ( w. contains( "Soft-reboot:" ) ) ;
1085
1109
}
1110
+
1111
+ #[ test]
1112
+ fn test_composefs_parsing ( ) {
1113
+ const DIGEST : & str = "8b7df143d91c716ecfa5fc1730022f6b421b05cedee8fd52b1fc65a96030ad52" ;
1114
+ let v = ComposefsCmdline :: new ( DIGEST ) ;
1115
+ assert ! ( !v. insecure) ;
1116
+ assert_eq ! ( v. digest. as_ref( ) , DIGEST ) ;
1117
+ let v = ComposefsCmdline :: new ( & format ! ( "?{}" , DIGEST ) ) ;
1118
+ assert ! ( v. insecure) ;
1119
+ assert_eq ! ( v. digest. as_ref( ) , DIGEST ) ;
1120
+ }
1086
1121
}
0 commit comments