Skip to content

Commit 313dc53

Browse files
committed
lib: Fix bootc status on non-bootc systems
Previously, `BootedStorage::new()` unconditionally tried to open `/sysroot` before checking the environment type. This caused `bootc status` to fail on non-ostree/composefs systems. (We did work in containers and we had tests for that; but the container case is special cased even earlier) Fixes: https://issues.redhat.com/browse/RHEL-135687 Assisted-by: Claude Code (Opus 4.5) Signed-off-by: Colin Walters <walters@verbum.org>
1 parent a578483 commit 313dc53

3 files changed

Lines changed: 48 additions & 14 deletions

File tree

crates/lib/src/store/mod.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -143,28 +143,27 @@ pub(crate) enum BootedStorageKind<'a> {
143143
Composefs(BootedComposefs),
144144
}
145145

146+
/// Open the physical root (/sysroot) and /run directories for a booted system.
147+
fn get_physical_root_and_run() -> Result<(Dir, Dir)> {
148+
let physical_root = {
149+
let d = Dir::open_ambient_dir("/sysroot", cap_std::ambient_authority())
150+
.context("Opening /sysroot")?;
151+
open_dir_remount_rw(&d, ".".into())?
152+
};
153+
let run =
154+
Dir::open_ambient_dir("/run", cap_std::ambient_authority()).context("Opening /run")?;
155+
Ok((physical_root, run))
156+
}
157+
146158
impl BootedStorage {
147159
/// Create a new booted storage accessor for the given environment.
148160
///
149161
/// The caller must have already called `prepare_for_write()` if
150162
/// `env.needs_mount_namespace()` is true.
151163
pub(crate) async fn new(env: Environment) -> Result<Option<Self>> {
152-
let physical_root = {
153-
let d = Dir::open_ambient_dir("/sysroot", cap_std::ambient_authority())
154-
.context("Opening /sysroot")?;
155-
// Remount /sysroot rw only if we are in a new mount ns
156-
if env.needs_mount_namespace() {
157-
open_dir_remount_rw(&d, ".".into())?
158-
} else {
159-
d
160-
}
161-
};
162-
163-
let run =
164-
Dir::open_ambient_dir("/run", cap_std::ambient_authority()).context("Opening /run")?;
165-
166164
let r = match &env {
167165
Environment::ComposefsBooted(cmdline) => {
166+
let (physical_root, run) = get_physical_root_and_run()?;
168167
let mut composefs = ComposefsRepository::open_path(&physical_root, COMPOSEFS)?;
169168
if cmdline.insecure {
170169
composefs.set_insecure(true);
@@ -201,6 +200,7 @@ impl BootedStorage {
201200
// remount /sysroot as writable, and we call set_mount_namespace_in_use()
202201
// to indicate we're in a mount namespace. Without actually being in a
203202
// mount namespace, this would leave the global /sysroot writable.
203+
let (physical_root, run) = get_physical_root_and_run()?;
204204

205205
let sysroot = ostree::Sysroot::new_default();
206206
sysroot.set_mount_namespace_in_use();
@@ -219,6 +219,7 @@ impl BootedStorage {
219219

220220
Some(Self { storage })
221221
}
222+
// For container or non-bootc environments, there's no storage
222223
Environment::Container | Environment::Other => None,
223224
};
224225
Ok(r)

hack/provision-packit.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ set -exuo pipefail
44
# Check environment
55
printenv
66

7+
# This must work outside of a container too
8+
bootc status
9+
710
# temp folder to save building files and folders
811
BOOTC_TEMPDIR=$(mktemp -d)
912
trap 'rm -rf -- "$BOOTC_TEMPDIR"' EXIT
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/bash
2+
# Test that `bootc status` works on a non-bootc-deployed system.
3+
#
4+
# This simulates a "package mode" environment where bootc is installed
5+
# via RPM on a traditional system (not deployed via ostree/composefs).
6+
# The key is hiding /run/.containerenv so bootc doesn't think it's in a container.
7+
#
8+
# xref: https://issues.redhat.com/browse/RHEL-135687
9+
set -euo pipefail
10+
image=$1
11+
12+
# Run the container with:
13+
# - A tmpfs over /run to hide .containerenv (simulates bare metal)
14+
# - Unset the 'container' environment variable
15+
# - No /sysroot (simulates package mode)
16+
# Use --format=humanreadable to get consistent output
17+
output=$(podman run --rm \
18+
--tmpfs /run \
19+
--env container= \
20+
"$image" \
21+
bootc status --format=humanreadable 2>&1)
22+
23+
# Verify the output indicates this is not a bootc-deployed system
24+
if echo "$output" | grep -q "System is not deployed via bootc"; then
25+
echo "ok status-outside-container: correctly reports non-bootc system"
26+
else
27+
echo "FAIL: unexpected output from bootc status:" >&2
28+
echo "$output" >&2
29+
exit 1
30+
fi

0 commit comments

Comments
 (0)