@@ -15,9 +15,9 @@ use std::io::Read;
1515use std:: os:: unix:: ffi:: OsStrExt ;
1616use std:: os:: unix:: fs:: MetadataExt ;
1717use std:: path:: { Path , PathBuf } ;
18- use std:: process:: { Command , Output } ;
1918
2019use anyhow:: { bail, Context , Result } ;
20+ use cmd_lib:: { run_cmd, run_fun} ;
2121use dstack_types:: volume:: {
2222 DstackVolumeHeader , DSTACK_VOLUME_HEADER_SIZE , DSTACK_VOLUME_KIND_VERITY , DSTACK_VOLUME_MAGIC ,
2323} ;
@@ -43,7 +43,7 @@ struct VerityVolume {
4343}
4444
4545fn main ( ) -> Result < ( ) > {
46- tracing_subscriber:: fmt ( ) . with_target ( false ) . init ( ) ;
46+ tracing_subscriber:: fmt ( ) . init ( ) ;
4747 let compose_path = std:: env:: args_os ( )
4848 . nth ( 1 )
4949 . map ( PathBuf :: from)
@@ -56,8 +56,8 @@ fn main() -> Result<()> {
5656 return Ok ( ( ) ) ;
5757 }
5858
59- let _ = run ( Command :: new ( " modprobe" ) . arg ( " dm-verity" ) ) ;
60- let _ = run ( Command :: new ( " udevadm" ) . args ( [ " settle" , " --timeout=5" ] ) ) ;
59+ let _ = run_cmd ! ( modprobe dm-verity) ;
60+ let _ = run_cmd ! ( udevadm settle --timeout=5 ) ;
6161
6262 let volumes = discover_volumes ( ) ?;
6363 info ! (
@@ -194,19 +194,6 @@ fn parse_header(bytes: &[u8]) -> Result<Option<DstackVolumeHeader>> {
194194}
195195
196196fn resolve_verity ( disk : & BlockDisk , header : DstackVolumeHeader ) -> Result < VerityVolume > {
197- if header. kind_version != 1 {
198- bail ! ( "unsupported verity version {}" , header. kind_version) ;
199- }
200- if header. flags != 0 {
201- bail ! ( "unsupported verity flags {:#x}" , header. flags) ;
202- }
203- if header. data_block_size != 4096 || header. hash_block_size != 4096 {
204- bail ! (
205- "unsupported verity block sizes {}/{}" ,
206- header. data_block_size,
207- header. hash_block_size
208- ) ;
209- }
210197 if disk. partitions . is_empty ( ) {
211198 bail ! ( "raw verity layout is not defined by kind version 1" ) ;
212199 }
@@ -249,27 +236,19 @@ fn activate_requested(
249236 info ! ( mapper = mapper_name, "reused active verity mapping" ) ;
250237 return Ok ( ( ) ) ;
251238 }
252- checked (
253- Command :: new ( "veritysetup" ) . args ( [ "close" , & mapper_name] ) ,
254- "closing stale verity mapping" ,
255- ) ?;
239+ run_cmd ! ( veritysetup close $mapper_name) . context ( "closing stale verity mapping" ) ?;
256240 }
257241
258242 // The on-disk root only selected a candidate. Pass the root from the
259243 // measured compose to veritysetup, which is the actual trust decision.
260- checked (
261- Command :: new ( "veritysetup" )
262- . arg ( "open" )
263- . arg ( & candidate. data )
264- . arg ( & mapper_name)
265- . arg ( & candidate. hash )
266- . arg ( & expected_root) ,
267- "opening dm-verity volume" ,
268- ) ?;
244+ let data = & candidate. data ;
245+ let hash = & candidate. hash ;
246+ run_cmd ! ( veritysetup open $data $mapper_name $hash $expected_root)
247+ . context ( "opening dm-verity volume" ) ?;
269248 if let Err ( err) =
270249 verify_first_block ( & mapped) . and_then ( |_| mount_volume ( index, requested, & mapped) )
271250 {
272- let _ = run ( Command :: new ( " veritysetup" ) . args ( [ " close" , & mapper_name] ) ) ;
251+ let _ = run_cmd ! ( veritysetup close $ mapper_name) ;
273252 return Err ( err) ;
274253 }
275254 used. insert ( candidate_index) ;
@@ -284,12 +263,7 @@ fn verify_first_block(path: &Path) -> Result<()> {
284263}
285264
286265fn mount_volume ( index : usize , requested : & RequestedVolume , mapped : & Path ) -> Result < ( ) > {
287- let fs_type = command_stdout (
288- Command :: new ( "blkid" )
289- . args ( [ "-o" , "value" , "-s" , "TYPE" ] )
290- . arg ( mapped) ,
291- )
292- . unwrap_or_default ( ) ;
266+ let fs_type = run_fun ! ( blkid -o value -s TYPE $mapped) . unwrap_or_default ( ) ;
293267 match & requested. target {
294268 VolumeTarget :: DockerSeed => {
295269 let mountpoint = PathBuf :: from ( format ! ( "/run/dstack-verity/{index}" ) ) ;
@@ -300,7 +274,7 @@ fn mount_volume(index: usize, requested: &RequestedVolume, mapped: &Path) -> Res
300274 mount_read_only ( mapped, & mountpoint, fs_type. trim ( ) ) ?;
301275 }
302276 if let Err ( err) = seed_docker ( & mountpoint) {
303- let _ = run ( Command :: new ( " umount" ) . arg ( & mountpoint) ) ;
277+ let _ = run_cmd ! ( umount $ mountpoint) ;
304278 return Err ( err) ;
305279 }
306280 info ! ( root = %hex:: encode( requested. verity_root) , "seeded docker from verity volume" ) ;
@@ -331,14 +305,12 @@ fn mount_read_only(device: &Path, target: &Path, fs_type: &str) -> Result<()> {
331305 } else {
332306 "ro"
333307 } ;
334- let mut command = Command :: new ( "mount" ) ;
335- if !fs_type. is_empty ( ) {
336- command. args ( [ "-t" , fs_type] ) ;
337- }
338- checked (
339- command. arg ( "-o" ) . arg ( options) . arg ( device) . arg ( target) ,
340- "mounting verity volume" ,
341- ) ?;
308+ if fs_type. is_empty ( ) {
309+ run_cmd ! ( mount -o $options $device $target) . context ( "mounting verity volume" ) ?;
310+ } else {
311+ run_cmd ! ( mount -t $fs_type -o $options $device $target)
312+ . context ( "mounting verity volume" ) ?;
313+ }
342314 Ok ( ( ) )
343315}
344316
@@ -360,23 +332,15 @@ fn seed_docker(volume: &Path) -> Result<()> {
360332 let target = store. join ( "overlay2" ) . join ( layer_id) . join ( "diff" ) ;
361333 fs:: create_dir_all ( & target) ?;
362334 if !is_mountpoint ( & target) ? {
363- if let Err ( err) = checked (
364- Command :: new ( "mount" )
365- . args ( [ "--bind" ] )
366- . arg ( & source)
367- . arg ( & target) ,
368- "binding docker layer" ,
369- ) {
335+ if let Err ( err) = run_cmd ! ( mount --bind $source $target) . context ( "binding docker layer" )
336+ {
370337 unwind_binds ( & bound) ;
371338 return Err ( err) ;
372339 }
373340 // A bind inherits neither the intended policy nor all mount flags.
374- if let Err ( err) = checked (
375- Command :: new ( "mount" )
376- . args ( [ "-o" , "remount,bind,ro" ] )
377- . arg ( & target) ,
378- "making docker layer read-only" ,
379- ) {
341+ if let Err ( err) =
342+ run_cmd ! ( mount -o remount, bind, ro $target) . context ( "making docker layer read-only" )
343+ {
380344 bound. push ( target) ;
381345 unwind_binds ( & bound) ;
382346 return Err ( err) ;
@@ -419,13 +383,8 @@ fn child_directories(path: &Path) -> Result<Vec<PathBuf>> {
419383
420384fn copy_contents ( source : & Path , target : & Path ) -> Result < ( ) > {
421385 fs:: create_dir_all ( target) ?;
422- checked (
423- Command :: new ( "cp" )
424- . args ( [ "-a" ] )
425- . arg ( source. join ( "." ) )
426- . arg ( target) ,
427- "copying docker metadata" ,
428- ) ?;
386+ let source_contents = source. join ( "." ) ;
387+ run_cmd ! ( cp -a $source_contents $target) . context ( "copying docker metadata" ) ?;
429388 Ok ( ( ) )
430389}
431390
@@ -474,10 +433,7 @@ fn copy_layer_metadata(volume: &Path, store: &Path) -> Result<()> {
474433 if source. file_name ( ) == Some ( OsStr :: new ( "diff" ) ) {
475434 continue ;
476435 }
477- checked (
478- Command :: new ( "cp" ) . args ( [ "-a" ] ) . arg ( & source) . arg ( & target) ,
479- "copying docker layer metadata" ,
480- ) ?;
436+ run_cmd ! ( cp -a $source $target) . context ( "copying docker layer metadata" ) ?;
481437 }
482438 }
483439 Ok ( ( ) )
@@ -549,20 +505,12 @@ fn unescape_mountinfo(value: &[u8]) -> Vec<u8> {
549505
550506fn unwind_binds ( paths : & [ PathBuf ] ) {
551507 for path in paths. iter ( ) . rev ( ) {
552- let _ = run ( Command :: new ( "umount" ) . arg ( path) ) ;
553- }
554- }
555-
556- fn command_stdout ( command : & mut Command ) -> Result < String > {
557- let output = command. output ( ) ?;
558- if !output. status . success ( ) {
559- bail ! ( "command failed with {}" , output. status) ;
508+ let _ = run_cmd ! ( umount $path) ;
560509 }
561- Ok ( String :: from_utf8 ( output. stdout ) ?)
562510}
563511
564512fn mapping_root ( mapper_name : & str ) -> Result < String > {
565- let status = command_stdout ( Command :: new ( " veritysetup" ) . args ( [ " status" , mapper_name] ) ) ?;
513+ let status = run_fun ! ( veritysetup status $ mapper_name) ?;
566514 status
567515 . lines ( )
568516 . find_map ( |line| {
@@ -574,22 +522,6 @@ fn mapping_root(mapper_name: &str) -> Result<String> {
574522 . context ( "verity mapping status has no root hash" )
575523}
576524
577- fn run ( command : & mut Command ) -> Result < Output > {
578- command. output ( ) . context ( "running command" )
579- }
580-
581- fn checked ( command : & mut Command , operation : & str ) -> Result < Output > {
582- let output = command. output ( ) . with_context ( || operation. to_string ( ) ) ?;
583- if !output. status . success ( ) {
584- bail ! (
585- "{operation} failed with {}: {}" ,
586- output. status,
587- String :: from_utf8_lossy( & output. stderr) . trim( )
588- ) ;
589- }
590- Ok ( output)
591- }
592-
593525#[ cfg( test) ]
594526mod tests {
595527 use super :: * ;
0 commit comments