@@ -16,7 +16,7 @@ use cap_std_ext::dirext::CapStdExtDirExt;
1616use composefs:: fsverity:: { FsVerityHashValue , Sha256HashValue , Sha512HashValue } ;
1717use composefs:: generic_tree:: { Directory , Inode , Leaf , LeafContent , Stat } ;
1818use composefs:: tree:: ImageError ;
19- use rustix:: fs:: readlinkat;
19+ use rustix:: fs:: { AtFlags , Gid , Uid , readlinkat} ;
2020
2121#[ derive( Debug ) ]
2222struct CustomMetadata {
@@ -195,7 +195,6 @@ fn get_modifications(
195195 . extend ( collect_all_files ( & curr_dir, current_path. clone ( ) ) ) ;
196196 }
197197
198- // TODO: Test if a file was changed to a directory
199198 Err ( e) => Err ( e) ?,
200199 }
201200 }
@@ -439,19 +438,14 @@ fn create_dir_with_perms(
439438 . set_permissions ( & dir_name, Permissions :: from_mode ( stat. st_mode ) )
440439 . context ( format ! ( "Changing permissions for dir {dir_name:?}" ) ) ?;
441440
442- println ! (
443- "Set permission of {dir_name:?} to {:?}" ,
444- Permissions :: from_mode( stat. st_mode)
445- ) ;
446-
447- // TODO: Handle ownership
448- //
449- // rustix::fs::chown(
450- // &modified,
451- // Some(Uid::from_raw(current_inode.stat().st_uid)),
452- // Some(Gid::from_raw(current_inode.stat().st_gid)),
453- // )
454- // .context(format!("chown {modified:?}"))?;
441+ rustix:: fs:: chownat (
442+ & new_etc_fd,
443+ dir_name,
444+ Some ( Uid :: from_raw ( stat. st_uid ) ) ,
445+ Some ( Gid :: from_raw ( stat. st_gid ) ) ,
446+ AtFlags :: SYMLINK_NOFOLLOW ,
447+ )
448+ . context ( format ! ( "chown {dir_name:?}" ) ) ?;
455449
456450 Ok ( ( ) )
457451}
@@ -478,6 +472,15 @@ fn handle_leaf(
478472 . copy ( & file, new_etc_fd, & file)
479473 . context ( format ! ( "Copying file {file:?}" ) ) ?;
480474
475+ rustix:: fs:: chownat (
476+ & new_etc_fd,
477+ file,
478+ Some ( Uid :: from_raw ( leaf. stat . st_uid ) ) ,
479+ Some ( Gid :: from_raw ( leaf. stat . st_gid ) ) ,
480+ AtFlags :: SYMLINK_NOFOLLOW ,
481+ )
482+ . context ( format ! ( "chown {file:?}" ) ) ?;
483+
481484 "file"
482485 }
483486
@@ -495,6 +498,15 @@ fn handle_leaf(
495498 . symlink ( PathBuf :: from ( os_str) , & file)
496499 . context ( format ! ( "Creating symlink {file:?}" ) ) ?;
497500
501+ rustix:: fs:: chownat (
502+ & new_etc_fd,
503+ file,
504+ Some ( Uid :: from_raw ( leaf. stat . st_uid ) ) ,
505+ Some ( Gid :: from_raw ( leaf. stat . st_gid ) ) ,
506+ AtFlags :: SYMLINK_NOFOLLOW ,
507+ )
508+ . context ( format ! ( "chown {file:?}" ) ) ?;
509+
498510 "symlink"
499511 }
500512
@@ -528,22 +540,8 @@ fn handle_modified_files(
528540 // Directory exists in the new /etc, but was modified in some way
529541 Ok ( ( dir, filename) ) => {
530542 let new_inode = dir. lookup ( filename) ;
531- // println!("new_inode: {new_inode:?}");
532-
533543 let ty = match current_inode {
534544 Inode :: Directory ( ..) => {
535- // let remove = match new_inode {
536- // // Dir with the same name is present in new /etc
537- // // We delete this dir and create a new one
538- // Some(Inode::Directory(..)) => true,
539-
540- // // Dir doesn't exist in the new /etc, so create it
541- // // Nothing to remove
542- // None => false,
543-
544- // _ => anyhow::bail!("Dir {file:?} converted to file"),
545- // };
546-
547545 create_dir_with_perms ( new_etc_fd, file, current_inode. stat ( ) , true ) ?;
548546
549547 "dir"
@@ -852,13 +850,23 @@ mod tests {
852850 c. create_dir_all ( "dir/perms" ) ?;
853851 c. set_permissions ( "dir/perms" , Permissions :: from_mode ( 0o777 ) ) ?;
854852
853+ // Directory ownership
854+ p. create_dir_all ( "dir/owner" ) ?;
855+
856+ c. create_dir_all ( "dir/owner" ) ?;
857+ rustix:: fs:: chownat (
858+ & c,
859+ "dir/owner" ,
860+ Some ( Uid :: from_raw ( u16:: MAX as u32 ) ) ,
861+ Some ( Gid :: from_raw ( u16:: MAX as u32 ) ) ,
862+ AtFlags :: SYMLINK_NOFOLLOW ,
863+ ) ?;
864+
855865 let ( pristine_etc_files, current_etc_files, new_etc_files) = traverse_etc ( & p, & c, & n) ?;
856866 let diff = compute_diff ( & pristine_etc_files, & current_etc_files) ?;
857867 println ! ( "current_etc_files: {current_etc_files:#?}" ) ;
858868 merge ( & c, & current_etc_files, & n, & new_etc_files, diff) ?;
859869
860- // std::thread::sleep(std::time::Duration::from_secs(4434));
861-
862870 assert ! ( files_eq( & c, & n, "new_file.txt" ) ?) ;
863871 assert ! ( files_eq( & c, & n, "a/new_file.txt" ) ?) ;
864872 assert ! ( files_eq( & c, & n, "a/b/new_file.txt" ) ?) ;
@@ -892,6 +900,11 @@ mod tests {
892900 n. metadata( "dir/perms" ) ?
893901 ) ) ;
894902
903+ assert ! ( compare_meta(
904+ c. metadata( "dir/owner" ) ?,
905+ n. metadata( "dir/owner" ) ?
906+ ) ) ;
907+
895908 Ok ( ( ) )
896909 }
897910}
0 commit comments