Skip to content

Commit d93c0e4

Browse files
install-to-fs: Move ostree target check before prepare_install
We need to know the underlying filesystem for the install to filesystem target, which we can't get just by `findmnt` if `/` is mounted as overlay, which is the case for ostree systems (and composefs systems) in the future. We already had code checking for this, move it around so we have that info BEFORE we call `prepare_install` Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
1 parent 6bd6c9a commit d93c0e4

1 file changed

Lines changed: 96 additions & 42 deletions

File tree

crates/lib/src/install.rs

Lines changed: 96 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ use crate::store::Storage;
201201
use crate::task::Task;
202202
use crate::utils::sigpolicy_from_opt;
203203
use bootc_kernel_cmdline::{INITRD_ARG_PREFIX, ROOTFLAGS, bytes, utf8};
204-
use bootc_mount::{Filesystem, inspect_filesystem};
204+
use bootc_mount::Filesystem;
205205
use composefs::fsverity::FsVerityHashValue;
206206

207207
/// The toplevel boot directory
@@ -2353,43 +2353,11 @@ pub(crate) async fn install_to_filesystem(
23532353
target_path
23542354
);
23552355

2356-
let fs_inspect = inspect_filesystem(&opts.filesystem_opts.root_path)?;
2357-
2358-
// Gather global state, destructuring the provided options.
2359-
// IMPORTANT: We might re-execute the current process in this function (for SELinux among other things)
2360-
// IMPORTANT: and hence anything that is done before MUST BE IDEMPOTENT.
2361-
// IMPORTANT: In practice, we should only be gathering information before this point,
2362-
// IMPORTANT: and not performing any mutations at all.
2363-
let state = prepare_install(
2364-
opts.config_opts,
2365-
opts.source_opts,
2366-
opts.target_opts,
2367-
opts.composefs_opts,
2368-
Some(fs_inspect.fstype.as_str().try_into()?),
2369-
)
2370-
.await?;
2371-
23722356
// And the last bit of state here is the fsopts, which we also destructure now.
23732357
let mut fsopts = opts.filesystem_opts;
23742358

2375-
// If we're doing an alongside install, automatically set up the host rootfs
2376-
// mount if it wasn't done already.
2377-
if targeting_host_root
2378-
&& fsopts.root_path.as_str() == ALONGSIDE_ROOT_MOUNT
2379-
&& !fsopts.root_path.try_exists()?
2380-
{
2381-
tracing::debug!("Mounting host / to {ALONGSIDE_ROOT_MOUNT}");
2382-
std::fs::create_dir(ALONGSIDE_ROOT_MOUNT)?;
2383-
bootc_mount::bind_mount_from_pidns(
2384-
bootc_mount::PID1,
2385-
"/".into(),
2386-
ALONGSIDE_ROOT_MOUNT.into(),
2387-
true,
2388-
)
2389-
.context("Mounting host / to {ALONGSIDE_ROOT_MOUNT}")?;
2390-
}
2391-
23922359
let target_root_path = fsopts.root_path.clone();
2360+
23932361
// Get a file descriptor for the root path /target
23942362
let target_rootfs_fd =
23952363
Dir::open_ambient_dir(&target_root_path, cap_std::ambient_authority())
@@ -2412,11 +2380,6 @@ pub(crate) async fn install_to_filesystem(
24122380
}
24132381
}
24142382

2415-
// Check to see if this happens to be the real host root
2416-
if !fsopts.acknowledge_destructive {
2417-
warn_on_host_root(&target_rootfs_fd)?;
2418-
}
2419-
24202383
// If we're installing to an ostree root, then find the physical root from
24212384
// the deployment root.
24222385
let possible_physical_root = fsopts.root_path.join("sysroot");
@@ -2446,6 +2409,100 @@ pub(crate) async fn install_to_filesystem(
24462409
target_rootfs_fd.try_clone()?
24472410
};
24482411

2412+
// Gather data about the root filesystem
2413+
let inspect = bootc_mount::inspect_filesystem(&fsopts.root_path)?;
2414+
2415+
// Gather global state, destructuring the provided options.
2416+
// IMPORTANT: We might re-execute the current process in this function (for SELinux among other things)
2417+
// IMPORTANT: and hence anything that is done before MUST BE IDEMPOTENT.
2418+
// IMPORTANT: In practice, we should only be gathering information before this point,
2419+
// IMPORTANT: and not performing any mutations at all.
2420+
let state = prepare_install(
2421+
opts.config_opts,
2422+
opts.source_opts,
2423+
opts.target_opts,
2424+
opts.composefs_opts,
2425+
Some(inspect.fstype.as_str().try_into()?),
2426+
)
2427+
.await?;
2428+
2429+
// And the last bit of state here is the fsopts, which we also destructure now.
2430+
// let mut fsopts = opts.filesystem_opts;
2431+
2432+
// If we're doing an alongside install, automatically set up the host rootfs
2433+
// mount if it wasn't done already.
2434+
if targeting_host_root
2435+
&& target_root_path.as_str() == ALONGSIDE_ROOT_MOUNT
2436+
&& !target_root_path.try_exists()?
2437+
{
2438+
tracing::debug!("Mounting host / to {ALONGSIDE_ROOT_MOUNT}");
2439+
std::fs::create_dir(ALONGSIDE_ROOT_MOUNT)?;
2440+
bootc_mount::bind_mount_from_pidns(
2441+
bootc_mount::PID1,
2442+
"/".into(),
2443+
ALONGSIDE_ROOT_MOUNT.into(),
2444+
true,
2445+
)
2446+
.context("Mounting host / to {ALONGSIDE_ROOT_MOUNT}")?;
2447+
}
2448+
2449+
// let target_root_path = fsopts.root_path.clone();
2450+
// // Get a file descriptor for the root path /target
2451+
// let target_rootfs_fd =
2452+
// Dir::open_ambient_dir(&target_root_path, cap_std::ambient_authority())
2453+
// .with_context(|| format!("Opening target root directory {target_root_path}"))?;
2454+
//
2455+
// tracing::debug!("Target root filesystem: {target_root_path}");
2456+
//
2457+
// if let Some(false) = target_rootfs_fd.is_mountpoint(".")? {
2458+
// anyhow::bail!("Not a mountpoint: {target_root_path}");
2459+
// }
2460+
//
2461+
// // Check that the target is a directory
2462+
// {
2463+
// let root_path = &fsopts.root_path;
2464+
// let st = root_path
2465+
// .symlink_metadata()
2466+
// .with_context(|| format!("Querying target filesystem {root_path}"))?;
2467+
// if !st.is_dir() {
2468+
// anyhow::bail!("Not a directory: {root_path}");
2469+
// }
2470+
// }
2471+
2472+
// Check to see if this happens to be the real host root
2473+
if !fsopts.acknowledge_destructive {
2474+
warn_on_host_root(&target_rootfs_fd)?;
2475+
}
2476+
2477+
// // If we're installing to an ostree root, then find the physical root from
2478+
// // the deployment root.
2479+
// let possible_physical_root = fsopts.root_path.join("sysroot");
2480+
// let possible_ostree_dir = possible_physical_root.join("ostree");
2481+
// let is_already_ostree = possible_ostree_dir.exists();
2482+
// if is_already_ostree {
2483+
// tracing::debug!(
2484+
// "ostree detected in {possible_ostree_dir}, assuming target is a deployment root and using {possible_physical_root}"
2485+
// );
2486+
// fsopts.root_path = possible_physical_root;
2487+
// };
2488+
//
2489+
// // Get a file descriptor for the root path
2490+
// // It will be /target/sysroot on ostree OS, or will be /target
2491+
// let rootfs_fd = if is_already_ostree {
2492+
// let root_path = &fsopts.root_path;
2493+
// let rootfs_fd = Dir::open_ambient_dir(&fsopts.root_path, cap_std::ambient_authority())
2494+
// .with_context(|| format!("Opening target root directory {root_path}"))?;
2495+
//
2496+
// tracing::debug!("Root filesystem: {root_path}");
2497+
//
2498+
// if let Some(false) = rootfs_fd.is_mountpoint(".")? {
2499+
// anyhow::bail!("Not a mountpoint: {root_path}");
2500+
// }
2501+
// rootfs_fd
2502+
// } else {
2503+
// target_rootfs_fd.try_clone()?
2504+
// };
2505+
24492506
match fsopts.replace {
24502507
Some(ReplaceMode::Wipe) => {
24512508
let rootfs_fd = rootfs_fd.try_clone()?;
@@ -2459,9 +2516,6 @@ pub(crate) async fn install_to_filesystem(
24592516
None => require_empty_rootdir(&rootfs_fd)?,
24602517
}
24612518

2462-
// Gather data about the root filesystem
2463-
let inspect = bootc_mount::inspect_filesystem(&fsopts.root_path)?;
2464-
24652519
// We support overriding the mount specification for root (i.e. LABEL vs UUID versus
24662520
// raw paths).
24672521
// We also support an empty specification as a signal to omit any mountspec kargs.

0 commit comments

Comments
 (0)