From 6f52311f70e88de40c3275c6956f26ee724b2020 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 21 Feb 2025 18:12:56 -0500 Subject: [PATCH 01/10] ci: Bump to latest buildah The platform-engineering include is using a truly ancient buildah image. Stop including that and bump to the latest. Signed-off-by: Colin Walters --- .gitlab-ci.yml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 08c0ffe..cb0af33 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,24 @@ --- -include: - - remote: https://gitlab.com/platform-engineering-org/gitlab-ci/-/raw/main/templates/build-image.gitlab-ci.yml +stages: + - build + +variables: + IMAGE: ${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHA} + CONTAINERFILE: Containerfile + CONTEXT: . + EXTRA_ARGS: "" + +.build-image: + stage: build + image: quay.io/buildah/stable:v1.38.0 + needs: [] + script: buildah bud -f ${CONTAINERFILE} --no-cache -t ${IMAGE} ${EXTRA_ARGS} ${CONTEXT} + rules: + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" + when: never + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS + when: never build-image: extends: .build-image From d1a21ed1593efa8f4896ebaecfb56c669b857d04 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 20 Feb 2025 16:57:08 -0500 Subject: [PATCH 02/10] tier-0: Rename to minimal The "tiers" nomenclature ended up being unhelpful since we introduced "tier-x" which is between tier-0 and tier-1. We also never exposed the tier naming outside of our source code. In preparation for doing so, rename to tier-0 to "minimal" which is a bit more descriptive. Renaming the other images will follow. Signed-off-by: Colin Walters --- .gitlab-ci.yml | 2 +- README.md | 11 +++++------ fedora-tier-0.yaml => fedora-minimal.yaml | 4 ++-- {tier-0 => minimal}/basic-fixes.yaml | 0 {tier-0 => minimal}/bootc.yaml | 0 {tier-0 => minimal}/bootupd.yaml | 0 {tier-0 => minimal}/finalize.d/01-var.sh | 0 {tier-0 => minimal}/group | 0 {tier-0 => minimal}/grub2-removals.yaml | 0 {tier-0 => minimal}/initramfs.yaml | 0 {tier-0 => minimal}/kernel-install.yaml | 0 {tier-0 => minimal}/kernel.yaml | 0 {tier-0 => minimal}/manifest.yaml | 2 +- {tier-0 => minimal}/ostree.yaml | 0 {tier-0 => minimal}/passwd | 0 {tier-0 => minimal}/postprocess-conf.yaml | 2 +- {tier-0 => minimal}/tmpfiles.yaml | 0 tier-x/manifest.yaml | 2 +- 18 files changed, 11 insertions(+), 12 deletions(-) rename fedora-tier-0.yaml => fedora-minimal.yaml (67%) rename {tier-0 => minimal}/basic-fixes.yaml (100%) rename {tier-0 => minimal}/bootc.yaml (100%) rename {tier-0 => minimal}/bootupd.yaml (100%) rename {tier-0 => minimal}/finalize.d/01-var.sh (100%) rename {tier-0 => minimal}/group (100%) rename {tier-0 => minimal}/grub2-removals.yaml (100%) rename {tier-0 => minimal}/initramfs.yaml (100%) rename {tier-0 => minimal}/kernel-install.yaml (100%) rename {tier-0 => minimal}/kernel.yaml (100%) rename {tier-0 => minimal}/manifest.yaml (93%) rename {tier-0 => minimal}/ostree.yaml (100%) rename {tier-0 => minimal}/passwd (100%) rename {tier-0 => minimal}/postprocess-conf.yaml (91%) rename {tier-0 => minimal}/tmpfiles.yaml (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cb0af33..4315f08 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,7 @@ build-image: extends: .build-image parallel: matrix: - - TIER: [tier-0, tier-1, tier-x] + - TIER: [minimal, tier-1, tier-x] variables: EXTRA_ARGS: "--security-opt=label=disable --cap-add=all --build-arg MANIFEST=fedora-$TIER.yaml" rules: diff --git a/README.md b/README.md index c4ddc9f..4d82095 100644 --- a/README.md +++ b/README.md @@ -60,19 +60,18 @@ to support smaller custom images. For more on this, see - **tier-1**: This image is the default, what is published as https://quay.io/repository/fedora/fedora-bootc -- **tier-0**: This content set is more of a convenient centralization point for CI - and curation around a package set that we can all agree is the rough minimum - necessary for a usable system. It's not meant to be used as is, but layered - upon. +- **minimal**: This content set is more of a convenient centralization point for CI + and curation around a package set that is intended as a starting point fror + a container base image. - **tier-x**: This content set is the shared base used by all image-based Fedora variants (IoT, Atomic Desktops, and CoreOS). Changes to this tier may be done without accounting for external users. To build this, pass `--build-arg=MANIFEST=fedora-tier-x.yaml` to the build command above. -**tier-1** inherits from **tier-x** and **tier-x** in turn inherit from **tier-0**. +**tier-1** inherits from **tier-x** and **tier-x** in turn inherit from **minimal**. -All non-trivial changes to **tier-0** and **tier-x** should be ACKed by at least +All non-trivial changes to **minimal** and **tier-x** should be ACKed by at least one stakeholder of each Fedora variant WGs. ## More information diff --git a/fedora-tier-0.yaml b/fedora-minimal.yaml similarity index 67% rename from fedora-tier-0.yaml rename to fedora-minimal.yaml index 6cef2a1..77cd0e2 100644 --- a/fedora-tier-0.yaml +++ b/fedora-minimal.yaml @@ -4,5 +4,5 @@ metadata: include: - fedora-generic.yaml - - tier-0/manifest.yaml - - tier-0/kernel.yaml + - minimal/manifest.yaml + - minimal/kernel.yaml diff --git a/tier-0/basic-fixes.yaml b/minimal/basic-fixes.yaml similarity index 100% rename from tier-0/basic-fixes.yaml rename to minimal/basic-fixes.yaml diff --git a/tier-0/bootc.yaml b/minimal/bootc.yaml similarity index 100% rename from tier-0/bootc.yaml rename to minimal/bootc.yaml diff --git a/tier-0/bootupd.yaml b/minimal/bootupd.yaml similarity index 100% rename from tier-0/bootupd.yaml rename to minimal/bootupd.yaml diff --git a/tier-0/finalize.d/01-var.sh b/minimal/finalize.d/01-var.sh similarity index 100% rename from tier-0/finalize.d/01-var.sh rename to minimal/finalize.d/01-var.sh diff --git a/tier-0/group b/minimal/group similarity index 100% rename from tier-0/group rename to minimal/group diff --git a/tier-0/grub2-removals.yaml b/minimal/grub2-removals.yaml similarity index 100% rename from tier-0/grub2-removals.yaml rename to minimal/grub2-removals.yaml diff --git a/tier-0/initramfs.yaml b/minimal/initramfs.yaml similarity index 100% rename from tier-0/initramfs.yaml rename to minimal/initramfs.yaml diff --git a/tier-0/kernel-install.yaml b/minimal/kernel-install.yaml similarity index 100% rename from tier-0/kernel-install.yaml rename to minimal/kernel-install.yaml diff --git a/tier-0/kernel.yaml b/minimal/kernel.yaml similarity index 100% rename from tier-0/kernel.yaml rename to minimal/kernel.yaml diff --git a/tier-0/manifest.yaml b/minimal/manifest.yaml similarity index 93% rename from tier-0/manifest.yaml rename to minimal/manifest.yaml index 5fd83e4..603c5fe 100644 --- a/tier-0/manifest.yaml +++ b/minimal/manifest.yaml @@ -31,7 +31,7 @@ packages: # in dnf5. In CentOS/RHEL, this pulls in dnf(4). We can simplify this back to # just `dnf` once the `dnf` package is retired from Fedora. - /usr/bin/dnf - # Even in tier-0, we have this. If you don't want SELinux today, you'll need + # Even in minimal, we have this. If you don't want SELinux today, you'll need # to build a custom image. - selinux-policy-targeted # And we want container-selinux because trying to layer it on later currently causes issues. diff --git a/tier-0/ostree.yaml b/minimal/ostree.yaml similarity index 100% rename from tier-0/ostree.yaml rename to minimal/ostree.yaml diff --git a/tier-0/passwd b/minimal/passwd similarity index 100% rename from tier-0/passwd rename to minimal/passwd diff --git a/tier-0/postprocess-conf.yaml b/minimal/postprocess-conf.yaml similarity index 91% rename from tier-0/postprocess-conf.yaml rename to minimal/postprocess-conf.yaml index 7356093..31ef9af 100644 --- a/tier-0/postprocess-conf.yaml +++ b/minimal/postprocess-conf.yaml @@ -7,7 +7,7 @@ opt-usrlocal: "root" machineid-compat: true # Note that the default for c9s+ is sqlite; we can't rely on rpm being -# in the target (it isn't in tier-0!) so turn this to host here. This +# in the target (it isn't in minimal!) so turn this to host here. This # does break the "hermetic build" aspect a bit. Maybe eventually # what we should do is special case this and actually install RPM temporarily # and then remove it... diff --git a/tier-0/tmpfiles.yaml b/minimal/tmpfiles.yaml similarity index 100% rename from tier-0/tmpfiles.yaml rename to minimal/tmpfiles.yaml diff --git a/tier-x/manifest.yaml b/tier-x/manifest.yaml index 2b2cf68..e5275d5 100644 --- a/tier-x/manifest.yaml +++ b/tier-x/manifest.yaml @@ -1,5 +1,5 @@ include: - - ../tier-0/manifest.yaml + - ../minimal/manifest.yaml packages: # Used by admins interactively From e77e3dd0aca1a9491bb8670e3b3dfe5ce6976343 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 21 Feb 2025 13:16:43 -0500 Subject: [PATCH 03/10] minimal: Require kernel.yaml We have a legacy of trying to support using e.g. kernel-rt. But it adds complexity in the inheritance because minimal/manifest.yaml isn't standalone, it also needs a kernel. As part of custom base images I want to simplify this. In order to use kernel-rt, we'll just say that you build a minimal base, and then swap to kernel-rt as a secondary step for now. Signed-off-by: Colin Walters --- fedora-bootc.yaml | 1 - fedora-minimal.yaml | 1 - fedora-tier-x.yaml | 1 - minimal/manifest.yaml | 1 + tier-1/kernel.yaml | 1 - tier-x/kernel.yaml | 1 - 6 files changed, 1 insertion(+), 5 deletions(-) delete mode 120000 tier-1/kernel.yaml delete mode 120000 tier-x/kernel.yaml diff --git a/fedora-bootc.yaml b/fedora-bootc.yaml index 68dc692..11763a0 100644 --- a/fedora-bootc.yaml +++ b/fedora-bootc.yaml @@ -5,4 +5,3 @@ metadata: include: - fedora-generic.yaml - tier-1/manifest.yaml - - tier-1/kernel.yaml diff --git a/fedora-minimal.yaml b/fedora-minimal.yaml index 77cd0e2..76762f6 100644 --- a/fedora-minimal.yaml +++ b/fedora-minimal.yaml @@ -5,4 +5,3 @@ metadata: include: - fedora-generic.yaml - minimal/manifest.yaml - - minimal/kernel.yaml diff --git a/fedora-tier-x.yaml b/fedora-tier-x.yaml index 90a96fd..f80d107 100644 --- a/fedora-tier-x.yaml +++ b/fedora-tier-x.yaml @@ -5,4 +5,3 @@ metadata: include: - fedora-generic.yaml - tier-x/manifest.yaml - - tier-x/kernel.yaml diff --git a/minimal/manifest.yaml b/minimal/manifest.yaml index 603c5fe..5efd94c 100644 --- a/minimal/manifest.yaml +++ b/minimal/manifest.yaml @@ -15,6 +15,7 @@ remove-from-packages: - [systemd-udev, /usr/lib/systemd/system-generators/systemd-gpt-auto-generator] include: + - kernel.yaml - postprocess-conf.yaml - tmpfiles.yaml - bootc.yaml diff --git a/tier-1/kernel.yaml b/tier-1/kernel.yaml deleted file mode 120000 index d6f64cc..0000000 --- a/tier-1/kernel.yaml +++ /dev/null @@ -1 +0,0 @@ -../tier-0/kernel.yaml \ No newline at end of file diff --git a/tier-x/kernel.yaml b/tier-x/kernel.yaml deleted file mode 120000 index d6f64cc..0000000 --- a/tier-x/kernel.yaml +++ /dev/null @@ -1 +0,0 @@ -../tier-0/kernel.yaml \ No newline at end of file From 3950d19bdc75427fc45abffbe78aaee8cb77883d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 21 Feb 2025 14:45:13 -0500 Subject: [PATCH 04/10] manifests: Add descriptions This is generally useful for the same reason dpkg/rpm packages have descriptions. But it's also specifically preparation for the base image builder having a list operation to show available configurations. Signed-off-by: Colin Walters --- minimal/manifest.yaml | 3 +++ tier-1/manifest.yaml | 6 ++++++ tier-x/manifest.yaml | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/minimal/manifest.yaml b/minimal/manifest.yaml index 5efd94c..2c4a62e 100644 --- a/minimal/manifest.yaml +++ b/minimal/manifest.yaml @@ -1,3 +1,6 @@ +metadata: + summary: Effectively just bootc, systemd, kernel, and dnf as a starting point. + edition: "2024" # Be minimal diff --git a/tier-1/manifest.yaml b/tier-1/manifest.yaml index c84117b..499d298 100644 --- a/tier-1/manifest.yaml +++ b/tier-1/manifest.yaml @@ -1,3 +1,9 @@ +metadata: + summary: | + A relatively full, but still generic base image. Roughly + similar to a headless server installation. Automatic updates + are on by default. + # Flip this back on, we're going to be a larger system recommends: true diff --git a/tier-x/manifest.yaml b/tier-x/manifest.yaml index e5275d5..0b5d0d3 100644 --- a/tier-x/manifest.yaml +++ b/tier-x/manifest.yaml @@ -1,3 +1,11 @@ +metadata: + summary: | + A relatively full, but still generic base image. Roughly + similar to a smaller Fedora CoreOS. Includes NetworkManager, + openssh, various CLI tools, etc. + + Automatic updates are not on by default. + include: - ../minimal/manifest.yaml From 11a09f4c76accf1d13ccab5e65ef4a4d95c5ee44 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 21 Feb 2025 14:55:37 -0500 Subject: [PATCH 05/10] Rename "tier-1" to "standard" Followup to the rename of "tier-0" to "minimal". The tiers nomenclature didn't end up working out. Signed-off-by: Colin Walters --- .gitlab-ci.yml | 2 +- README.md | 6 +++--- fedora-bootc.yaml | 2 +- fedora-tier-1.yaml => fedora-standard.yaml | 0 {tier-1 => standard}/autoupdates.yaml | 0 {tier-1 => standard}/bootc-generic-growpart | 0 {tier-1 => standard}/bootc-generic-growpart.service | 0 {tier-1 => standard}/coreos-user-experience.yaml | 0 {tier-1 => standard}/generic-growfs.yaml | 0 {tier-1 => standard}/initramfs-full.yaml | 4 ++-- {tier-1 => standard}/manifest.yaml | 0 {tier-1 => standard}/networking-tools.yaml | 0 {tier-1 => standard}/persistent-journal.yaml | 0 {tier-1 => standard}/system-configuration.yaml | 0 14 files changed, 7 insertions(+), 7 deletions(-) rename fedora-tier-1.yaml => fedora-standard.yaml (100%) rename {tier-1 => standard}/autoupdates.yaml (100%) rename {tier-1 => standard}/bootc-generic-growpart (100%) rename {tier-1 => standard}/bootc-generic-growpart.service (100%) rename {tier-1 => standard}/coreos-user-experience.yaml (100%) rename {tier-1 => standard}/generic-growfs.yaml (100%) rename {tier-1 => standard}/initramfs-full.yaml (54%) rename {tier-1 => standard}/manifest.yaml (100%) rename {tier-1 => standard}/networking-tools.yaml (100%) rename {tier-1 => standard}/persistent-journal.yaml (100%) rename {tier-1 => standard}/system-configuration.yaml (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4315f08..86919ef 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,7 @@ build-image: extends: .build-image parallel: matrix: - - TIER: [minimal, tier-1, tier-x] + - TIER: [minimal, standard, tier-x] variables: EXTRA_ARGS: "--security-opt=label=disable --cap-add=all --build-arg MANIFEST=fedora-$TIER.yaml" rules: diff --git a/README.md b/README.md index 4d82095..4c2d4bd 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ podman build --security-opt=label=disable --cap-add=all \ --device /dev/fuse -t localhost/fedora-bootc . ``` -See the `Containerfile` for more details. This builds the default `tier-1` image. +See the `Containerfile` for more details. This builds the default `standard` image. ## Fedora versions @@ -58,7 +58,7 @@ It is planned to rework and improve this in the future, especially to support smaller custom images. For more on this, see [this tracker issue](https://gitlab.com/fedora/bootc/tracker/-/issues/32). -- **tier-1**: This image is the default, what is published as +- **standard**: This image is the default, what is published as https://quay.io/repository/fedora/fedora-bootc - **minimal**: This content set is more of a convenient centralization point for CI and curation around a package set that is intended as a starting point fror @@ -69,7 +69,7 @@ to support smaller custom images. For more on this, see To build this, pass `--build-arg=MANIFEST=fedora-tier-x.yaml` to the build command above. -**tier-1** inherits from **tier-x** and **tier-x** in turn inherit from **minimal**. +**standard** inherits from **tier-x** and **tier-x** in turn inherit from **minimal**. All non-trivial changes to **minimal** and **tier-x** should be ACKed by at least one stakeholder of each Fedora variant WGs. diff --git a/fedora-bootc.yaml b/fedora-bootc.yaml index 11763a0..e8251b2 100644 --- a/fedora-bootc.yaml +++ b/fedora-bootc.yaml @@ -4,4 +4,4 @@ metadata: include: - fedora-generic.yaml - - tier-1/manifest.yaml + - standard/manifest.yaml diff --git a/fedora-tier-1.yaml b/fedora-standard.yaml similarity index 100% rename from fedora-tier-1.yaml rename to fedora-standard.yaml diff --git a/tier-1/autoupdates.yaml b/standard/autoupdates.yaml similarity index 100% rename from tier-1/autoupdates.yaml rename to standard/autoupdates.yaml diff --git a/tier-1/bootc-generic-growpart b/standard/bootc-generic-growpart similarity index 100% rename from tier-1/bootc-generic-growpart rename to standard/bootc-generic-growpart diff --git a/tier-1/bootc-generic-growpart.service b/standard/bootc-generic-growpart.service similarity index 100% rename from tier-1/bootc-generic-growpart.service rename to standard/bootc-generic-growpart.service diff --git a/tier-1/coreos-user-experience.yaml b/standard/coreos-user-experience.yaml similarity index 100% rename from tier-1/coreos-user-experience.yaml rename to standard/coreos-user-experience.yaml diff --git a/tier-1/generic-growfs.yaml b/standard/generic-growfs.yaml similarity index 100% rename from tier-1/generic-growfs.yaml rename to standard/generic-growfs.yaml diff --git a/tier-1/initramfs-full.yaml b/standard/initramfs-full.yaml similarity index 54% rename from tier-1/initramfs-full.yaml rename to standard/initramfs-full.yaml index 2c55a83..b84a498 100644 --- a/tier-1/initramfs-full.yaml +++ b/standard/initramfs-full.yaml @@ -1,8 +1,8 @@ -# Configuration for the "tier-1" initramfs +# Configuration for the initramfs postprocess: - | #!/usr/bin/env bash mkdir -p /usr/lib/dracut/dracut.conf.d - cat > /usr/lib/dracut/dracut.conf.d/30-bootc-tier-1.conf << 'EOF' + cat > /usr/lib/dracut/dracut.conf.d/30-bootc-standard.conf << 'EOF' add_dracutmodules+=" lvm crypt fips " EOF diff --git a/tier-1/manifest.yaml b/standard/manifest.yaml similarity index 100% rename from tier-1/manifest.yaml rename to standard/manifest.yaml diff --git a/tier-1/networking-tools.yaml b/standard/networking-tools.yaml similarity index 100% rename from tier-1/networking-tools.yaml rename to standard/networking-tools.yaml diff --git a/tier-1/persistent-journal.yaml b/standard/persistent-journal.yaml similarity index 100% rename from tier-1/persistent-journal.yaml rename to standard/persistent-journal.yaml diff --git a/tier-1/system-configuration.yaml b/standard/system-configuration.yaml similarity index 100% rename from tier-1/system-configuration.yaml rename to standard/system-configuration.yaml From 62b9f3e766e03745d048d5ef0cd8d1710e3e23cd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 21 Feb 2025 15:29:17 -0500 Subject: [PATCH 06/10] manifests: Drop metadata from fedora manifests Let's inherit from the generic descriptions. Signed-off-by: Colin Walters --- fedora-bootc.yaml | 4 ---- fedora-minimal.yaml | 4 ---- fedora-tier-x.yaml | 4 ---- 3 files changed, 12 deletions(-) diff --git a/fedora-bootc.yaml b/fedora-bootc.yaml index e8251b2..a505c04 100644 --- a/fedora-bootc.yaml +++ b/fedora-bootc.yaml @@ -1,7 +1,3 @@ -metadata: - name: fedora-boot-tier1 - summary: Fedora Bootable Tier 1 - include: - fedora-generic.yaml - standard/manifest.yaml diff --git a/fedora-minimal.yaml b/fedora-minimal.yaml index 76762f6..10d409e 100644 --- a/fedora-minimal.yaml +++ b/fedora-minimal.yaml @@ -1,7 +1,3 @@ -metadata: - name: fedora-boot-tier0 - summary: Fedora Bootable Tier 0 - include: - fedora-generic.yaml - minimal/manifest.yaml diff --git a/fedora-tier-x.yaml b/fedora-tier-x.yaml index f80d107..91af79c 100644 --- a/fedora-tier-x.yaml +++ b/fedora-tier-x.yaml @@ -1,7 +1,3 @@ -metadata: - name: fedora-boot-tier-x - summary: Fedora Bootable Tier X - include: - fedora-generic.yaml - tier-x/manifest.yaml From 8fbe774210b5caffde6d55a41952672f5fa64df4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 21 Feb 2025 15:43:39 -0500 Subject: [PATCH 07/10] Swap symlink state for fedora-bootc -> fedora-standard Followup to the naming standardization. Now `fedora-bootc.yaml` is effectively a deprecated alias only used by the legacy pungi configs. Signed-off-by: Colin Walters --- fedora-bootc.yaml | 4 +--- fedora-standard.yaml | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) mode change 100644 => 120000 fedora-bootc.yaml mode change 120000 => 100644 fedora-standard.yaml diff --git a/fedora-bootc.yaml b/fedora-bootc.yaml deleted file mode 100644 index a505c04..0000000 --- a/fedora-bootc.yaml +++ /dev/null @@ -1,3 +0,0 @@ -include: - - fedora-generic.yaml - - standard/manifest.yaml diff --git a/fedora-bootc.yaml b/fedora-bootc.yaml new file mode 120000 index 0000000..e9e57b1 --- /dev/null +++ b/fedora-bootc.yaml @@ -0,0 +1 @@ +fedora-standard.yaml \ No newline at end of file diff --git a/fedora-standard.yaml b/fedora-standard.yaml deleted file mode 120000 index d9c3fd0..0000000 --- a/fedora-standard.yaml +++ /dev/null @@ -1 +0,0 @@ -fedora-bootc.yaml \ No newline at end of file diff --git a/fedora-standard.yaml b/fedora-standard.yaml new file mode 100644 index 0000000..a505c04 --- /dev/null +++ b/fedora-standard.yaml @@ -0,0 +1,3 @@ +include: + - fedora-generic.yaml + - standard/manifest.yaml From 745c9eb6d3407cb1c79e6a7c68f4b2fa52a24ce1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 21 Feb 2025 16:02:22 -0500 Subject: [PATCH 08/10] Move fedora-generic to fedora-includes I want to make it clearer which manifests are actually "toplevels" versus which are just for inclusion. Move fedora-generic to its own subdirectory for this reason. Signed-off-by: Colin Walters --- fedora-generic.yaml => fedora-includes/generic.yaml | 0 fedora-minimal.yaml | 2 +- fedora-standard.yaml | 2 +- fedora-tier-x.yaml | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename fedora-generic.yaml => fedora-includes/generic.yaml (100%) diff --git a/fedora-generic.yaml b/fedora-includes/generic.yaml similarity index 100% rename from fedora-generic.yaml rename to fedora-includes/generic.yaml diff --git a/fedora-minimal.yaml b/fedora-minimal.yaml index 10d409e..a6b3b23 100644 --- a/fedora-minimal.yaml +++ b/fedora-minimal.yaml @@ -1,3 +1,3 @@ include: - - fedora-generic.yaml + - fedora-includes/generic.yaml - minimal/manifest.yaml diff --git a/fedora-standard.yaml b/fedora-standard.yaml index a505c04..73eeb5d 100644 --- a/fedora-standard.yaml +++ b/fedora-standard.yaml @@ -1,3 +1,3 @@ include: - - fedora-generic.yaml + - fedora-includes/generic.yaml - standard/manifest.yaml diff --git a/fedora-tier-x.yaml b/fedora-tier-x.yaml index 91af79c..eb2a3e9 100644 --- a/fedora-tier-x.yaml +++ b/fedora-tier-x.yaml @@ -1,3 +1,3 @@ include: - - fedora-generic.yaml + - fedora-includes/generic.yaml - tier-x/manifest.yaml From c89b6f429813932faaa44004ce2ffc5b77fdc181 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 21 Feb 2025 13:10:22 -0500 Subject: [PATCH 09/10] Introduce bootc-base-imagectl - Embed the manifests into the container image - Add bootc-base-imagectl which is a tightly controlled frontend to execute on those manifests. For now, we don't attempt to rework how we build the standard image to actually look like `dnf install`, but we show that it can work. Signed-off-by: Colin Walters --- .gitlab-ci.yml | 2 +- Containerfile | 15 ++++-- bootc-base-imagectl | 87 ++++++++++++++++++++++++++++++ bootc-base-imagectl.md | 99 +++++++++++++++++++++++++++++++++++ install-manifests | 18 +++++++ tests/Containerfile.test-c10s | 31 +++++++++++ 6 files changed, 248 insertions(+), 4 deletions(-) create mode 100755 bootc-base-imagectl create mode 100644 bootc-base-imagectl.md create mode 100755 install-manifests create mode 100644 tests/Containerfile.test-c10s diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 86919ef..5c82de0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -26,7 +26,7 @@ build-image: matrix: - TIER: [minimal, standard, tier-x] variables: - EXTRA_ARGS: "--security-opt=label=disable --cap-add=all --build-arg MANIFEST=fedora-$TIER.yaml" + EXTRA_ARGS: "--security-opt=label=disable --cap-add=all --build-arg MANIFEST=fedora-$TIER" rules: - if: $CI_PROJECT_NAMESPACE != "fedora/bootc" when: never diff --git a/Containerfile b/Containerfile index d01755b..4f08153 100644 --- a/Containerfile +++ b/Containerfile @@ -11,7 +11,7 @@ FROM quay.io/fedora/fedora:rawhide as repos # BOOTSTRAPPING: This can be any image that has rpm-ostree and selinux-policy-targeted. FROM quay.io/fedora/fedora:rawhide as builder RUN dnf -y install rpm-ostree selinux-policy-targeted -ARG MANIFEST=fedora-bootc.yaml +ARG MANIFEST=fedora-standard # The input git repository has .repo files committed to git rpm-ostree has historically # emphasized that. But here, we are fetching the repos from the container base image. # So copy the source, and delete the hardcoded ones in git, and use the container base @@ -20,8 +20,17 @@ COPY . /src WORKDIR /src RUN rm -vf /src/*.repo RUN --mount=type=cache,target=/workdir \ - --mount=type=bind,rw,from=repos,src=/,dst=/repos \ - rpm-ostree experimental compose rootfs --cachedir=/workdir --source-root-rw=/repos ${MANIFEST} /target-rootfs + --mount=type=bind,rw,from=repos,src=/,dst=/repos </dev/null +# Run the build script in the same way we expect custom images to do, and also +# "re-inject" the manifests into the target, so secondary container builds can use it. +/usr/libexec/bootc-base-imagectl build-rootfs --reinject --manifest=${MANIFEST} /repos /target-rootfs +EORUN # This pulls in the rootfs generated in the previous step FROM scratch diff --git a/bootc-base-imagectl b/bootc-base-imagectl new file mode 100755 index 0000000..05b880b --- /dev/null +++ b/bootc-base-imagectl @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 + +import os +import os.path as path +import subprocess +import shutil +import json +import argparse +import sys + +MANIFESTDIR = 'usr/share/doc/bootc-base-imagectl/manifests' + +def run_build_rootfs(args): + """ + Regenerates a base image using a build configuration. + """ + target = args.target + if os.path.isdir(args.manifest): + manifest_path = os.path.join(args.manifest, 'manifest.yaml') + else: + manifest_path = args.manifest + '.yaml' + try: + # Perform the build + subprocess.run([ + 'rpm-ostree', + 'experimental', + 'compose', + 'rootfs', + f'--source-root-rw={args.source_root}', + f'/{MANIFESTDIR}/{manifest_path}', + target, + ], check=True) + # And run the bootc linter for good measure + subprocess.run([ + 'bootc', + 'container', + 'lint', + f'--rootfs={target}', + ], check=True) + except subprocess.CalledProcessError as e: + print(f"Error executing command: {e}") + sys.exit(1) + + # Copy our own build configuration into the target if configured; + # this is used for the first stage build. But by default *secondary* + # builds don't get this. + if args.reinject: + for d in [MANIFESTDIR]: + dst = path.join(target, d) + print(f"Copying /{d} to {dst}") + shutil.copytree('/' + d, dst) + for f in ['usr/libexec/bootc-base-imagectl']: + dst = path.join(target, f) + print(f"Copying /{f} to {dst}") + shutil.copy('/' + f, dst) + +def run_list(args): + d = '/' + MANIFESTDIR + for ent in sorted(os.listdir(d)): + name, ext = os.path.splitext(ent) + if ext != '.yaml': + continue + fullpath = os.path.join(d, ent) + if os.path.islink(fullpath): + continue + o = subprocess.check_output(['rpm-ostree', 'compose', 'tree', '--print-only', fullpath]) + manifest = json.loads(o) + description = manifest['metadata']['summary'] + print(f"{name}: {description}") + print("---") + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Operate on the build configuration for this container") + subparsers = parser.add_subparsers(help='Subcommands', required=True) + + build_rootfs = subparsers.add_parser('build-rootfs', help='Generate a container root filesystem') + build_rootfs.add_argument("--reinject", help="Also reinject the build configurations into the target", action='store_true') + build_rootfs.add_argument("--manifest", help="Use the specified manifest", action='store', default='default') + build_rootfs.add_argument("source_root", help="Path to the source root directory used for dnf configuration.") + build_rootfs.add_argument("target", help="Path to the target root directory that will be generated.") + build_rootfs.set_defaults(func=run_build_rootfs) + + cmd_list = subparsers.add_parser('list', help='List available manifests') + cmd_list.set_defaults(func=run_list) + + args = parser.parse_args() + args.func(args) \ No newline at end of file diff --git a/bootc-base-imagectl.md b/bootc-base-imagectl.md new file mode 100644 index 0000000..9a90b34 --- /dev/null +++ b/bootc-base-imagectl.md @@ -0,0 +1,99 @@ +# bootc-base-imagectl + +A core premise of the bootc model is that rich +control over Linux system customization can be accomplished +with a "default" container build: + +``` +FROM +RUN ... +``` + +As of recently, it is possible to e.g. swap the kernel +and other fundamental components as part of default derivation. + +However, some use cases want even more control - for example, +as an organization deploying a bootc system, I may want to ensure +the base image version carries a set of packages at +exactly specific versions (perhaps defined by a lockfile, +or an rpm-md repository). There are many tools which +manage snapshots of yum (rpm-md) repositories. + +There are currently issues where it won't quite work to e.g. +`dnf -y upgrade selinux-policy-targeted`. + +The `/usr/libexec/bootc-base-imagectl` tool which is +included in the base image is designed to enable building +a root filesystem in ostree-container format from a set +of RPMs controlled by the user. + +## Understanding the base image content + +Most, but not all content from the base image comes from RPMs. +There is some additional non-RPM content, as well as postprocessing +that operates on the filesystem root. At the current time the +implementation of the base image build uses `rpm-ostree`, +but this is considered an implementation detail subject to change. + +## Using bootc-base-imagectl build-rootfs + +The core operation is `bootc-base-imagectl build-rootfs`. + +This command takes just two arguments: + +- A "source root" which should have an `/etc/yum.repos.d` + that defines the input RPM content. This source root is also used + to control things like the `$releasever`. +- A path to the target root filesystem which will be generated as + a directory. The target should not already exist (but its parent must exist). + +### Other options + +`bootc-base-imagectl list` will enumerate available configurations that +can be selected by passing `--manifest` to `build-rootfs`. + +### Implementation + +The current implementation uses `rpm-ostree` on a manifest (treefile) +embedded in the container image itself. These manifests are not intended +to be editable directly. + +To emphasize: the implementation of this command (especially the configuration +files that it reads) are subject to change. + +### Cross builds and the builder image + +The build tooling is designed to support "cross builds"; the +repository root could e.g. be CentOS Stream 10, while the +builder root is Fedora or RHEL, etc. + +In other words, one given base image can be used as a "builder" to produce another +using different RPMs. + +### Example: Generate a new image using CentOS Stream 10 content from RHEL + +FROM quay.io/centos/centos:stream10 as repos + +FROM registry.redhat.io/rhel10/rhel-bootc:10 as builder +RUN --mount=type=bind,from=repos,src=/,dst=/repos,rw /usr/libexec/bootc-base-imagectl build-rootfs --manifest=minimal /repos /target-rootfs + +# This container image uses the "artifact pattern"; it has some +# basic configuration we expect to apply to multiple container images. +FROM quay.io/exampleos/baseconfig@sha256:.... as baseconfig + +FROM scratch +COPY --from=builder /target-rootfs/ / +# Now we make other arbitrary changes. Copy our systemd units and +# other tweaks from the baseconfig container image. +COPY --from=baseconfig /usr/ /usr/ +RUN < Date: Mon, 24 Feb 2025 13:53:01 -0500 Subject: [PATCH 10/10] ci: Drop tier-x build, do build test case As part of all of this we're de-emphasizing "tier-x" and focusing on making it ergonomic to either build up from minimal, or down+up from standard. Second, also add a CI test for our derived image. Signed-off-by: Colin Walters --- .gitlab-ci.yml | 32 +++++++------------ ...le.test-c10s => Containerfile.test-derive} | 7 ++-- 2 files changed, 14 insertions(+), 25 deletions(-) rename tests/{Containerfile.test-c10s => Containerfile.test-derive} (85%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5c82de0..d25599d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,31 +3,21 @@ stages: - build variables: - IMAGE: ${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_SHA} - CONTAINERFILE: Containerfile - CONTEXT: . - EXTRA_ARGS: "" + PRIV_ARGS: "--security-opt=label=disable --cap-add=all --device /dev/fuse" .build-image: stage: build image: quay.io/buildah/stable:v1.38.0 needs: [] - script: buildah bud -f ${CONTAINERFILE} --no-cache -t ${IMAGE} ${EXTRA_ARGS} ${CONTEXT} - rules: - - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" - when: never - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS - when: never -build-image: +build-minimal: extends: .build-image - parallel: - matrix: - - TIER: [minimal, standard, tier-x] - variables: - EXTRA_ARGS: "--security-opt=label=disable --cap-add=all --build-arg MANIFEST=fedora-$TIER" - rules: - - if: $CI_PROJECT_NAMESPACE != "fedora/bootc" - when: never - - if: $CI_PIPELINE_SOURCE == "merge_request_event" + script: buildah build -f Containerfile --no-cache -t localhost/fedora-bootc:minimal ${PRIV_ARGS} --build-arg=manifest=fedora-minimal . + +standard-build-and-test: + extends: .build-image + script: | + set -xeuo pipefail + buildah build --no-cache -t localhost/fedora-bootc ${PRIV_ARGS} . + cd tests + buildah build -f Containerfile.test-derive --no-cache -t localhost/fedora-bootc-derived ${PRIV_ARGS} . diff --git a/tests/Containerfile.test-c10s b/tests/Containerfile.test-derive similarity index 85% rename from tests/Containerfile.test-c10s rename to tests/Containerfile.test-derive index 2b6b4e6..52cd0a7 100644 --- a/tests/Containerfile.test-c10s +++ b/tests/Containerfile.test-derive @@ -1,7 +1,7 @@ # This test case exercises using the fedora-bootc image as a builder # to generate a minimal target image derived from CentOS Stream 10 content, # and then further extends it in a secondary phase. -FROM quay.io/centos/centos:stream10 as repos +FROM quay.io/fedora/fedora-bootc:rawhide as repos # This is intentionally a locally built image FROM localhost/fedora-bootc as builder @@ -12,16 +12,15 @@ FROM scratch COPY --from=builder /target-rootfs/ / RUN <