From 7a904d3c8057995d3f5e42a5533c2f389781b54d Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Thu, 17 Jul 2025 17:19:08 +0200 Subject: [PATCH] osbuild: use bootc install to deploy the container Instead of deploying the container to the tree then copy all the contents to the disk image, use bootc to directly manage the installation to the target filesystems. Right now this requires to use the image as the buildroot so this requires python (for osbuild). This is tracked in [1]. [1] https://github.com/bootc-dev/bootc/issues/1410 Requires https://github.com/osbuild/osbuild/pull/2149 --- build.sh | 18 +- ...gnition-parametrize-the-path-to-boot.patch | 69 ++++ .../coreos.osbuild.x86_64.mpp.yaml | 332 +++--------------- 3 files changed, 124 insertions(+), 295 deletions(-) create mode 100644 src/0001-stages-ignition-parametrize-the-path-to-boot.patch diff --git a/build.sh b/build.sh index 2e942dbc51..751903d6ac 100755 --- a/build.sh +++ b/build.sh @@ -177,25 +177,25 @@ write_archive_info() { } patch_osbuild() { - return # we have no patches right now + # return # we have no patches right now ## Add a few patches that either haven't made it into a release or ## that will be obsoleted with other work that will be done soon. ## To make it easier to apply patches we'll move around the osbuild ## code on the system first: - #rmdir /usr/lib/osbuild/osbuild - #mv /usr/lib/python3.13/site-packages/osbuild /usr/lib/osbuild/ - #mkdir /usr/lib/osbuild/tools - #mv /usr/bin/osbuild-mpp /usr/lib/osbuild/tools/ + rmdir /usr/lib/osbuild/osbuild + mv /usr/lib/python3.13/site-packages/osbuild /usr/lib/osbuild/ + mkdir /usr/lib/osbuild/tools + mv /usr/bin/osbuild-mpp /usr/lib/osbuild/tools/ ## Now all the software is under the /usr/lib/osbuild dir and we can patch - #cat foo.patch | patch -d /usr/lib/osbuild -p1 + patch -d /usr/lib/osbuild -p1 < src/0001-stages-ignition-parametrize-the-path-to-boot.patch # ## And then move the files back; supermin appliance creation will need it back ## in the places delivered by the RPM. - #mv /usr/lib/osbuild/tools/osbuild-mpp /usr/bin/osbuild-mpp - #mv /usr/lib/osbuild/osbuild /usr/lib/python3.13/site-packages/osbuild - #mkdir /usr/lib/osbuild/osbuild + mv /usr/lib/osbuild/tools/osbuild-mpp /usr/bin/osbuild-mpp + mv /usr/lib/osbuild/osbuild /usr/lib/python3.13/site-packages/osbuild + mkdir /usr/lib/osbuild/osbuild } if [ $# -ne 0 ]; then diff --git a/src/0001-stages-ignition-parametrize-the-path-to-boot.patch b/src/0001-stages-ignition-parametrize-the-path-to-boot.patch new file mode 100644 index 0000000000..f28d22f55b --- /dev/null +++ b/src/0001-stages-ignition-parametrize-the-path-to-boot.patch @@ -0,0 +1,69 @@ +From e37bd5d256c02f2a7693ec220322cf131e8e5274 Mon Sep 17 00:00:00 2001 +From: jbtrystram +Date: Thu, 17 Jul 2025 15:59:27 +0200 +Subject: [PATCH] stages/ignition: parametrize the path to boot + +Allow passing a mount to specify where to write the igntion.firstboot +file. +This keeps the default `tree:///` value to not break existing stages. +--- + stages/org.osbuild.ignition | 13 ++++++++----- + stages/org.osbuild.ignition.meta.json | 5 +++++ + 2 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/stages/org.osbuild.ignition b/stages/org.osbuild.ignition +index 23f91c48..4466cabf 100755 +--- a/stages/org.osbuild.ignition ++++ b/stages/org.osbuild.ignition +@@ -2,18 +2,17 @@ + import sys + + import osbuild.api ++from osbuild.util import parsing + + +-def main(tree, options): +- network = options.get("network", []) +- ++def main(network, location): + # grub, when detecting the '/boot/ignition.firstboot' file + # will set the "ignition_firstboot" option so that ignition + # gets triggered during that boot. Additionally, the file + # itself will be sourced this the 'ignition_network_kcmdline' + # that is also in the "ignition_firstboot" variable can be + # overwritten with the contents of `network` +- with open(f"{tree}/boot/ignition.firstboot", "w", encoding="utf8") as f: ++ with open(f"{location}/ignition.firstboot", "w", encoding="utf8") as f: + if network: + netstr = " ".join(network) + f.write(f"set ignition_network_kcmdline='{netstr}'") +@@ -23,5 +22,9 @@ def main(tree, options): + + if __name__ == '__main__': + args = osbuild.api.arguments() +- r = main(args["tree"], args.get("options", {})) ++ options = args.get("options", {}) ++ target = options.get("target", "tree:///boot") ++ location = parsing.parse_location(target, args) ++ network = options.get("network", []) ++ r = main(network, location) + sys.exit(r) +diff --git a/stages/org.osbuild.ignition.meta.json b/stages/org.osbuild.ignition.meta.json +index 612d59c7..dd295c24 100644 +--- a/stages/org.osbuild.ignition.meta.json ++++ b/stages/org.osbuild.ignition.meta.json +@@ -22,6 +22,11 @@ + "items": { + "type": "string" + } ++ }, ++ "target": { ++ "type": "string", ++ "description": "Location to write the 'ignition.firstboot' file.", ++ "default": "tree:///boot" + } + } + } +-- +2.50.1 + diff --git a/src/osbuild-manifests/coreos.osbuild.x86_64.mpp.yaml b/src/osbuild-manifests/coreos.osbuild.x86_64.mpp.yaml index dcde8fc280..7429e8614d 100644 --- a/src/osbuild-manifests/coreos.osbuild.x86_64.mpp.yaml +++ b/src/osbuild-manifests/coreos.osbuild.x86_64.mpp.yaml @@ -39,11 +39,11 @@ mpp-vars: # matches. Unfortunately for FCOS there is no python so we can't # really use FCOS as the buildroot so we'll use the host as the # buildroot there. - buildroot: - mpp-if: osname in ['rhcos', 'scos'] - then: "name:deployed-tree" - else: - mpp-format-string: '{host_as_buildroot}' + buildroot: "name:deployed-tree" + # mpp-if: osname in ['rhcos', 'scos', 'fc'] + # then: "name:deployed-tree" + # else: + # mpp-format-string: '{host_as_buildroot}' mpp-define-images: - id: image sector_size: @@ -164,86 +164,6 @@ pipelines: origin: org.osbuild.pipeline references: - name:deployed-tree - - type: org.osbuild.ostree.init-fs - - type: org.osbuild.ostree.os-init - options: - osname: - mpp-format-string: '{osname}' - - type: org.osbuild.ostree.config - options: - repo: /ostree/repo - config: - sysroot: - readonly: true - bootloader: none - # https://github.com/coreos/fedora-coreos-tracker/issues/1333 - bls-append-except-default: grub_users="" - # Opt-in to https://github.com/ostreedev/ostree/pull/2705 which will - # add /boot as the prefix on top of BLS config entries. This is OK - # because there is a symlink that is created in the root of the boot - # filesystem by OSTree (boot -> .) that makes it so that /boot paths - # will always work. - bootprefix: true - - type: org.osbuild.mkdir - options: - paths: - - path: /boot/efi - mode: 493 - - type: org.osbuild.ignition - # Deploy via ociarchive or container - - mpp-if: ociarchive != '' - then: - type: org.osbuild.ostree.deploy.container - options: - osname: - mpp-format-string: '{osname}' - target_imgref: - mpp-format-string: '{container_imgref}' - mounts: - - /boot - - /boot/efi - kernel_opts: - - rw - - '$ignition_firstboot' - - mpp-format-string: '{extra_kargs}' - inputs: - images: - type: org.osbuild.containers - origin: org.osbuild.pipeline - references: - name:oci-archive: - name: coreos.ociarchive - else: - type: org.osbuild.ostree.deploy.container - options: - osname: - mpp-format-string: '{osname}' - target_imgref: - mpp-format-string: '{container_imgref}' - mounts: - - /boot - - /boot/efi - kernel_opts: - - rw - - '$ignition_firstboot' - - mpp-format-string: '{extra_kargs}' - inputs: - images: - type: org.osbuild.containers - origin: org.osbuild.source - mpp-resolve-images: - images: - - source: $container_repo - tag: $container_tag - - type: org.osbuild.ostree.aleph - options: - coreos_compat: true - deployment: - default: true - - type: org.osbuild.ostree.selinux - options: - deployment: - default: true - name: raw-image build: mpp-format-string: '{buildroot}' @@ -344,69 +264,23 @@ pipelines: partition: mpp-format-int: '{image.layout[''boot''].partnum}' target: /boot-mount-point - - type: org.osbuild.selinux - options: - file_contexts: input://tree/etc/selinux/targeted/contexts/files/file_contexts - target: mount://root/ - inputs: - tree: - type: org.osbuild.tree - origin: org.osbuild.pipeline - references: - - name:deployed-tree - devices: - disk: - type: org.osbuild.loopback - options: - filename: disk.img - partscan: true - mounts: - - name: root - type: org.osbuild.xfs - source: disk - partition: - mpp-format-int: '{image.layout[''root''].partnum}' - target: / - - type: org.osbuild.selinux - options: - file_contexts: input://tree/etc/selinux/targeted/contexts/files/file_contexts - target: mount://root/boot/ - inputs: - tree: - type: org.osbuild.tree + # Use bootc install to-filesystem to install the ostree content from the container image + # inside our disc image + - type: org.osbuild.bootc.install-to-filesystem + inputs: + images: + type: org.osbuild.containers origin: org.osbuild.pipeline references: - - name:deployed-tree - devices: - disk: - type: org.osbuild.loopback - options: - filename: disk.img - partscan: true - mounts: - - name: root - type: org.osbuild.xfs - source: disk - partition: - mpp-format-int: '{image.layout[''root''].partnum}' - target: / - - name: boot - type: org.osbuild.ext4 - source: disk - partition: - mpp-format-int: '{image.layout[''boot''].partnum}' - target: /boot - - type: org.osbuild.copy - inputs: - tree: - type: org.osbuild.tree - origin: org.osbuild.pipeline - references: - - name:tree + name:oci-archive: + name: coreos.ociarchive options: - paths: - - from: input://tree/ - to: mount://root/ + kernel-args: + - rw + - '$ignition_firstboot' + - mpp-format-string: '{extra_kargs}' + target-imgref: + mpp-format-string: '{container_imgref}' devices: disk: type: org.osbuild.loopback @@ -432,13 +306,11 @@ pipelines: partition: mpp-format-int: '{image.layout[''EFI-SYSTEM''].partnum}' target: /boot/efi - - type: org.osbuild.bootupd + # set up the `ignition.firstboot` stamp at the end because + # bootc want empty filesystems + - type: org.osbuild.ignition options: - bios: - device: disk - static-configs: true - deployment: - default: true + target: mount://boot/ devices: disk: type: org.osbuild.loopback @@ -458,36 +330,6 @@ pipelines: partition: mpp-format-int: '{image.layout[''boot''].partnum}' target: /boot - - name: efi - type: org.osbuild.fat - source: disk - partition: - mpp-format-int: '{image.layout[''EFI-SYSTEM''].partnum}' - target: /boot/efi - - type: org.osbuild.chattr - options: - items: - mount://root/: - immutable: true - devices: - disk: - type: org.osbuild.loopback - options: - filename: disk.img - partscan: true - mounts: - - name: root - type: org.osbuild.xfs - source: disk - partition: - mpp-format-int: '{image.layout[''root''].partnum}' - target: / - - name: ostree.deployment - type: org.osbuild.ostree.deployment - options: - source: mount - deployment: - default: true - name: raw-4k-image build: mpp-format-string: '{buildroot}' @@ -598,41 +440,23 @@ pipelines: partition: mpp-format-int: '{image4k.layout[''boot''].partnum}' target: /boot-mount-point - - type: org.osbuild.selinux - options: - file_contexts: input://tree/etc/selinux/targeted/contexts/files/file_contexts - target: mount://root/ - inputs: - tree: - type: org.osbuild.tree + # Use bootc install to-filesystem to install the ostree content from the container image + # inside our disc image + - type: org.osbuild.bootc.install-to-filesystem + inputs: + images: + type: org.osbuild.containers origin: org.osbuild.pipeline references: - - name:deployed-tree - devices: - disk: - type: org.osbuild.loopback - options: - filename: disk.img - partscan: true - sector-size: - mpp-format-int: "{four_k_sector_size}" - mounts: - - name: root - type: org.osbuild.xfs - source: disk - partition: - mpp-format-int: '{image4k.layout[''root''].partnum}' - target: / - - type: org.osbuild.selinux + name:oci-archive: + name: coreos.ociarchive options: - file_contexts: input://tree/etc/selinux/targeted/contexts/files/file_contexts - target: mount://root/boot/ - inputs: - tree: - type: org.osbuild.tree - origin: org.osbuild.pipeline - references: - - name:deployed-tree + kernel-args: + - rw + - '$ignition_firstboot' + - mpp-format-string: '{extra_kargs}' + target-imgref: + mpp-format-string: '{container_imgref}' devices: disk: type: org.osbuild.loopback @@ -646,57 +470,25 @@ pipelines: type: org.osbuild.xfs source: disk partition: - mpp-format-int: '{image4k.layout[''root''].partnum}' - target: / - - name: boot - type: org.osbuild.ext4 - source: disk - partition: - mpp-format-int: '{image4k.layout[''boot''].partnum}' - target: /boot - - type: org.osbuild.copy - inputs: - tree: - type: org.osbuild.tree - origin: org.osbuild.pipeline - references: - - name:tree - options: - paths: - - from: input://tree/ - to: mount://root/ - devices: - disk: - type: org.osbuild.loopback - options: - filename: disk.img - partscan: true - sector-size: - mpp-format-int: "{four_k_sector_size}" - mounts: - - name: root - type: org.osbuild.xfs - source: disk - partition: - mpp-format-int: '{image4k.layout[''root''].partnum}' + mpp-format-int: '{image.layout[''root''].partnum}' target: / - name: boot type: org.osbuild.ext4 source: disk partition: - mpp-format-int: '{image4k.layout[''boot''].partnum}' + mpp-format-int: '{image.layout[''boot''].partnum}' target: /boot - name: efi type: org.osbuild.fat source: disk partition: - mpp-format-int: '{image4k.layout[''EFI-SYSTEM''].partnum}' + mpp-format-int: '{image.layout[''EFI-SYSTEM''].partnum}' target: /boot/efi - - type: org.osbuild.bootupd + # set up the `ignition.firstboot` stamp at the end because + # bootc want empty filesystems + - type: org.osbuild.ignition options: - static-configs: true - deployment: - default: true + target: mount://boot/ devices: disk: type: org.osbuild.loopback @@ -710,46 +502,14 @@ pipelines: type: org.osbuild.xfs source: disk partition: - mpp-format-int: '{image4k.layout[''root''].partnum}' + mpp-format-int: '{image.layout[''root''].partnum}' target: / - name: boot type: org.osbuild.ext4 source: disk partition: - mpp-format-int: '{image4k.layout[''boot''].partnum}' + mpp-format-int: '{image.layout[''boot''].partnum}' target: /boot - - name: efi - type: org.osbuild.fat - source: disk - partition: - mpp-format-int: '{image4k.layout[''EFI-SYSTEM''].partnum}' - target: /boot/efi - - type: org.osbuild.chattr - options: - items: - mount://root/: - immutable: true - devices: - disk: - type: org.osbuild.loopback - options: - filename: disk.img - partscan: true - sector-size: - mpp-format-int: "{four_k_sector_size}" - mounts: - - name: root - type: org.osbuild.xfs - source: disk - partition: - mpp-format-int: '{image4k.layout[''root''].partnum}' - target: / - - name: ostree.deployment - type: org.osbuild.ostree.deployment - options: - source: mount - deployment: - default: true - mpp-import-pipelines: path: platform.aliyun.ipp.yaml - mpp-import-pipelines: