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