Skip to content

cli: Make loader-entries unavailable when ostree lacks bootconfig-extra - #2485

Merged
cgwalters merged 1 commit into
bootc-dev:mainfrom
jmarrero:gate-ostree
Sep 23, 2026
Merged

cgwalters merged 1 commit into
bootc-dev:mainfrom
jmarrero:gate-ostree

Conversation

@jmarrero

@jmarrero jmarrero commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

bootc loader-entries set-options-for-source only works with libostree >= 2026.1, which added the bootconfig-extra serialization that carries x-options-source-* keys through a staged deployment. Until now the subcommand was advertised in bootc --help on every host and only failed at runtime.

That matters for TuneD: its bootc integration probes for the feature by running bootc loader-entries set-options-for-source --help and checking the exit status, and only falls back to its rpm-ostree/GRUB2 path when that fails (see redhat-performance/tuned#827). Merely hiding the subcommand from help would not be enough, since a hidden clap subcommand still answers --help with exit status 0.

So detect the feature via ostree_check_version() at runtime and, when it is missing, make the subcommand unavailable: hide it from --help, disable --help on it and its children so a probe fails, and reject an actual invocation after parsing with an error naming the required ostree version.

The gate is applied only at argument-parsing time, not in Opt::command(), so the man page sync (dump-cli-json) and bootc completion keep describing the full CLI regardless of the ostree version of the host that built the package.

Testing

Built the RPM against CentOS Stream 9 and ran TuneD 2.28.0 (with redhat-performance/tuned#892) on two bcvk VMs:

  • RHEL 9.8 bootc, ostree 2025.7 (no bootconfig-extra): loader-entries is absent from bootc --help, the probe exits 2 and a direct invocation is rejected. tuned-adm profile with a [bootloader] cmdline= went through rpm-ostree (Initiated txn KernelArgs for client(… unit:tuned.service)), no bootc lines in the TuneD log; the kargs are on the cmdline after reboot, a profile switch removes them via rpm-ostree, and bootc rollback back into the tuned deployment restores them.
  • CentOS Stream 9, ostree 2026.4: subcommand listed, probe exits 0, TuneD takes the bootc path; after reboot the kargs and the x-options-source-tuned key are in the booted BLS entry.

Unit test cli::tests::test_host_feature_gates covers the gate.

Assisted-by: AI
I am knowledgeable in this problem domain and tested the change on both ostree versions as described above.

@github-actions github-actions Bot added the area/documentation Updates to the documentation label Sep 21, 2026
@bootc-bot
bootc-bot Bot requested a review from cgwalters September 21, 2026 23:15
cgwalters
cgwalters previously approved these changes Sep 22, 2026

@cgwalters cgwalters left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is OK, but what we really want in the future is a varlink api for stuff like this.

Comment thread crates/lib/src/cli.rs Outdated
fn check_host_feature_gates(opt: &Opt, bootconfig_extra: bool) -> Result<(), clap::Error> {
if matches!(opt, Opt::LoaderEntries(_)) && !bootconfig_extra {
let err = crate::loader_entries::unsupported_ostree_error();
return Err(Opt::command().error(clap::error::ErrorKind::InvalidSubcommand, err));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to allow a caller to distinguish "some other error" from "operation not supported" I think we could return an exit code of 77 or so which has some precendent for "skipped".

…xtra

`bootc loader-entries set-options-for-source` only works with
libostree >= 2026.1, which added the `bootconfig-extra` serialization
that carries `x-options-source-*` keys through a staged deployment.
Until now the subcommand was advertised in `bootc --help` on every
host and only failed at runtime.

That matters for TuneD: its bootc integration probes for the feature
by running `bootc loader-entries set-options-for-source --help` and
checking the exit status, and only falls back to its rpm-ostree/GRUB2
path when that fails. See
<redhat-performance/tuned#827>. Merely hiding
the subcommand from help would not be enough, since a hidden clap
subcommand still answers `--help` with exit status 0.

So detect the feature via `ostree_check_version()` at runtime and, when
it is missing, make the subcommand unavailable: hide it from `--help`
and reject any invocation of it before parsing, `--help` included, with
an error naming the required ostree version.  That rejection exits with
status 77 (the "skipped" convention) rather than clap's usage-error 2,
so a caller can tell "not supported on this host" from a mistake.

The gate is applied only at argument-parsing time, not in
`Opt::command()`. That keeps the man page sync (`dump-cli-json`) and
`bootc completion` (run by the Makefile at package build time)
describing the full CLI, so generated docs and completions don't
change depending on the ostree version of whichever host built them.

Assisted-by: AI

Signed-off-by: Joseph Marrero Corchado <jmarrero@redhat.com>
@jmarrero
jmarrero marked this pull request as ready for review September 22, 2026 15:27
@bootc-bot
bootc-bot Bot requested a review from cgwalters September 22, 2026 15:27
@cgwalters
cgwalters enabled auto-merge (rebase) September 22, 2026 19:07
@cgwalters
cgwalters merged commit ae375f9 into bootc-dev:main Sep 23, 2026
179 of 186 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/documentation Updates to the documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants