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_kernel_cmdline::utf8::Cmdline;
|
||||||
use bootc_mount::{PID1, bind_mount_from_pidns};
|
use bootc_mount::{PID1, bind_mount_from_pidns};
|
||||||
use camino::Utf8Path;
|
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 fn_error_context::context;
|
||||||
use ostree_ext::systemd_has_soft_reboot;
|
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};
|
use std::{fs::create_dir_all, os::unix::process::CommandExt, path::PathBuf, process::Command};
|
||||||
|
|
||||||
const NEXTROOT: &str = "/run/nextroot";
|
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
|
/// Checks if the provided deployment is soft reboot capable, and soft reboots the system if
|
||||||
/// argument `reboot` is true
|
/// argument `reboot` is true
|
||||||
#[context("Soft rebooting")]
|
#[context("Soft rebooting")]
|
||||||
pub(crate) async fn prepare_soft_reboot_composefs(
|
pub(crate) async fn prepare_soft_reboot_composefs(
|
||||||
storage: &Storage,
|
storage: &Storage,
|
||||||
booted_cfs: &BootedComposefs,
|
booted_cfs: &BootedComposefs,
|
||||||
deployment_id: &String,
|
deployment_id: Option<&String>,
|
||||||
reboot: bool,
|
reboot: bool,
|
||||||
|
reset: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if !systemd_has_soft_reboot() {
|
if !systemd_has_soft_reboot() {
|
||||||
anyhow::bail!("System does not support soft reboots")
|
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 {
|
if *deployment_id == *booted_cfs.cmdline.digest {
|
||||||
anyhow::bail!("Cannot soft-reboot to currently booted deployment");
|
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() {
|
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(())
|
Ok(())
|
||||||
|
|||||||
@@ -618,8 +618,12 @@ pub(crate) enum InternalsOpts {
|
|||||||
/// Dump CLI structure as JSON for documentation generation
|
/// Dump CLI structure as JSON for documentation generation
|
||||||
DumpCliJson,
|
DumpCliJson,
|
||||||
PrepSoftReboot {
|
PrepSoftReboot {
|
||||||
deployment: String,
|
#[clap(required_unless_present = "reset")]
|
||||||
#[clap(long)]
|
deployment: Option<String>,
|
||||||
|
#[clap(long, conflicts_with = "reset")]
|
||||||
|
reboot: bool,
|
||||||
|
#[clap(long, conflicts_with = "reboot")]
|
||||||
|
reset: bool,
|
||||||
reboot: bool,
|
reboot: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1836,7 +1840,11 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
InternalsOpts::PrepSoftReboot { deployment, reboot } => {
|
InternalsOpts::PrepSoftReboot {
|
||||||
|
deployment,
|
||||||
|
reboot,
|
||||||
|
reset,
|
||||||
|
} => {
|
||||||
let storage = &get_storage().await?;
|
let storage = &get_storage().await?;
|
||||||
|
|
||||||
match storage.kind()? {
|
match storage.kind()? {
|
||||||
@@ -1845,8 +1853,14 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
|
|||||||
anyhow::bail!("soft-reboot only implemented for composefs")
|
anyhow::bail!("soft-reboot only implemented for composefs")
|
||||||
}
|
}
|
||||||
BootedStorageKind::Composefs(booted_cfs) => {
|
BootedStorageKind::Composefs(booted_cfs) => {
|
||||||
prepare_soft_reboot_composefs(&storage, &booted_cfs, &deployment, reboot)
|
prepare_soft_reboot_composefs(
|
||||||
.await
|
&storage,
|
||||||
|
&booted_cfs,
|
||||||
|
deployment.as_ref(),
|
||||||
|
reboot,
|
||||||
|
reset,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user