Skip to content

Commit 3efcbdd

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 <[email protected]>
1 parent 68d5cea commit 3efcbdd

File tree

3 files changed

+48
-14
lines changed

3 files changed

+48
-14
lines changed

crates/lib/src/store/mod.rs

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

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

208208
let sysroot = ostree::Sysroot::new_default();
209209
sysroot.set_mount_namespace_in_use();
@@ -223,6 +223,7 @@ impl BootedStorage {
223223

224224
Some(Self { storage })
225225
}
226+
// For container or non-bootc environments, there's no storage
226227
Environment::Container | Environment::Other => None,
227228
};
228229
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)