mirror of
https://github.com/containers/bootc.git
synced 2026-02-05 06:45:13 +01:00
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>
This commit is contained in:
@@ -145,28 +145,27 @@ pub(crate) enum BootedStorageKind<'a> {
|
||||
Composefs(BootedComposefs),
|
||||
}
|
||||
|
||||
/// Open the physical root (/sysroot) and /run directories for a booted system.
|
||||
fn get_physical_root_and_run() -> Result<(Dir, Dir)> {
|
||||
let physical_root = {
|
||||
let d = Dir::open_ambient_dir("/sysroot", cap_std::ambient_authority())
|
||||
.context("Opening /sysroot")?;
|
||||
open_dir_remount_rw(&d, ".".into())?
|
||||
};
|
||||
let run =
|
||||
Dir::open_ambient_dir("/run", cap_std::ambient_authority()).context("Opening /run")?;
|
||||
Ok((physical_root, run))
|
||||
}
|
||||
|
||||
impl BootedStorage {
|
||||
/// Create a new booted storage accessor for the given environment.
|
||||
///
|
||||
/// The caller must have already called `prepare_for_write()` if
|
||||
/// `env.needs_mount_namespace()` is true.
|
||||
pub(crate) async fn new(env: Environment) -> Result<Option<Self>> {
|
||||
let physical_root = {
|
||||
let d = Dir::open_ambient_dir("/sysroot", cap_std::ambient_authority())
|
||||
.context("Opening /sysroot")?;
|
||||
// Remount /sysroot rw only if we are in a new mount ns
|
||||
if env.needs_mount_namespace() {
|
||||
open_dir_remount_rw(&d, ".".into())?
|
||||
} else {
|
||||
d
|
||||
}
|
||||
};
|
||||
|
||||
let run =
|
||||
Dir::open_ambient_dir("/run", cap_std::ambient_authority()).context("Opening /run")?;
|
||||
|
||||
let r = match &env {
|
||||
Environment::ComposefsBooted(cmdline) => {
|
||||
let (physical_root, run) = get_physical_root_and_run()?;
|
||||
let mut composefs = ComposefsRepository::open_path(&physical_root, COMPOSEFS)?;
|
||||
if cmdline.insecure {
|
||||
composefs.set_insecure(true);
|
||||
@@ -204,6 +203,7 @@ impl BootedStorage {
|
||||
// remount /sysroot as writable, and we call set_mount_namespace_in_use()
|
||||
// to indicate we're in a mount namespace. Without actually being in a
|
||||
// mount namespace, this would leave the global /sysroot writable.
|
||||
let (physical_root, run) = get_physical_root_and_run()?;
|
||||
|
||||
let sysroot = ostree::Sysroot::new_default();
|
||||
sysroot.set_mount_namespace_in_use();
|
||||
@@ -223,6 +223,7 @@ impl BootedStorage {
|
||||
|
||||
Some(Self { storage })
|
||||
}
|
||||
// For container or non-bootc environments, there's no storage
|
||||
Environment::Container | Environment::Other => None,
|
||||
};
|
||||
Ok(r)
|
||||
|
||||
@@ -4,6 +4,9 @@ set -exuo pipefail
|
||||
# Check environment
|
||||
printenv
|
||||
|
||||
# This must work outside of a container too
|
||||
bootc status
|
||||
|
||||
# temp folder to save building files and folders
|
||||
BOOTC_TEMPDIR=$(mktemp -d)
|
||||
trap 'rm -rf -- "$BOOTC_TEMPDIR"' EXIT
|
||||
|
||||
30
tests/container/status-outside-container/run
Executable file
30
tests/container/status-outside-container/run
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
# Test that `bootc status` works on a non-bootc-deployed system.
|
||||
#
|
||||
# This simulates a "package mode" environment where bootc is installed
|
||||
# via RPM on a traditional system (not deployed via ostree/composefs).
|
||||
# The key is hiding /run/.containerenv so bootc doesn't think it's in a container.
|
||||
#
|
||||
# xref: https://issues.redhat.com/browse/RHEL-135687
|
||||
set -euo pipefail
|
||||
image=$1
|
||||
|
||||
# Run the container with:
|
||||
# - A tmpfs over /run to hide .containerenv (simulates bare metal)
|
||||
# - Unset the 'container' environment variable
|
||||
# - No /sysroot (simulates package mode)
|
||||
# Use --format=humanreadable to get consistent output
|
||||
output=$(podman run --rm \
|
||||
--tmpfs /run \
|
||||
--env container= \
|
||||
"$image" \
|
||||
bootc status --format=humanreadable 2>&1)
|
||||
|
||||
# Verify the output indicates this is not a bootc-deployed system
|
||||
if echo "$output" | grep -q "System is not deployed via bootc"; then
|
||||
echo "ok status-outside-container: correctly reports non-bootc system"
|
||||
else
|
||||
echo "FAIL: unexpected output from bootc status:" >&2
|
||||
echo "$output" >&2
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user