diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8860f5b7..9815a986 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,11 @@ jobs: - uses: actions/checkout@v4 - name: build run: sudo podman build -t localhost/bootupd:latest -f ci/Containerfile.c9s . + - name: bootupctl status in container + run: | + set -xeuo pipefail + output=$(sudo podman run --rm -ti localhost/bootupd:latest bootupctl status | tr -d '\r') + [ "Available components: BIOS EFI" == "${output}" ] - name: bootc install to disk run: | set -xeuo pipefail diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index ab86f9f8..574180da 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -100,6 +100,9 @@ impl CtlCommand { /// Runner for `status` verb. fn run_status(opts: StatusOpts) -> Result<()> { + if crate::util::running_in_container() { + return run_status_in_container(); + } ensure_running_in_systemd()?; let r = bootupd::status()?; if opts.json { @@ -171,3 +174,14 @@ fn ensure_running_in_systemd() -> Result<()> { } Ok(()) } + +/// If running in container, just print the available payloads +fn run_status_in_container() -> Result<()> { + let all_components = crate::bootupd::get_components(); + if all_components.is_empty() { + return Ok(()); + } + let avail: Vec<_> = all_components.keys().cloned().collect(); + println!("Available components: {}", avail.join(" ")); + Ok(()) +} diff --git a/src/util.rs b/src/util.rs index 0635ef41..f03a395b 100644 --- a/src/util.rs +++ b/src/util.rs @@ -96,3 +96,22 @@ pub(crate) fn cmd_output(cmd: &mut Command) -> Result { String::from_utf8(result.stdout) .with_context(|| format!("decoding as UTF-8 output of `{:#?}`", cmd)) } + +/// Copy from https://github.com/containers/bootc/blob/main/ostree-ext/src/container_utils.rs#L20 +/// Attempts to detect if the current process is running inside a container. +/// This looks for the `container` environment variable or the presence +/// of Docker or podman's more generic `/run/.containerenv`. +/// This is a best-effort function, as there is not a 100% reliable way +/// to determine this. +pub fn running_in_container() -> bool { + if std::env::var_os("container").is_some() { + return true; + } + // https://stackoverflow.com/questions/20010199/how-to-determine-if-a-process-runs-inside-lxc-docker + for p in ["/run/.containerenv", "/.dockerenv"] { + if Path::new(p).exists() { + return true; + } + } + false +}