@@ -187,7 +187,7 @@ use serde::{Deserialize, Serialize};
187187
188188#[ cfg( feature = "install-to-disk" ) ]
189189use self :: baseline:: InstallBlockDeviceOpts ;
190- use crate :: bootc_composefs:: status:: ComposefsCmdline ;
190+ use crate :: bootc_composefs:: status:: { ComposefsCmdline , get_bootloader } ;
191191use crate :: bootc_composefs:: {
192192 boot:: setup_composefs_boot, repo:: initialize_composefs_repository,
193193 status:: get_container_manifest_and_config,
@@ -1542,12 +1542,21 @@ async fn verify_target_fetch(
15421542}
15431543
15441544/// Preparation for an install; validates and prepares some (thereafter immutable) global state.
1545+ ///
1546+ /// # Parameters
1547+ /// - `config_opts`: Installation configuration options (root user setup, generic image, etc.)
1548+ /// - `source_opts`: Source image reference; if `None`, assumes running inside a container
1549+ /// - `target_opts`: Target image reference and root path options
1550+ /// - `composefs_options`: composefs-related settings for the installation
1551+ /// - `target_fs`: Target filesystem type; used for `install to-filesystem`
1552+ /// - `replace_mode`: If `Some`, indicates an `install to-filesystem` or `install to-existing-root` with the given replacement mode
15451553async fn prepare_install (
15461554 mut config_opts : InstallConfigOpts ,
15471555 source_opts : InstallSourceOpts ,
15481556 mut target_opts : InstallTargetOpts ,
15491557 mut composefs_options : InstallComposefsOpts ,
15501558 target_fs : Option < FilesystemEnum > ,
1559+ replace_mode : Option < ReplaceMode > ,
15511560) -> Result < Arc < State > > {
15521561 tracing:: trace!( "Preparing install" ) ;
15531562 let rootfs = cap_std:: fs:: Dir :: open_ambient_dir ( "/" , cap_std:: ambient_authority ( ) )
@@ -1698,6 +1707,12 @@ async fn prepare_install(
16981707
16991708 setup_sys_mount ( "efivarfs" , EFIVARFS ) ?;
17001709
1710+ // Read efivars to get the bootloader
1711+ // Only if the operation is to replace the existing installation
1712+ if let Some ( ..) = replace_mode {
1713+ config_opts. bootloader = Some ( get_bootloader ( ) . context ( "Determining existing bootloader" ) ?)
1714+ } ;
1715+
17011716 // Now, deal with SELinux state.
17021717 let selinux_state = reexecute_self_for_selinux_if_needed ( & source, config_opts. disable_selinux ) ?;
17031718 tracing:: debug!( "SELinux state: {selinux_state:?}" ) ;
@@ -2171,6 +2186,7 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
21712186 opts. target_opts ,
21722187 opts. composefs_opts ,
21732188 block_opts. filesystem ,
2189+ None ,
21742190 )
21752191 . await ?;
21762192
@@ -2560,6 +2576,7 @@ pub(crate) async fn install_to_filesystem(
25602576 opts. target_opts ,
25612577 opts. composefs_opts ,
25622578 Some ( inspect. fstype . as_str ( ) . try_into ( ) ?) ,
2579+ fsopts. replace ,
25632580 )
25642581 . await ?;
25652582
@@ -2633,18 +2650,22 @@ pub(crate) async fn install_to_filesystem(
26332650 false
26342651 }
26352652 } ;
2653+
26362654 // Find the UUID of /boot because we need it for GRUB.
2637- let boot_uuid = if boot_is_mount {
2638- let boot_path = target_root_path. join ( BOOT ) ;
2639- tracing:: debug!( "boot_path={boot_path}" ) ;
2640- let u = bootc_mount:: inspect_filesystem ( & boot_path)
2641- . with_context ( || format ! ( "Inspecting /{BOOT}" ) ) ?
2642- . uuid
2643- . ok_or_else ( || anyhow ! ( "No UUID found for /{BOOT}" ) ) ?;
2644- Some ( u)
2645- } else {
2646- None
2655+ let boot_uuid = match state. config_opts . bootloader {
2656+ Some ( Bootloader :: Grub ) | None if boot_is_mount => {
2657+ let boot_path = target_root_path. join ( BOOT ) ;
2658+ tracing:: debug!( "boot_path={boot_path}" ) ;
2659+ let u = bootc_mount:: inspect_filesystem ( & boot_path)
2660+ . with_context ( || format ! ( "Inspecting /{BOOT}" ) ) ?
2661+ . uuid
2662+ . ok_or_else ( || anyhow ! ( "No UUID found for /{BOOT}" ) ) ?;
2663+ Some ( u)
2664+ }
2665+
2666+ _ => None ,
26472667 } ;
2668+
26482669 tracing:: debug!( "boot UUID: {boot_uuid:?}" ) ;
26492670
26502671 // Find the real underlying backing device for the root. This is currently just required
0 commit comments