Skip to content

frontend: prefer dnf over tdnf to work around tdnf GPG and forcearch limitations#991

Open
cpuguy83 wants to merge 2 commits intoproject-dalec:mainfrom
cpuguy83:fix_signing_with_base_img
Open

frontend: prefer dnf over tdnf to work around tdnf GPG and forcearch limitations#991
cpuguy83 wants to merge 2 commits intoproject-dalec:mainfrom
cpuguy83:fix_signing_with_base_img

Conversation

@cpuguy83
Copy link
Collaborator

@cpuguy83 cpuguy83 commented Mar 11, 2026

tdnf fails when installing signed local RPMs (from the cmdline virtual repo) into an installroot with a populated RPM database, because it requires a gpgkey entry for cmdline which is a synthetic repo with no config. This manifests when building containers with a custom base image on azlinux/mariner distros.

Rather than working around individual tdnf bugs, prefer dnf when it is available. The install script now checks for dnf at runtime and switches from tdnf transparently. The same-platform worker bootstrap is updated to install dnf as a separate first step (mirroring the cross-arch path) so that subsequent installs benefit from dnf.

This also exposed a couple of other issues:

  1. We weren't testing depsonly anywhere except in the basic "e2e" tests in docker-bake.hcl which is just a holdover from before we had integration tests. I've migrated the tests there and made it run on all distros that support this target (rpm distros only).
  2. Instead of manually pulling in all packages into a dir (and incurring extra copying), just pass the list of packages to install to a new method for handling this scenario.

This fixes a real issue we saw in our builds where azlinux3/container is used but a custom base image is set instead of building one from scratch (as is the default).

@cpuguy83 cpuguy83 force-pushed the fix_signing_with_base_img branch from d465f16 to 97c0856 Compare March 11, 2026 23:25
…limitations

tdnf fails when installing signed local RPMs (from the cmdline virtual
repo) into an installroot with a populated RPM database, because it
requires a gpgkey entry for cmdline which is a synthetic repo with no
config. This manifests when building containers with a custom base image
on azlinux/mariner distros.

Rather than working around individual tdnf bugs, prefer dnf when it is
available. The install script now checks for dnf at runtime and switches
from tdnf transparently. The same-platform worker bootstrap is updated
to install dnf as a separate first step (mirroring the cross-arch path)
so that subsequent installs benefit from dnf.

Also remove hardcoded GPG email from test key ID lookups in favor of
selecting the first available key.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
@cpuguy83 cpuguy83 force-pushed the fix_signing_with_base_img branch from 97c0856 to 08fb0cd Compare March 12, 2026 00:27
@cpuguy83 cpuguy83 marked this pull request as ready for review March 12, 2026 00:30
Copilot AI review requested due to automatic review settings March 12, 2026 00:30
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR expands RPM-based distro support for a “deps-only” container target, adjusts RPM install behavior to prefer dnf over tdnf when available, and adds coverage for a signed-RPM install edge case when using a custom base image.

Changes:

  • Add container/depsonly target plumbing to the RPM distro implementation and exercise it in integration tests.
  • Prefer dnf over tdnf at install time when dnf is present (and bootstrap dnf earlier in worker creation).
  • Add a signing-focused regression test that signs built RPMs and validates container builds with a custom base image.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/target_ubuntu_test.go Updates GPG key ID extraction used when signing an APT repo in tests.
test/target_rockylinux_test.go Adds deps-only target config and an extra signing regression test invocation.
test/target_azlinux_test.go Adds deps-only target config, switches repo signing hook used by tests, and runs the signing regression test with a custom base image.
test/target_almalinux_test.go Adds deps-only target config and an extra signing regression test invocation.
test/signing_test.go Introduces RPM signing helper + regression test for installing signed RPMs into a custom base image.
test/linux_target_test.go Adds DepsOnly to targetConfig and adds deps-only integration tests validating runtime deps-only behavior.
targets/linux/rpm/distro/worker.go Bootstraps dnf earlier (when needed) and introduces slices usage.
targets/linux/rpm/distro/dnf_install.go Removes unused download-only options and prefers dnf over tdnf automatically when dnf exists.
targets/linux/rpm/distro/container.go Adds BuildContainerWithPackages and updates deps-only handler to install package names rather than local RPMs.
docker-bake.hcl Removes the bake-based deps-only test target from the test group.

if samePlatform(targetPlat, buildPlat) {
if slices.Contains(cfg.BuilderPackages, "dnf") {
// Install dnf first since this will be bootstrapped with a different package manager
// This keeps the package cache for the bootstrap mananager separate from the other base packages we use.
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

Typo in comment: "bootstrap mananager" should be "bootstrap manager".

Suggested change
// This keeps the package cache for the bootstrap mananager separate from the other base packages we use.
// This keeps the package cache for the bootstrap manager separate from the other base packages we use.

Copilot uses AI. Check for mistakes.
Comment on lines +677 to +679
// This triggers skipBase=true in BuildContainer, meaning the RPMs
// are installed via "tdnf install /path/to/signed.rpm --installroot=/tmp/rootfs"
// into the custom base image's rootfs.
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

These comments describe the install path specifically as tdnf install ..., but this helper is also called from dnf-based distros (e.g., AlmaLinux/Rocky). Consider rewording to describe the generic local-RPM install path (package manager varies) or constrain the helper to tdnf-based distros only.

Suggested change
// This triggers skipBase=true in BuildContainer, meaning the RPMs
// are installed via "tdnf install /path/to/signed.rpm --installroot=/tmp/rootfs"
// into the custom base image's rootfs.
// This triggers skipBase=true in BuildContainer, meaning the RPMs are
// installed from the local filesystem into the custom base image's
// rootfs using the target distro's package manager (for example,
// tdnf or dnf with an appropriate --installroot).

Copilot uses AI. Check for mistakes.
@cpuguy83 cpuguy83 force-pushed the fix_signing_with_base_img branch from 08fb0cd to c590d2d Compare March 12, 2026 17:24
The way depsonly worked was always a bit janky and didn't actually
support the full dependency constraint specification.
Additionally I found the shift to dnf from tdnf broke due to `--alldeps`
being missing (possibly just in mariner2, but still missing).

This shifts depsonly to use BuildPkg and BuildContainer where we create
a meta package with just the runtime deps.
Because depsonly allows specifying a partial spec (ie missing things
like name, license, other normally required fields) we have to fill in
those details so rpmbuild can succeed.

Add deps-only integration tests for all RPM distros with two sub-tests:
- minimal spec: only runtime deps, verifies curl is installed
- full spec: includes sources, build steps, and a shell script artifact;
  verifies runtime deps are installed and build artifacts are excluded
- replaces the "e2e" test in docker-bake.hcl and tets all relevant
  distros

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
@cpuguy83 cpuguy83 force-pushed the fix_signing_with_base_img branch from c590d2d to 0a95d13 Compare March 12, 2026 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants