Skip to content

Commit 3cfa0b6

Browse files
cli/composefs: Show staged/rollback deployments
Store the staged deployment at `/run/composefs/staged-deployment` similar to how it's done in ostree Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent 6783896 commit 3cfa0b6

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

lib/src/cli.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ async fn upgrade_composefs(_opts: UpgradeOpts) -> Result<()> {
831831
BootType::Uki => setup_composefs_uki_boot(BootSetupType::Upgrade, repo, &id, entry),
832832
}?;
833833

834-
write_composefs_state(&Utf8PathBuf::from("/sysroot"), id, imgref)?;
834+
write_composefs_state(&Utf8PathBuf::from("/sysroot"), id, imgref, true)?;
835835

836836
Ok(())
837837
}

lib/src/install.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub(crate) mod osconfig;
1515

1616
use std::collections::HashMap;
1717
use std::fs::create_dir_all;
18-
use std::io::{Seek, SeekFrom, Write};
18+
use std::io::Write;
1919
use std::os::fd::{AsFd, AsRawFd};
2020
use std::os::unix::fs::symlink;
2121
use std::os::unix::process::CommandExt;
@@ -1779,19 +1779,26 @@ fn setup_composefs_boot(root_setup: &RootSetup, state: &State, image_id: &str) -
17791779
transport: state.source.imageref.transport.to_string(),
17801780
signature: None,
17811781
},
1782+
false,
17821783
)?;
17831784

17841785
Ok(())
17851786
}
17861787

1788+
pub(crate) const COMPOSEFS_TRANSIENT_STATE_DIR: &str = "/run/composefs";
1789+
pub(crate) const COMPOSEFS_STAGED_DEPLOYMENT_PATH: &str = "/run/composefs/staged-deployment";
1790+
/// Relative to /sysroot
1791+
pub(crate) const STATE_DIR_RELATIVE: &str = "state/deploy";
1792+
17871793
/// Creates and populates /sysroot/state/deploy/image_id
17881794
#[context("Writing composefs state")]
17891795
pub(crate) fn write_composefs_state(
17901796
root_path: &Utf8PathBuf,
17911797
deployment_id: Sha256HashValue,
17921798
imgref: &ImageReference,
1799+
staged: bool,
17931800
) -> Result<()> {
1794-
let state_path = root_path.join(format!("state/deploy/{}", deployment_id.to_hex()));
1801+
let state_path = root_path.join(format!("{STATE_DIR_RELATIVE}/{}", deployment_id.to_hex()));
17951802

17961803
create_dir_all(state_path.join("etc/upper"))?;
17971804
create_dir_all(state_path.join("etc/work"))?;
@@ -1821,6 +1828,19 @@ pub(crate) fn write_composefs_state(
18211828
.write(config.to_string().as_bytes())
18221829
.context("Falied to write to .origin file")?;
18231830

1831+
if staged {
1832+
std::fs::create_dir_all(COMPOSEFS_TRANSIENT_STATE_DIR)
1833+
.with_context(|| format!("Creating {COMPOSEFS_TRANSIENT_STATE_DIR}"))?;
1834+
1835+
let mut file = std::fs::OpenOptions::new()
1836+
.write(true)
1837+
.create(true)
1838+
.open(COMPOSEFS_STAGED_DEPLOYMENT_PATH)
1839+
.context("Opening staged-deployment file")?;
1840+
1841+
file.write_all(deployment_id.to_hex().as_bytes())?;
1842+
}
1843+
18241844
Ok(())
18251845
}
18261846

lib/src/status.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use ostree_ext::ostree;
2323
use tokio::io::AsyncReadExt;
2424

2525
use crate::cli::OutputFormat;
26+
use crate::install::{COMPOSEFS_STAGED_DEPLOYMENT_PATH, STATE_DIR_RELATIVE};
2627
use crate::spec::ImageStatus;
2728
use crate::spec::{BootEntry, BootOrder, Host, HostSpec, HostStatus, HostType};
2829
use crate::spec::{ImageReference, ImageSignature};
@@ -389,8 +390,8 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
389390
let sysroot = cap_std::fs::Dir::open_ambient_dir("/sysroot", cap_std::ambient_authority())
390391
.context("Opening sysroot")?;
391392
let deployments = sysroot
392-
.read_dir("state/deploy")
393-
.context("Reading sysroot state/deploy")?;
393+
.read_dir(STATE_DIR_RELATIVE)
394+
.with_context(|| format!("Reading sysroot {STATE_DIR_RELATIVE}"))?;
394395

395396
let host_spec = HostSpec {
396397
image: None,
@@ -399,6 +400,17 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
399400

400401
let mut host = Host::new(host_spec);
401402

403+
let staged_deployment_id = match std::fs::File::open(COMPOSEFS_STAGED_DEPLOYMENT_PATH) {
404+
Ok(mut f) => {
405+
let mut s = String::new();
406+
f.read_to_string(&mut s)?;
407+
408+
Ok(Some(s))
409+
}
410+
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
411+
Err(e) => Err(e),
412+
}?;
413+
402414
for depl in deployments {
403415
let depl = depl?;
404416

@@ -422,6 +434,15 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
422434
host.status.booted = Some(boot_entry);
423435
continue;
424436
}
437+
438+
if let Some(staged_deployment_id) = &staged_deployment_id {
439+
if depl_file_name == staged_deployment_id.trim() {
440+
host.status.staged = Some(boot_entry);
441+
continue;
442+
}
443+
}
444+
445+
host.status.rollback = Some(boot_entry);
425446
}
426447

427448
Ok(host)

0 commit comments

Comments
 (0)