Skip to content

Commit 7e50df1

Browse files
committed
start moving to systemd service model
1 parent 75b8806 commit 7e50df1

File tree

3 files changed

+89
-24
lines changed

3 files changed

+89
-24
lines changed

crates/lib/src/cli.rs

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,8 @@ pub(crate) enum InternalsOpts {
485485
/// Initiate a reboot the same way we would after --apply; intended
486486
/// primarily for testing.
487487
Reboot,
488+
/// Check if soft reboot should be performed and prepare if needed
489+
PrepareSoftReboot,
488490
#[cfg(feature = "rhsm")]
489491
/// Publish subscription-manager facts to /etc/rhsm/facts/bootc.facts
490492
PublishRhsmFacts,
@@ -738,7 +740,40 @@ fn can_perform_soft_reboot(deployment: Option<&crate::spec::BootEntry>) -> bool
738740
deployment.map(|d| d.soft_reboot_capable).unwrap_or(false)
739741
}
740742

741-
/// Prepare and execute a soft reboot for the given deployment
743+
/// If there is staged deployment, check if soft reboot is possible and prepare the system for it
744+
fn should_soft_reboot(
745+
sysroot: &crate::store::Storage,
746+
booted_deployment: Option<&ostree::Deployment>,
747+
) -> Result<bool> {
748+
// Get updated status to check for soft-reboot capability
749+
let (_deployments, updated_host) = crate::status::get_status(sysroot, booted_deployment)?;
750+
751+
// Check if there's a staged deployment that can perform soft reboot
752+
if can_perform_soft_reboot(updated_host.status.staged.as_ref()) {
753+
soft_reboot_staged(sysroot)?;
754+
return Ok(true);
755+
}
756+
757+
//Check if we are trying to rollback
758+
//Then prepare for soft reboot for the rollback deployment
759+
let host = crate::status::get_status_require_booted(sysroot)?.2;
760+
if host.spec.boot_order == crate::spec::BootOrder::Rollback {
761+
if can_perform_soft_reboot(host.status.rollback.as_ref()) {
762+
println!("Rollback deployment is soft-reboot capable, preparing for soft-reboot...");
763+
764+
let deployments_list = sysroot.deployments();
765+
let target_deployment = deployments_list
766+
.first()
767+
.ok_or_else(|| anyhow::anyhow!("No deployments found after rollback"))?;
768+
769+
prepare_soft_reboot(sysroot, target_deployment)?;
770+
return Ok(true);
771+
}
772+
}
773+
Ok(false)
774+
}
775+
776+
/// Prepare a soft reboot for the given deployment
742777
#[context("Preparing soft reboot")]
743778
fn prepare_soft_reboot(
744779
sysroot: &crate::store::Storage,
@@ -887,9 +922,6 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
887922
println!("Staged update present, not changed.");
888923

889924
if opts.apply {
890-
if can_perform_soft_reboot(host.status.staged.as_ref()) {
891-
soft_reboot_staged(sysroot)?;
892-
}
893925
crate::reboot::reboot()?;
894926
}
895927
} else if booted_unchanged {
@@ -986,12 +1018,6 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
9861018
sysroot.update_mtime()?;
9871019

9881020
if opts.apply {
989-
// Get updated status to check for soft-reboot capability
990-
let updated_host = crate::status::get_status(sysroot, Some(&booted_deployment))?.1;
991-
992-
if can_perform_soft_reboot(updated_host.status.staged.as_ref()) {
993-
soft_reboot_staged(sysroot)?;
994-
}
9951021
crate::reboot::reboot()?;
9961022
}
9971023

@@ -1005,20 +1031,6 @@ async fn rollback(opts: RollbackOpts) -> Result<()> {
10051031
crate::deploy::rollback(sysroot).await?;
10061032

10071033
if opts.apply {
1008-
// Get status before rollback to check soft-reboot capability
1009-
let host = crate::status::get_status_require_booted(sysroot)?.2;
1010-
1011-
if can_perform_soft_reboot(host.status.rollback.as_ref()) {
1012-
println!("Rollback deployment is soft-reboot capable, performing soft-reboot...");
1013-
1014-
let deployments_list = sysroot.deployments();
1015-
let target_deployment = deployments_list
1016-
.first()
1017-
.ok_or_else(|| anyhow::anyhow!("No deployments found after rollback"))?;
1018-
1019-
prepare_soft_reboot(sysroot, target_deployment)?;
1020-
}
1021-
10221034
crate::reboot::reboot()?;
10231035
}
10241036

@@ -1302,6 +1314,17 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
13021314
}
13031315
},
13041316
InternalsOpts::Reboot => crate::reboot::reboot(),
1317+
InternalsOpts::PrepareSoftReboot => {
1318+
let sysroot = &get_storage().await?;
1319+
let booted_deployment = sysroot.booted_deployment();
1320+
let should_perform = should_soft_reboot(sysroot, booted_deployment.as_ref())?;
1321+
if should_perform {
1322+
println!("Soft reboot preparation completed");
1323+
} else {
1324+
println!("Soft reboot not needed");
1325+
}
1326+
Ok(())
1327+
}
13051328
InternalsOpts::Fsck => {
13061329
let sysroot = &get_storage().await?;
13071330
crate::fsck::fsck(&sysroot, std::io::stdout().lock()).await?;

crates/lib/src/status.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,18 @@ fn human_render_slot(
467467
}
468468
}
469469
}
470+
471+
// Show soft-reboot capability
472+
write_row_name(&mut out, "Soft-reboot", prefix_len)?;
473+
writeln!(
474+
out,
475+
"{}",
476+
if entry.soft_reboot_capable {
477+
"yes"
478+
} else {
479+
"no"
480+
}
481+
)?;
470482
}
471483

472484
tracing::debug!("pinned={}", entry.pinned);
@@ -504,6 +516,18 @@ fn human_render_slot_ostree(
504516
if let Some(ostree) = &entry.ostree {
505517
render_verbose_ostree_info(&mut out, ostree, slot, prefix_len)?;
506518
}
519+
520+
// Show soft-reboot capability
521+
write_row_name(&mut out, "Soft-reboot", prefix_len)?;
522+
writeln!(
523+
out,
524+
"{}",
525+
if entry.soft_reboot_capable {
526+
"yes"
527+
} else {
528+
"no"
529+
}
530+
)?;
507531
}
508532

509533
tracing::debug!("pinned={}", entry.pinned);
@@ -725,5 +749,6 @@ mod tests {
725749
assert!(w.contains("Deploy serial:"));
726750
assert!(w.contains("Staged:"));
727751
assert!(w.contains("Commit:"));
752+
assert!(w.contains("Soft-reboot:"));
728753
}
729754
}

systemd/bootc-soft-reboot.service

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[Unit]
2+
Description=bootc soft reboot preparation
3+
Documentation=man:bootc(8)
4+
ConditionPathExists=/run/ostree-booted
5+
DefaultDependencies=no
6+
Before=reboot.target soft-reboot.target ostree-finalize-staged.service
7+
Conflicts=reboot.target soft-reboot.target
8+
9+
[Service]
10+
Type=oneshot
11+
RemainAfterExit=yes
12+
ExecStart=/bin/true
13+
ExecStop=/usr/bin/bootc internals prepare-soft-reboot
14+
TimeoutStopSec=5m
15+
16+
[Install]
17+
WantedBy=multi-user.target

0 commit comments

Comments
 (0)