Skip to content

fix(images): reduce container-base size by excluding locales and docs - #20008

Open
binujp wants to merge 1 commit into
4.0from
bphilip/resize-base-minimal
Open

binujp wants to merge 1 commit into
4.0from
bphilip/resize-base-minimal

Conversation

@binujp

@binujp binujp commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Trim the container-base image by excluding non-English RPM locale data and RPM documentation, while retaining licenses and normal runtime package management.

  • Package the temporary language-selection macro in azurelinux-release-locale-minimal, selected only during the core bootstrap.
  • Reinstall bootstrap RPMs in a post-bootstrap hook so RPM applies the language policy and records excluded payloads correctly.
  • Erase the temporary policy RPM directly from config.sh before shipping, allowing subsequent package installations to select their normal locale payloads.
  • Enable rpm-excludedocs only for core and add artifact checks for locale filtering, policy removal, documentation exclusion, and license preservation.

Why the post-bootstrap hook is necessary

KIWI's host-side bootstrap package transaction does not honor RPM macro overrides installed inside the build chroot. Installing the policy RPM alone therefore cannot filter the initial bootstrap payloads. The post-bootstrap script reinstalls those packages inside the target chroot, where the packaged language policy is active.

Other image profiles do not demand this level of intervention. Even distroless-minimal primarily focuses on package minimization rather than minimizing image size itself. Focusing this change on container-base lets us be judicious about the number of build exceptions we introduce; the other images retain their existing behavior.

Size and validation

The size reduction is approximately 10 MB, with the rebuilt compressed x86_64 OCI archive now 32.05 MB (about 32 MB, or 30.57 MiB).

Rebuilt container-base on x86_64 and checked the new artifact:

  • Static checks: 55 passed, 36 skipped, including the minimal RPM documentation-exclusion test, which verifies that Bash's README is absent while its license remains.
  • Selected runtime checks: 4 passed, covering shell access, localhost resolution, production package installation, and explicit non-persistent Preview repository opt-in.

Attribution

Based on the original work by Kshitiz Godara (kgodara912) in #19837: #19837.

@binujp
binujp requested a review from a team as a code owner November 5, 2026 22:10
Copilot AI balanced review requested due to automatic review settings November 5, 2026 22:10
@binujp

binujp commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
2 pipeline(s) were filtered out due to trigger conditions.

@binujp

binujp commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
2 pipeline(s) were filtered out due to trigger conditions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues remain for the container image locale-filtering and documentation-exclusion changes.

No open issues 🎉

What changed in this PR

Reduces container-base image size by filtering non-English locale payloads and excluding RPM documentation, while preserving licenses and normal runtime package management. Other image profiles retain their existing behavior.

Changes:

  • Adds a temporary language-policy RPM and reinstalls bootstrap packages inside the image to apply it.
  • Enables documentation exclusion for the core profile and removes the language-policy RPM before shipping.
  • Adds artifact checks for locale filtering, policy removal, documentation exclusion, and license preservation.
File Description
specs/​a/​azurelinux-release/​macros.container-languages Adds the rendered RPM language policy.
specs/​a/​azurelinux-release/​azurelinux-release.spec Reflects the new policy subpackage and release bump.
locks/​azurelinux-release.lock Refreshes the component input fingerprint.
base/​images/​tests/​cases/​static/​test_container_languages.py Checks filtered payloads, policy removal, and retained licenses.
base/​images/​teams/​container.xml Selects the bootstrap policy and enables documentation exclusion for core.
base/​images/​post_bootstrap.sh Reinstalls bootstrap packages under the target’s language policy.
base/​images/​config.sh Removes the temporary policy RPM before shipping.
base/​comps/​azurelinux-release/​macros.container-languages Defines the allowed RPM language payloads.
base/​comps/​azurelinux-release/​azurelinux-release.spec Packages and validates the temporary language policy.

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 22:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues remain for the container image locale and documentation filtering changes.

No open issues 🎉

Review effort: Balanced

@@ -27,6 +27,7 @@
<packagemanager>dnf5</packagemanager>
</preferences>
<preferences profiles="core">

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

question(blocking): Can you help me understand why we can't just use rpm-locale-filtering?

Based on this code in kiwi, it looks like that always includes the POSIX, C, C.UTF-8, and then unions in anything listed in the locale setting:

https://github.com/OSInside/kiwi/blob/f26db086eaa5ee77b26e3edd0363f8b77af8dff1/kiwi/xml_state.py#L282-L302

if self.get_rpm_locale_filtering():
    rpm_locale = ['POSIX', 'C', 'C.UTF-8']

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We could; but that works only in the image build phase. We still need the post-bootstrap script to reinstall bootstrap rpms to be locale filtered. With a custom rpm we get flexibility to add other customizations in the future. I will make that change, but we do not get a script less bootstrap phase.

<packagemanager>dnf5</packagemanager>
</preferences>
<preferences profiles="core">
<rpm-excludedocs>true</rpm-excludedocs>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

question(blocking): Don't we want this to apply to the distroless containers?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Two reasons; from the bug my understanding is the container size concern is focused on the core container. Distroless containers do not have the option of reinstalling rpms and thus pulling in locales or docs later. Whatever is already installed is what is available for all workloads. If the focus is on minimizing size of all containers, we can do that. For that, I would rather work on a separate PR.

Use KIWI's native RPM locale filtering for container-base and reinstall bootstrap packages inside the target chroot so filtering applies to their payloads. Let KIWI clean up its temporary RPM macro instead of shipping a custom policy RPM.

Exclude documentation only for core and verify locale filtering, build-time policy cleanup, and license retention.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c5603870-57b3-4c21-9eb9-62b600c146af
@binujp
binujp force-pushed the bphilip/resize-base-minimal branch from 0fa5a70 to 048db62 Compare November 6, 2026 07:03
Copilot AI balanced review requested due to automatic review settings November 6, 2026 07:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The KIWI/DNF5 bootstrap reinstall and history check need artifact/runtime validation unavailable here, while supplied results cover a different policy mechanism and omit the supported aarch64 image.

No open issues 🎉

Review effort: Balanced

def test_bootstrap_language_macro_absent(rootfs: Path) -> None:
"""Do not ship the build-time RPM language override."""
assert not (rootfs / "etc/rpm/macros.kiwi-image-config").exists()
assert not (rootfs / "etc/rpm/macros.container-languages").exists()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

question(non-blocking): Is this still required?


def test_bootstrap_language_macro_absent(rootfs: Path) -> None:
"""Do not ship the build-time RPM language override."""
assert not (rootfs / "etc/rpm/macros.kiwi-image-config").exists()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

question(non-blocking): copilot seems to think that the config is created under /usr/lib/rpm/ somewhere; I'm not sure offhand but I figured I'd pass along the note.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants