mirror of
https://github.com/containers/bootc.git
synced 2026-02-05 15:45:53 +01:00
composefs: Add option to reset soft reboot state
Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
This commit is contained in:
committed by
Colin Walters
parent
4c22d1664e
commit
7dd3683034
@@ -10,25 +10,70 @@ use bootc_initramfs_setup::setup_root;
|
||||
use bootc_kernel_cmdline::utf8::Cmdline;
|
||||
use bootc_mount::{PID1, bind_mount_from_pidns};
|
||||
use camino::Utf8Path;
|
||||
use cap_std_ext::cap_std::ambient_authority;
|
||||
use cap_std_ext::cap_std::fs::Dir;
|
||||
use cap_std_ext::dirext::CapStdExtDirExt;
|
||||
use fn_error_context::context;
|
||||
use ostree_ext::systemd_has_soft_reboot;
|
||||
use rustix::mount::{unmount, UnmountFlags};
|
||||
use std::{fs::create_dir_all, os::unix::process::CommandExt, path::PathBuf, process::Command};
|
||||
|
||||
const NEXTROOT: &str = "/run/nextroot";
|
||||
|
||||
#[context("Resetting soft reboot state")]
|
||||
fn reset_soft_reboot() -> Result<()> {
|
||||
let run = Utf8Path::new("/run");
|
||||
bind_mount_from_pidns(PID1, &run, &run, true).context("Bind mounting /run")?;
|
||||
|
||||
let run_dir = Dir::open_ambient_dir("/run", ambient_authority()).context("Opening run")?;
|
||||
|
||||
let nextroot = run_dir
|
||||
.open_dir_optional("nextroot")
|
||||
.context("Opening nextroot")?;
|
||||
|
||||
let Some(nextroot) = nextroot else {
|
||||
tracing::debug!("Nextroot is not a directory");
|
||||
println!("No deployment staged for soft rebooting");
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let nextroot_mounted = nextroot
|
||||
.is_mountpoint(".")?
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get mount info"))?;
|
||||
|
||||
if !nextroot_mounted {
|
||||
tracing::debug!("Nextroot is not a mountpoint");
|
||||
println!("No deployment staged for soft rebooting");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
unmount(NEXTROOT, UnmountFlags::DETACH).context("Unmounting nextroot")?;
|
||||
|
||||
println!("Soft reboot state cleared successfully");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Checks if the provided deployment is soft reboot capable, and soft reboots the system if
|
||||
/// argument `reboot` is true
|
||||
#[context("Soft rebooting")]
|
||||
pub(crate) async fn prepare_soft_reboot_composefs(
|
||||
storage: &Storage,
|
||||
booted_cfs: &BootedComposefs,
|
||||
deployment_id: &String,
|
||||
deployment_id: Option<&String>,
|
||||
reboot: bool,
|
||||
reset: bool,
|
||||
) -> Result<()> {
|
||||
if !systemd_has_soft_reboot() {
|
||||
anyhow::bail!("System does not support soft reboots")
|
||||
}
|
||||
|
||||
if reset {
|
||||
return reset_soft_reboot();
|
||||
}
|
||||
|
||||
let deployment_id = deployment_id.ok_or_else(|| anyhow::anyhow!("Expected deployment id"))?;
|
||||
|
||||
if *deployment_id == *booted_cfs.cmdline.digest {
|
||||
anyhow::bail!("Cannot soft-reboot to currently booted deployment");
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ pub(crate) async fn do_upgrade(
|
||||
}
|
||||
|
||||
if opts.soft_reboot.is_some() {
|
||||
prepare_soft_reboot_composefs(storage, booted_cfs, &id.to_hex(), true).await?;
|
||||
prepare_soft_reboot_composefs(storage, booted_cfs, Some(&id.to_hex()), true, false).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -618,8 +618,12 @@ pub(crate) enum InternalsOpts {
|
||||
/// Dump CLI structure as JSON for documentation generation
|
||||
DumpCliJson,
|
||||
PrepSoftReboot {
|
||||
deployment: String,
|
||||
#[clap(long)]
|
||||
#[clap(required_unless_present = "reset")]
|
||||
deployment: Option<String>,
|
||||
#[clap(long, conflicts_with = "reset")]
|
||||
reboot: bool,
|
||||
#[clap(long, conflicts_with = "reboot")]
|
||||
reset: bool,
|
||||
reboot: bool,
|
||||
},
|
||||
}
|
||||
@@ -1836,7 +1840,11 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
InternalsOpts::PrepSoftReboot { deployment, reboot } => {
|
||||
InternalsOpts::PrepSoftReboot {
|
||||
deployment,
|
||||
reboot,
|
||||
reset,
|
||||
} => {
|
||||
let storage = &get_storage().await?;
|
||||
|
||||
match storage.kind()? {
|
||||
@@ -1845,8 +1853,14 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
|
||||
anyhow::bail!("soft-reboot only implemented for composefs")
|
||||
}
|
||||
BootedStorageKind::Composefs(booted_cfs) => {
|
||||
prepare_soft_reboot_composefs(&storage, &booted_cfs, &deployment, reboot)
|
||||
.await
|
||||
prepare_soft_reboot_composefs(
|
||||
&storage,
|
||||
&booted_cfs,
|
||||
deployment.as_ref(),
|
||||
reboot,
|
||||
reset,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user