@@ -564,7 +564,7 @@ pub(crate) fn print_configuration() -> Result<()> {
564564}
565565
566566#[ context( "Creating ostree deployment" ) ]
567- async fn initialize_ostree_root ( state : & State , root_setup : & RootSetup ) -> Result < Storage > {
567+ async fn initialize_ostree_root ( state : & State , root_setup : & RootSetup ) -> Result < ( Storage , bool ) > {
568568 let sepolicy = state. load_policy ( ) ?;
569569 let sepolicy = sepolicy. as_ref ( ) ;
570570 // Load a fd for the mounted target physical root
@@ -578,11 +578,17 @@ async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result
578578
579579 let stateroot = state. stateroot ( ) ;
580580
581- Task :: new_and_run (
582- "Initializing ostree layout" ,
583- "ostree" ,
584- [ "admin" , "init-fs" , "--modern" , rootfs. as_str ( ) ] ,
585- ) ?;
581+ let has_ostree = rootfs_dir. try_exists ( "ostree/repo" ) ?;
582+ if !has_ostree {
583+ Task :: new_and_run (
584+ "Initializing ostree layout" ,
585+ "ostree" ,
586+ [ "admin" , "init-fs" , "--modern" , rootfs. as_str ( ) ] ,
587+ ) ?;
588+ } else {
589+ println ! ( "Reusing extant ostree layout" ) ;
590+ let _ = crate :: utils:: open_dir_remount_rw ( rootfs_dir, "sysroot" . into ( ) ) ?;
591+ }
586592
587593 // And also label /boot AKA xbootldr, if it exists
588594 let bootdir = rootfs. join ( "boot" ) ;
@@ -607,9 +613,14 @@ async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result
607613 let sysroot = ostree:: Sysroot :: new ( Some ( & gio:: File :: for_path ( rootfs) ) ) ;
608614 sysroot. load ( cancellable) ?;
609615
610- sysroot
611- . init_osname ( stateroot, cancellable)
612- . context ( "initializing stateroot" ) ?;
616+ let stateroot_exists = rootfs_dir. try_exists ( format ! ( "ostree/deploy/{stateroot}" ) ) ?;
617+ if stateroot_exists {
618+ anyhow:: bail!( "Cannot redeploy over extant stateroot {stateroot}" ) ;
619+ } else {
620+ sysroot
621+ . init_osname ( stateroot, cancellable)
622+ . context ( "initializing stateroot" ) ?;
623+ }
613624
614625 let sysroot_dir = Dir :: reopen_dir ( & crate :: utils:: sysroot_fd ( & sysroot) ) ?;
615626
@@ -637,14 +648,15 @@ async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result
637648 let sysroot = ostree:: Sysroot :: new ( Some ( & gio:: File :: for_path ( rootfs) ) ) ;
638649 sysroot. load ( cancellable) ?;
639650 let sysroot = SysrootLock :: new_from_sysroot ( & sysroot) . await ?;
640- Storage :: new ( sysroot, & temp_run)
651+ Ok ( ( Storage :: new ( sysroot, & temp_run) ? , has_ostree ) )
641652}
642653
643654#[ context( "Creating ostree deployment" ) ]
644655async fn install_container (
645656 state : & State ,
646657 root_setup : & RootSetup ,
647658 sysroot : & ostree:: Sysroot ,
659+ has_ostree : bool ,
648660) -> Result < ( ostree:: Deployment , InstallAleph ) > {
649661 let sepolicy = state. load_policy ( ) ?;
650662 let sepolicy = sepolicy. as_ref ( ) ;
@@ -730,6 +742,7 @@ async fn install_container(
730742 options. kargs = Some ( kargs. as_slice ( ) ) ;
731743 options. target_imgref = Some ( & state. target_imgref ) ;
732744 options. proxy_cfg = proxy_cfg;
745+ options. no_clean = has_ostree;
733746 let imgstate = crate :: utils:: async_task_with_spinner (
734747 "Deploying container image" ,
735748 ostree_container:: deploy:: deploy ( & sysroot, stateroot, & src_imageref, Some ( options) ) ,
@@ -1275,10 +1288,11 @@ async fn install_with_sysroot(
12751288 sysroot : & Storage ,
12761289 boot_uuid : & str ,
12771290 bound_images : & [ crate :: boundimage:: ResolvedBoundImage ] ,
1291+ has_ostree : bool ,
12781292) -> Result < ( ) > {
12791293 // And actually set up the container in that root, returning a deployment and
12801294 // the aleph state (see below).
1281- let ( _deployment, aleph) = install_container ( state, rootfs, & sysroot) . await ?;
1295+ let ( _deployment, aleph) = install_container ( state, rootfs, & sysroot, has_ostree ) . await ?;
12821296 // Write the aleph data that captures the system state at the time of provisioning for aid in future debugging.
12831297 rootfs
12841298 . rootfs_fd
@@ -1339,6 +1353,19 @@ async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Re
13391353 . ok_or_else ( || anyhow ! ( "No uuid for boot/root" ) ) ?;
13401354 tracing:: debug!( "boot uuid={boot_uuid}" ) ;
13411355
1356+ // If we're doing an alongside install, then the /dev bootupd sees needs to be the host's.
1357+ // What we probably really want to do here is tunnel in the host's /dev properly, but for now
1358+ // just copy /dev/disk
1359+ if rootfs. skip_finalize {
1360+ if !Utf8Path :: new ( "/dev/disk" ) . try_exists ( ) ? {
1361+ Task :: new_and_run (
1362+ "Copying host /dev/disk" ,
1363+ "cp" ,
1364+ [ "-a" , "/proc/1/root/dev/disk" , "/dev/disk" ] ,
1365+ ) ?;
1366+ }
1367+ }
1368+
13421369 let bound_images = if state. config_opts . skip_bound_images {
13431370 Vec :: new ( )
13441371 } else {
@@ -1359,8 +1386,16 @@ async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Re
13591386
13601387 // Initialize the ostree sysroot (repo, stateroot, etc.)
13611388 {
1362- let sysroot = initialize_ostree_root ( state, rootfs) . await ?;
1363- install_with_sysroot ( state, rootfs, & sysroot, & boot_uuid, & bound_images) . await ?;
1389+ let ( sysroot, has_ostree) = initialize_ostree_root ( state, rootfs) . await ?;
1390+ install_with_sysroot (
1391+ state,
1392+ rootfs,
1393+ & sysroot,
1394+ & boot_uuid,
1395+ & bound_images,
1396+ has_ostree,
1397+ )
1398+ . await ?;
13641399 // We must drop the sysroot here in order to close any open file
13651400 // descriptors.
13661401 }
@@ -1501,7 +1536,8 @@ fn remove_all_in_dir_no_xdev(d: &Dir) -> Result<()> {
15011536
15021537#[ context( "Removing boot directory content" ) ]
15031538fn clean_boot_directories ( rootfs : & Dir ) -> Result < ( ) > {
1504- let bootdir = rootfs. open_dir ( BOOT ) . context ( "Opening /boot" ) ?;
1539+ let bootdir =
1540+ crate :: utils:: open_dir_remount_rw ( rootfs, BOOT . into ( ) ) . context ( "Opening /boot" ) ?;
15051541 // This should not remove /boot/efi note.
15061542 remove_all_in_dir_no_xdev ( & bootdir) ?;
15071543 if ARCH_USES_EFI {
0 commit comments