Add `get_lockfile_dir()` helper function that looks for lockfiles in
`lockfiles/${stream}/` first, then falls back to the srcdir root.
This allows rhel-coreos-config to maintain lockfiles per stream in main
branch instead of having separate branches.
The `get_locked_nevras()` function now accepts a `stream` parameter
and uses the new helper to determine the lockfile directory.
The previous code used tuple unpacking `(x, y, _) = version.split('.', 2)`
which requires exactly 3 elements. This fails for RHCOS versions like
`10.2` or `9.8` which only have 2 components, causing:
ValueError: not enough values to unpack (expected 3, got 2)
Use a more robust approach that handles versions with any number of
components.
In hermetic builds, `secret.repo` must be removed so that only the
hermetic repo (`cachi2.repo`/`hermeto.repo`) is used. Previously, the
secret was mounted directly to `/etc/yum.repos.d/secret.repo`, but
buildah secret mounts are read-only and cannot be removed with
`unlink()`, causing builds to fail with "Device or resource busy".
Mount the secret to `/run/secrets/yumrepos` instead and copy it to
`/etc/yum.repos.d/secret.repo` only in non-hermetic mode. This allows
hermetic builds to have full control over which repos are active.
Konflux exposes ADDITIONAL_SECRET files using IDs in the form
<secret-name>/<filename>. Prefix the yumrepos and contentsets secret
IDs with container-image-build and update build-rootfs to use the
corresponding contentsets path.
ref: https://github.com/coreos/rhel-coreos-config/issues/307
This was moved here in a26053a but as pointed out in [1]
the function isn't called anywhere. Let's add the function call
and also delete the current contents of the buildroot-prep
script since they clearly weren't being used (not needed any longer).
Previously, we didn't add the `fedora-coreos-pool` repo when building
hermetically but it is required since the merge of [1] which
privileges this repo when crafting the RPM URLs.
Note that we don't need to modify the pool repo in hermetic mode as
it is handled by Hermeto i.e. in cachi2.repo.
[1] https://github.com/coreos/coreos-assembler/pull/4600
This allows the final directory name of the overlay dir
to determine the ordering the overlays are applied in.
A file in 03-core/etc/foo.d/file would override a file
in 02-core/etc/foo.d/file.
Here's how that ends of looking when building against
rhel-9.8 CoreOS (i.e. https://github.com/coreos/rhel-coreos-config/pull/276)
```
--add-dir=/src/fedora-coreos-config/overlay.d/05core
--add-dir=/src/overlay.d/05rhcos
--add-dir=/src/overlay.d/06gcp-routes
--add-dir=/src/fedora-coreos-config/overlay.d/08nouveau
--add-dir=/src/overlay.d/15rhcos-journald-backcompat
--add-dir=/src/overlay.d/15rhcos-networkmanager-dispatcher
--add-dir=/src/overlay.d/15rhcos-networkmanager-plugin-order
--add-dir=/src/overlay.d/15rhcos-tuned-bits
--add-dir=/src/fedora-coreos-config/overlay.d/20platform-chrony
--add-dir=/src/overlay.d/21dhcp-chrony
--add-dir=/src/overlay.d/30gcp-udev-rules
--add-dir=/src/fedora-coreos-config/overlay.d/30lvmdevices
--add-dir=/src/overlay.d/30rhcos-nvme-compat-udev
--add-dir=/src/fedora-coreos-config/overlay.d/40import-virtiofs-systemd-credentials
```
Previously ostree-layers entries strings had to start with '/overlay'
and it was hardcoded to look into the overlay.d/ directory for them.
Rather than this let's just have the strings in the list be the actual
directory the override resides in.
Also here we rename a bunch of variables in build-rootfs to be add_dirs
instead of overlays, because the argument to bootc-base-imagectl is
--add-dir.
Make the comment at the top more accurate and add some debug logs
for the arguemnts in the args file that are passed in so we can see
what's happening under the hood during a build.
bootc-image-builder needs a disk partition table definition at
/usr/lib/image-builder/bootc/disk.yaml to produce disk images. Each
architecture has a different partition layout (e.g. BIOS boot on x86_64,
PReP on ppc64le, no boot partition on s390x), so the correct file must
be selected at build time.
This follows the same injection pattern already used for platforms.json
and image.json: build-rootfs links the correct partitioncorrect partition
table from the disk-image overlay.
Authored-by: Opencode.ai claude-opus-4-6@default
Injects some of the build-args as environnement variables into the
postprocess bwrap.
This will allow postprocess scripts to reuse these
values and make arbitrary changes based on it.
We explicitely only re-inject spicifc hand-picked variables instead of
forwarding the whole environnement to avoid unwanted side-effects.
See discussion on https://github.com/coreos/fedora-coreos-config/pull/4173
for context.
Assisted-by: Opencode.ai <Opus 4.6>
Move the buildroot-prep invocation from Containerfile into build-rootfs
as a new run_buildroot_prep() function. This runs after inject_yumrepos()
so that repos are available when buildroot-prep executes.
Also remove the cachi2 repo check from buildroot-prep since repo injection
is now handled earlier in the build process by inject_yumrepos().
Signed-off-by: Joel Capitao <jcapitao@redhat.com>
Assisted-by: Claude (Opus 4)
get_treefile() crashes when parsing versions with fewer than 3
components (e.g., "44"). Now we pad the version parts list with
"0" to ensure we always have at least 3 elements.
As a follow-up of e6d3ed2.
Basically we need to support setting it to:
- fedora-43
- centos-9
- rhel-9.8
So we need to include the minor in one case but not hte other two.
Let's add some conditional logic here for that.
I found issues where this was conflicting at times with the built-in
function id in module builtins.
Let's just rename to decrease chance of conflicts.
Now you can source in the build-args.conf and print the treefile
to stdout.
```
[coreos-assembler]$ source src/config/build-args.conf
bash: CoreOS: command not found
[coreos-assembler]$ export ID NAME STREAM VERSION MUTATE_OS_RELEASE MANIFEST PASSWD_GROUP_DIR IMAGE_CONFIG
[coreos-assembler]$ src/config/build-rootfs --srcdir src/config/ parse-treefile
{"packages": ["/usr/bin/kdumpctl", "/usr/share/makedumpfile", "NetworkManager-cloud-setup",
```
This removes SRCDIR from being a global/constant into a --srcdir
parameter to allow for execution of build-rootfs outside of
the Containerfile where things have been copied into /src/.
The default is still set to /src/ if the --srcdir paramter isn't
provided.
Assisted-By: <google/gemini-3-pro-preview>
This adds a `build-rootfs make-rootfs` subcommand that has the
same behavior as the original intention of the script. This is
prep for adding more subcommands.
At this point it just pulls the first field off the version string
which should be good enough. Only Fedora uses $releasever in yum repos
and the major version number works there.
These bits of information are used in various places. I thought
previously that `BASE_VERSION` would suffice and we'd be able to
use that fore mutating the os-release file, but it turns out it's not
a 1:1 relationship there. For example:
For Fedora 43 the BASE_VERSION is 43 and the string we need to find
and replace for VERSION and PRETTY_NAME in os-release is 43. For CentOS
Stream 9 the string we need to find/replace is `9`, but for RHEL 9.8
it's `9.8`. But this is complicated by the fact that we want our version
for c9s and c10s to be X.0 (i.e. 9.0, 10.0).
Here we drop BASE_VERSION (we can just use `VERSION` for what we need
in versionary) and introduce MUTATE_OS_RELEASE just for the string
to find and replace with the actual version.
These are all defined in env vars so let's just pick them up from
there rather than trying to explicitly add them to the CLI each time
we add a new argument.
When using subprocess in Python, spaces in the queryformat string can be
misinterpreted due to shell argument parsing. Switch to comma-separated
format without spaces to avoid parsing issues.
Assisted-by: Claude (Opus 4)
Signed-off-by: Joel Capitao <jcapitao@redhat.com>
..and use it for variable replacement in the image.yaml files rather
than the manifest since stream is the only var we are formatting/replacing
right now.
This further removes our dependence on the manifest.
In hermetic builds there is no access to the network. Detect this by
looking for the `cachi2.repo` that is injected by konflux during the
build.
In this case we make sure to not use any of our own repo and rely on
the repo created by hermeto.
This will make it easier to support downstream rhel-coreos-config
where we support building more than one variant from the main branch
and the image.yaml files are named per variant.
When verifying that the RPMs we locked on are what is in the built
container we ran into a corner case where if a RPM has explicitly
set their EPOCH to 0 then the NEVR from `rpm -q --qf` will include
that `0:`.
`rpm-ostree` just assumes any `0` EPOCH shouldn't be included
in the string [1] so it won't get written to the lockfile.
We need to account for this here.
We stumbled upon this by accident because perl was getting
included [2] when it shouldn't and it have subpackages that
set an EPOCH of `0`.
[1] 0ad2ee53f3/src/libpriv/rpmostree-rpm-util.cxx (L76-L84)
[2] https://github.com/coreos/fedora-coreos-tracker/issues/2059
Add the link target to the hash instead.
This broke the ostree builds with
`[2025-11-11T03:36:28.572Z] FileNotFoundError: [Errno 2] No such file or directory: '/src/overrides/rootfs/etc/grub.d/15_ostree'`
Signed-off-by: Colin Walters <walters@verbum.org>
This builds on the upstream changes [1][2] to support being able to build
the rootfs without generating the initramfs, which allows us to hook
in our own post-process scripts before then generating the initramfs
ourselves in build-rootfs.
The effect of this change is that our postprocess scripts can directly
impact the generated initramfs. Without this change we either needed
to implement hacks (like inject_dracut_version() and cleanup_dracut_version(),
which are deleted in this commit) OR run dracut twice (throwing away
the initial run as part of the `rpm-ostree compose rootfs`).
[1] 481fbb0342
[2] https://gitlab.com/fedora/bootc/base-images/-/merge_requests/320
This was being done at the bootc level but got changed in
https://gitlab.com/fedora/bootc/base-images/-/merge_requests/310
so we need to do it here again.
Do it in a postprocess because that's the way we can do it in a
container build (i.e. where `remove-from-packages:` isn't supported).
We also unfortunately need a SUPER HACK rip this out of the initramfs
build when dracut runs. Unfortunately in the build-with-buildah path
today our postprocess scripts here are only run *after* dracut has
run and so they won't affect the initramfs. I'm hoping this is
very temporary because we really need a better answer for this.
Right now, there is no change detection in our builds. We just always do
a new build, which is wasteful.
Let's re-implement a concept similar to rpm-ostree's inputhash, which
just hashes all the relevant inputs. We then add a label to the final
image with that input. On the cosa side, we can compare the hash to the
previous build to know if to no-op.
One major difference from rpm-ostree's inputhash is that it could know
the hash right after doing the depsolve (to have the final list of RPMs)
and thus avoid a full build. It's possible to do this here too though
it'd require bootc-base-imagectl and rpm-ostree changes. We'd need to
also define an API for having a `podman build` actually signal "no-op";
e.g. writing a file in the build context and erroring the build...
awkward.
Much more interesting and related to this is reproducible builds;
if our builds were reproducible, we wouldn't have to worry about
this because we'd just build the exact same artifact everytime.
There's some work required to get there though, and likely we'd
have to rework how we calculate our versions, since that's a dynamic
value which affects the rootfs and OCI labels (e.g. always have
the same version for the set of inputs; see also discussions in
https://github.com/coreos/fedora-coreos-tracker/issues/2015).
In the legacy path, rpm-ostree handles `mutate-os-release` before
calling dracut. So the initrd-release in the initramfs (built from
os-release) contains the updated values.
In the buildah path, we handle version mutation after the rpm-ostree
compose done by bootc-base-imagectl and so the initrd doesn't have the
updated values.
I find that versioning information in the initrd useful because systemd
will print it out on the console (the "Welcome to ..." string), and a
lot of our bug reports are from failures in the initramfs.
So this patch restores this information for the buildah path, but does
it in a subtle way to avoid having to regenerate the initramfs just
for that: we create a temporary dracut module and then delete it in
postprocessing.