Skip to content

Commit 7f94a7a

Browse files
authored
Merge pull request #939 from cgwalters/use-path-booted
Use a shared const and helpers for run/ostree-booted
2 parents a2e6dc4 + d5e0d61 commit 7f94a7a

File tree

5 files changed

+72
-45
lines changed

5 files changed

+72
-45
lines changed

lib/src/cli.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use fn_error_context::context;
1717
use ostree::gio;
1818
use ostree_container::store::PrepareResult;
1919
use ostree_ext::container as ostree_container;
20+
use ostree_ext::container_utils::ostree_booted;
2021
use ostree_ext::keyfileext::KeyFileExt;
2122
use ostree_ext::ostree;
2223
use schemars::schema_for;
@@ -611,9 +612,10 @@ fn prepare_for_write() -> Result<()> {
611612
if ostree_ext::container_utils::running_in_container() {
612613
anyhow::bail!("Detected container; this command requires a booted host system.");
613614
}
614-
if !std::path::Path::new("/run/ostree-booted").exists() {
615-
anyhow::bail!("This command requires an ostree-booted host system");
616-
}
615+
anyhow::ensure!(
616+
ostree_booted()?,
617+
"This command requires an ostree-booted host system"
618+
);
617619
crate::cli::require_root()?;
618620
ensure_self_unshared_mount_namespace()?;
619621
if crate::lsm::selinux_enabled()? && !crate::lsm::selinux_ensure_install()? {

lib/src/generator.rs

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use anyhow::{Context, Result};
44
use cap_std::fs::Dir;
55
use cap_std_ext::{cap_std, dirext::CapStdExtDirExt};
66
use fn_error_context::context;
7+
use ostree_ext::container_utils::is_ostree_booted_in;
78
use rustix::{fd::AsFd, fs::StatVfsMountFlags};
89

910
const EDIT_UNIT: &str = "bootc-fstab-edit.service";
@@ -14,7 +15,7 @@ pub(crate) const BOOTC_EDITED_STAMP: &str = "Updated by bootc-fstab-edit.service
1415
#[context("bootc generator")]
1516
pub(crate) fn fstab_generator_impl(root: &Dir, unit_dir: &Dir) -> Result<bool> {
1617
// Do nothing if not ostree-booted
17-
if !root.try_exists("run/ostree-booted")? {
18+
if !is_ostree_booted_in(root)? {
1819
return Ok(false);
1920
}
2021

@@ -105,31 +106,37 @@ fn test_generator_no_fstab() -> Result<()> {
105106
Ok(())
106107
}
107108

108-
#[test]
109-
fn test_generator_fstab() -> Result<()> {
110-
let tempdir = fixture()?;
111-
let unit_dir = &tempdir.open_dir("run/systemd/system")?;
112-
// Should still be a no-op
113-
tempdir.atomic_write("etc/fstab", "# Some dummy fstab")?;
114-
fstab_generator_impl(&tempdir, &unit_dir).unwrap();
115-
assert_eq!(unit_dir.entries()?.count(), 0);
116-
117-
// Also a no-op, not booted via ostree
118-
tempdir.atomic_write("etc/fstab", &format!("# {FSTAB_ANACONDA_STAMP}"))?;
119-
fstab_generator_impl(&tempdir, &unit_dir).unwrap();
120-
assert_eq!(unit_dir.entries()?.count(), 0);
121-
122-
// Now it should generate
123-
tempdir.atomic_write("run/ostree-booted", "ostree booted")?;
124-
fstab_generator_impl(&tempdir, &unit_dir).unwrap();
125-
assert_eq!(unit_dir.entries()?.count(), 2);
126-
127-
Ok(())
128-
}
109+
#[cfg(test)]
110+
mod test {
111+
use super::*;
112+
113+
use ostree_ext::container_utils::OSTREE_BOOTED;
114+
115+
#[test]
116+
fn test_generator_fstab() -> Result<()> {
117+
let tempdir = fixture()?;
118+
let unit_dir = &tempdir.open_dir("run/systemd/system")?;
119+
// Should still be a no-op
120+
tempdir.atomic_write("etc/fstab", "# Some dummy fstab")?;
121+
fstab_generator_impl(&tempdir, &unit_dir).unwrap();
122+
assert_eq!(unit_dir.entries()?.count(), 0);
123+
124+
// Also a no-op, not booted via ostree
125+
tempdir.atomic_write("etc/fstab", &format!("# {FSTAB_ANACONDA_STAMP}"))?;
126+
fstab_generator_impl(&tempdir, &unit_dir).unwrap();
127+
assert_eq!(unit_dir.entries()?.count(), 0);
128+
129+
// Now it should generate
130+
tempdir.atomic_write(OSTREE_BOOTED, "ostree booted")?;
131+
fstab_generator_impl(&tempdir, &unit_dir).unwrap();
132+
assert_eq!(unit_dir.entries()?.count(), 2);
133+
134+
Ok(())
135+
}
129136

130-
#[test]
131-
fn test_generator_fstab_idempotent() -> Result<()> {
132-
let anaconda_fstab = indoc::indoc! { "
137+
#[test]
138+
fn test_generator_fstab_idempotent() -> Result<()> {
139+
let anaconda_fstab = indoc::indoc! { "
133140
#
134141
# /etc/fstab
135142
# Created by anaconda on Tue Mar 19 12:24:29 2024
@@ -144,14 +151,15 @@ fn test_generator_fstab_idempotent() -> Result<()> {
144151
UUID=715be2b7-c458-49f2-acec-b2fdb53d9089 / xfs ro 0 0
145152
UUID=341c4712-54e8-4839-8020-d94073b1dc8b /boot xfs defaults 0 0
146153
" };
147-
let tempdir = fixture()?;
148-
let unit_dir = &tempdir.open_dir("run/systemd/system")?;
154+
let tempdir = fixture()?;
155+
let unit_dir = &tempdir.open_dir("run/systemd/system")?;
149156

150-
tempdir.atomic_write("etc/fstab", anaconda_fstab)?;
151-
tempdir.atomic_write("run/ostree-booted", "ostree booted")?;
152-
let updated = fstab_generator_impl(&tempdir, &unit_dir).unwrap();
153-
assert!(!updated);
154-
assert_eq!(unit_dir.entries()?.count(), 0);
157+
tempdir.atomic_write("etc/fstab", anaconda_fstab)?;
158+
tempdir.atomic_write(OSTREE_BOOTED, "ostree booted")?;
159+
let updated = fstab_generator_impl(&tempdir, &unit_dir).unwrap();
160+
assert!(!updated);
161+
assert_eq!(unit_dir.entries()?.count(), 0);
155162

156-
Ok(())
163+
Ok(())
164+
}
157165
}

lib/src/status.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ use std::io::Read;
55
use std::io::Write;
66

77
use anyhow::{Context, Result};
8-
use camino::Utf8Path;
98
use fn_error_context::context;
109
use ostree::glib;
1110
use ostree_container::OstreeImageReference;
1211
use ostree_ext::container as ostree_container;
12+
use ostree_ext::container_utils::ostree_booted;
1313
use ostree_ext::keyfileext::KeyFileExt;
1414
use ostree_ext::oci_spec;
1515
use ostree_ext::ostree;
@@ -294,7 +294,7 @@ pub(crate) async fn status(opts: super::cli::StatusOpts) -> Result<()> {
294294
0 | 1 => {}
295295
o => anyhow::bail!("Unsupported format version: {o}"),
296296
};
297-
let host = if !Utf8Path::new("/run/ostree-booted").try_exists()? {
297+
let host = if !ostree_booted()? {
298298
Default::default()
299299
} else {
300300
let sysroot = super::cli::get_storage().await?;

ostree-ext/src/container_utils.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
//! Helpers for interacting with containers at runtime.
22
3-
use crate::keyfileext::KeyFileExt;
4-
use anyhow::Result;
5-
use ostree::glib;
3+
use std::io;
64
use std::io::Read;
75
use std::path::Path;
86

7+
use anyhow::Result;
8+
use ocidir::cap_std::fs::Dir;
9+
use ostree::glib;
10+
11+
use crate::keyfileext::KeyFileExt;
12+
13+
/// The relative path to the stamp file which signals this is an ostree-booted system.
14+
pub const OSTREE_BOOTED: &str = "run/ostree-booted";
15+
916
// See https://github.com/coreos/rpm-ostree/pull/3285#issuecomment-999101477
1017
// For compatibility with older ostree, we stick this in /sysroot where
1118
// it will be ignored.
@@ -64,6 +71,17 @@ pub fn is_bare_split_xattrs() -> Result<bool> {
6471
}
6572
}
6673

74+
/// Returns true if the system appears to have been booted via ostree.
75+
/// This accesses global state in /run.
76+
pub fn ostree_booted() -> io::Result<bool> {
77+
Path::new(&format!("/{OSTREE_BOOTED}")).try_exists()
78+
}
79+
80+
/// Returns true if the target root appears to have been booted via ostree.
81+
pub fn is_ostree_booted_in(rootfs: &Dir) -> io::Result<bool> {
82+
rootfs.try_exists(OSTREE_BOOTED)
83+
}
84+
6785
/// Returns `true` if the current booted filesystem appears to be an ostree-native container.
6886
///
6987
/// This just invokes [`is_bare_split_xattrs`] and [`running_in_container`].
@@ -73,8 +91,7 @@ pub fn is_ostree_container() -> Result<bool> {
7391
// If we have a container-ostree repo format, then we'll assume we're
7492
// running in a container unless there's strong evidence not (we detect
7593
// we're part of a systemd unit or are in a booted ostree system).
76-
let maybe_container = running_in_container()
77-
|| (!running_in_systemd && !Path::new("/run/ostree-booted").exists());
94+
let maybe_container = running_in_container() || (!running_in_systemd && !ostree_booted()?);
7895
Ok(is_container_ostree && maybe_container)
7996
}
8097

ostree-ext/src/integrationtest.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::path::Path;
44

5-
use crate::container_utils::is_ostree_container;
5+
use crate::container_utils::{is_ostree_container, ostree_booted};
66
use anyhow::{anyhow, Context, Result};
77
use camino::Utf8Path;
88
use cap_std::fs::Dir;
@@ -21,7 +21,7 @@ use xshell::cmd;
2121
pub(crate) fn detectenv() -> Result<&'static str> {
2222
let r = if is_ostree_container()? {
2323
"ostree-container"
24-
} else if Path::new("/run/ostree-booted").exists() {
24+
} else if ostree_booted()? {
2525
"ostree"
2626
} else if crate::container_utils::running_in_container() {
2727
"container"

0 commit comments

Comments
 (0)