@@ -49,6 +49,43 @@ fn get_kargs_in_root(d: &Dir, sys_arch: &str) -> Result<Vec<String>> {
49
49
Ok ( ret)
50
50
}
51
51
52
+ /// Load kargs.d files from the target ostree commit root
53
+ fn get_kargs_from_ostree (
54
+ repo : & ostree:: Repo ,
55
+ fetched_tree : & ostree:: RepoFile ,
56
+ sys_arch : & str ,
57
+ ) -> Result < Vec < String > > {
58
+ let cancellable = gio:: Cancellable :: NONE ;
59
+ let queryattrs = "standard::name,standard::type" ;
60
+ let queryflags = gio:: FileQueryInfoFlags :: NOFOLLOW_SYMLINKS ;
61
+ let fetched_iter = fetched_tree. enumerate_children ( queryattrs, queryflags, cancellable) ?;
62
+ let mut ret = Vec :: new ( ) ;
63
+ while let Some ( fetched_info) = fetched_iter. next_file ( cancellable) ? {
64
+ // only read and parse the file if it is a toml file
65
+ let name = fetched_info. name ( ) ;
66
+ if let Some ( name) = name. to_str ( ) {
67
+ if name. ends_with ( ".toml" ) {
68
+ let fetched_child = fetched_iter. child ( & fetched_info) ;
69
+ let fetched_child = fetched_child
70
+ . downcast :: < ostree:: RepoFile > ( )
71
+ . expect ( "downcast" ) ;
72
+ fetched_child. ensure_resolved ( ) ?;
73
+ let fetched_contents_checksum = fetched_child. checksum ( ) ;
74
+ let f =
75
+ ostree:: Repo :: load_file ( repo, fetched_contents_checksum. as_str ( ) , cancellable) ?;
76
+ let file_content = f. 0 ;
77
+ let mut reader =
78
+ ostree_ext:: prelude:: InputStreamExtManual :: into_read ( file_content. unwrap ( ) ) ;
79
+ let s = std:: io:: read_to_string ( & mut reader) ?;
80
+ let parsed_kargs =
81
+ parse_kargs_toml ( & s, sys_arch) . with_context ( || format ! ( "Parsing {name}" ) ) ?;
82
+ ret. extend ( parsed_kargs) ;
83
+ }
84
+ }
85
+ }
86
+ Ok ( ret)
87
+ }
88
+
52
89
/// Compute the kernel arguments for the new deployment. This starts from the booted
53
90
/// karg, but applies the diff between the bootc karg files in /usr/lib/bootc/kargs.d
54
91
/// between the booted deployment and the new one.
@@ -86,33 +123,7 @@ pub(crate) fn get_kargs(
86
123
return Ok ( kargs) ;
87
124
}
88
125
89
- let mut remote_kargs: Vec < String > = vec ! [ ] ;
90
- let queryattrs = "standard::name,standard::type" ;
91
- let queryflags = gio:: FileQueryInfoFlags :: NOFOLLOW_SYMLINKS ;
92
- let fetched_iter = fetched_tree. enumerate_children ( queryattrs, queryflags, cancellable) ?;
93
- while let Some ( fetched_info) = fetched_iter. next_file ( cancellable) ? {
94
- // only read and parse the file if it is a toml file
95
- let name = fetched_info. name ( ) ;
96
- if let Some ( name) = name. to_str ( ) {
97
- if name. ends_with ( ".toml" ) {
98
- let fetched_child = fetched_iter. child ( & fetched_info) ;
99
- let fetched_child = fetched_child
100
- . downcast :: < ostree:: RepoFile > ( )
101
- . expect ( "downcast" ) ;
102
- fetched_child. ensure_resolved ( ) ?;
103
- let fetched_contents_checksum = fetched_child. checksum ( ) ;
104
- let f =
105
- ostree:: Repo :: load_file ( repo, fetched_contents_checksum. as_str ( ) , cancellable) ?;
106
- let file_content = f. 0 ;
107
- let mut reader =
108
- ostree_ext:: prelude:: InputStreamExtManual :: into_read ( file_content. unwrap ( ) ) ;
109
- let s = std:: io:: read_to_string ( & mut reader) ?;
110
- let mut parsed_kargs =
111
- parse_kargs_toml ( & s, sys_arch) . with_context ( || format ! ( "Parsing {name}" ) ) ?;
112
- remote_kargs. append ( & mut parsed_kargs) ;
113
- }
114
- }
115
- }
126
+ let remote_kargs = get_kargs_from_ostree ( repo, & fetched_tree, sys_arch) ?;
116
127
117
128
// get the diff between the existing and remote kargs
118
129
let mut added_kargs: Vec < String > = remote_kargs
@@ -156,6 +167,9 @@ fn parse_kargs_toml(contents: &str, sys_arch: &str) -> Result<Vec<String>> {
156
167
157
168
#[ cfg( test) ]
158
169
mod tests {
170
+ use fn_error_context:: context;
171
+ use rustix:: fd:: { AsFd , AsRawFd } ;
172
+
159
173
use super :: * ;
160
174
161
175
#[ test]
@@ -208,6 +222,20 @@ match-architectures = ["x86_64", "aarch64"]
208
222
assert ! ( parse_kargs_toml( test_missing, "x86_64" ) . is_err( ) ) ;
209
223
}
210
224
225
+ #[ context( "writing test kargs" ) ]
226
+ fn write_test_kargs ( td : & Dir ) -> Result < ( ) > {
227
+ td. write (
228
+ "usr/lib/bootc/kargs.d/01-foo.toml" ,
229
+ r##"kargs = ["console=tty0", "nosmt"]"## ,
230
+ ) ?;
231
+ td. write (
232
+ "usr/lib/bootc/kargs.d/02-bar.toml" ,
233
+ r##"kargs = ["console=ttyS1"]"## ,
234
+ ) ?;
235
+
236
+ Ok ( ( ) )
237
+ }
238
+
211
239
#[ test]
212
240
fn test_get_kargs_in_root ( ) -> Result < ( ) > {
213
241
let td = cap_std_ext:: cap_tempfile:: TempDir :: new ( cap_std:: ambient_authority ( ) ) ?;
@@ -220,18 +248,83 @@ match-architectures = ["x86_64", "aarch64"]
220
248
// Non-toml file
221
249
td. write ( "usr/lib/bootc/kargs.d/somegarbage" , "garbage" ) ?;
222
250
assert_eq ! ( get_kargs_in_root( & td, "x86_64" ) . unwrap( ) . len( ) , 0 ) ;
223
- td. write (
224
- "usr/lib/bootc/kargs.d/01-foo.toml" ,
225
- r##"kargs = ["console=tty0", "nosmt"]"## ,
226
- ) ?;
227
- td. write (
228
- "usr/lib/bootc/kargs.d/02-bar.toml" ,
229
- r##"kargs = ["console=ttyS1"]"## ,
230
- ) ?;
251
+
252
+ write_test_kargs ( & td) ?;
231
253
232
254
let args = get_kargs_in_root ( & td, "x86_64" ) . unwrap ( ) ;
233
255
similar_asserts:: assert_eq!( args, [ "console=tty0" , "nosmt" , "console=ttyS1" ] ) ;
234
256
235
257
Ok ( ( ) )
236
258
}
259
+
260
+ #[ context( "ostree commit" ) ]
261
+ fn ostree_commit (
262
+ repo : & ostree:: Repo ,
263
+ d : & Dir ,
264
+ path : & Utf8Path ,
265
+ ostree_ref : & str ,
266
+ ) -> Result < ( ) > {
267
+ let cancellable = gio:: Cancellable :: NONE ;
268
+ let txn = repo. auto_transaction ( cancellable) ?;
269
+
270
+ let mt = ostree:: MutableTree :: new ( ) ;
271
+ repo. write_dfd_to_mtree ( d. as_fd ( ) . as_raw_fd ( ) , path. as_str ( ) , & mt, None , cancellable)
272
+ . context ( "Writing merged filesystem to mtree" ) ?;
273
+
274
+ let merged_root = repo
275
+ . write_mtree ( & mt, cancellable)
276
+ . context ( "Writing mtree" ) ?;
277
+ let merged_root = merged_root. downcast :: < ostree:: RepoFile > ( ) . unwrap ( ) ;
278
+ let merged_commit = repo
279
+ . write_commit ( None , None , None , None , & merged_root, cancellable)
280
+ . context ( "Writing commit" ) ?;
281
+ repo. transaction_set_ref ( None , & ostree_ref, Some ( merged_commit. as_str ( ) ) ) ;
282
+ txn. commit ( cancellable) ?;
283
+ Ok ( ( ) )
284
+ }
285
+
286
+ #[ test]
287
+ fn test_get_kargs_in_ostree ( ) -> Result < ( ) > {
288
+ let cancellable = gio:: Cancellable :: NONE ;
289
+ let td = cap_std_ext:: cap_tempfile:: TempDir :: new ( cap_std:: ambient_authority ( ) ) ?;
290
+
291
+ td. create_dir ( "repo" ) ?;
292
+ let repo = & ostree:: Repo :: create_at (
293
+ td. as_fd ( ) . as_raw_fd ( ) ,
294
+ "repo" ,
295
+ ostree:: RepoMode :: Bare ,
296
+ None ,
297
+ gio:: Cancellable :: NONE ,
298
+ ) ?;
299
+
300
+ td. create_dir ( "rootfs" ) ?;
301
+ let test_rootfs = & td. open_dir ( "rootfs" ) ?;
302
+
303
+ ostree_commit ( repo, & test_rootfs, "." . into ( ) , "testref" ) ?;
304
+ // Helper closure to read the kargs
305
+ let get_kargs = |sys_arch : & str | -> Result < Vec < String > > {
306
+ let rootfs = repo. read_commit ( "testref" , cancellable) ?. 0 ;
307
+ let rootfs = rootfs. downcast_ref :: < ostree:: RepoFile > ( ) . unwrap ( ) ;
308
+ let fetched_tree = rootfs. resolve_relative_path ( "/usr/lib/bootc/kargs.d" ) ;
309
+ let fetched_tree = fetched_tree
310
+ . downcast :: < ostree:: RepoFile > ( )
311
+ . expect ( "downcast" ) ;
312
+ if !fetched_tree. query_exists ( cancellable) {
313
+ return Ok ( Default :: default ( ) ) ;
314
+ }
315
+ get_kargs_from_ostree ( repo, & fetched_tree, sys_arch)
316
+ } ;
317
+
318
+ // rootfs is empty
319
+ assert_eq ! ( get_kargs( "x86_64" ) . unwrap( ) . len( ) , 0 ) ;
320
+
321
+ test_rootfs. create_dir_all ( "usr/lib/bootc/kargs.d" ) ?;
322
+ write_test_kargs ( & test_rootfs) . unwrap ( ) ;
323
+ ostree_commit ( repo, & test_rootfs, "." . into ( ) , "testref" ) ?;
324
+
325
+ let args = get_kargs ( "x86_64" ) . unwrap ( ) ;
326
+ similar_asserts:: assert_eq!( args, [ "console=tty0" , "nosmt" , "console=ttyS1" ] ) ;
327
+
328
+ Ok ( ( ) )
329
+ }
237
330
}
0 commit comments