From 1065f6860d4ab110b9552a224c89b45d6b1772d8 Mon Sep 17 00:00:00 2001 From: Lei Li Date: Fri, 15 Mar 2024 07:34:02 +0000 Subject: [PATCH] podvm-mkosi: build s390x fedora image Package system with mkosi and generate bootloader with zipl Signed-off-by: Lei Li Signed-off-by: Lei Li --- hack/build-s390x-image.sh | 85 +++++++++++++++++++ podvm-mkosi/Makefile | 10 +++ podvm-mkosi/README.md | 24 ++++++ .../initrd/mkosi.conf.d/fedora-s390x.conf | 10 +++ .../system/mkosi.conf.d/fedora-bootable.conf | 7 ++ .../system/mkosi.conf.d/fedora-s390x.conf | 18 ++++ .../system/mkosi.conf.d/fedora.conf | 1 - .../system/mkosi.finalize.chroot | 14 +++ podvm-mkosi/mkosi.profiles/debug.conf | 2 + podvm-mkosi/mkosi.profiles/production.conf | 2 + 10 files changed, 172 insertions(+), 1 deletion(-) create mode 100755 hack/build-s390x-image.sh create mode 100644 podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/fedora-s390x.conf create mode 100644 podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora-bootable.conf create mode 100644 podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora-s390x.conf create mode 100755 podvm-mkosi/mkosi.presets/system/mkosi.finalize.chroot create mode 100644 podvm-mkosi/mkosi.profiles/debug.conf create mode 100644 podvm-mkosi/mkosi.profiles/production.conf diff --git a/hack/build-s390x-image.sh b/hack/build-s390x-image.sh new file mode 100755 index 000000000..083452ae1 --- /dev/null +++ b/hack/build-s390x-image.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +set -euo pipefail + +pushd ../podvm-mkosi/build + +workdir=. +tmp_img_path="${workdir}/tmp.qcow2" +tmp_nbd=/dev/nbd1 +dst_mnt=./dst_mnt +disksize=100G + +qemu-img create -f qcow2 "${tmp_img_path}" "${disksize}" + +modprobe nbd +qemu-nbd --connect="${tmp_nbd}" "${tmp_img_path}" + +# Partition and format +parted -a optimal "${tmp_nbd}" mklabel gpt \ + mkpart boot ext4 1MiB 256MiB \ + mkpart system 256MiB "${disksize}" \ + set 1 boot on + +echo "Waiting for the two nbd partitions to show up" +while true; do +sleep 1 +[[ -e "${tmp_nbd}"p2 ]] && break +done + +mke2fs -t ext4 -L boot "${tmp_nbd}"p1 +boot_uuid=$(blkid "${tmp_nbd}"p1 -s PARTUUID -o value) + +mke2fs -t ext4 -L system "${tmp_nbd}"p2 +system_uuid=$(blkid "${tmp_nbd}"p2 -s PARTUUID -o value) + +# Copy files +mkdir -p "${dst_mnt}" +mount "${tmp_nbd}p2" "${dst_mnt}" + +mkdir -p "${dst_mnt}"/boot +mount -o norecovery "${tmp_nbd}"p1 "${dst_mnt}"/boot + +cp initrd.cpio.zst "${dst_mnt}"/boot/initrd.img +cp system.vmlinuz "${dst_mnt}"/boot/vmlinuz + +src_mnt=system +tar_opts=(--numeric-owner --preserve-permissions --acl --selinux --xattrs --xattrs-include='*' --sparse) +tar -cf - "${tar_opts[@]}" --sort=none -C "${src_mnt}" . | tar -xf - "${tar_opts[@]}" --preserve-order -C "${dst_mnt}" + +cat < "${dst_mnt}/etc/fstab" +#This file was auto-generated +PARTUUID=${system_uuid} / ext4 defaults 1 1 +PARTUUID=${boot_uuid} /boot ext4 norecovery 1 2 +END + +mount -t sysfs sysfs "${dst_mnt}/sys" +mount -t proc proc "${dst_mnt}/proc" +mount --bind /dev "${dst_mnt}/dev" + +# generate bootloader +chroot "${dst_mnt}" zipl -V --targetbase "${tmp_nbd}" \ + --targettype scsi \ + --targetblocksize 512 \ + --targetoffset 2048 \ + --target /boot \ + --image /boot/vmlinuz \ + --ramdisk /boot/initrd.img \ + --parameters "root=LABEL=system selinux=0 enforcing=0 audit=0 systemd.firstboot=off" + +umount "${dst_mnt}/dev" +umount "${dst_mnt}/proc" +umount "${dst_mnt}/sys" + +umount "${dst_mnt}/boot" +umount "${dst_mnt}" + +qemu-nbd --disconnect "${tmp_nbd}" + +output_img_name="podvm-s390x.qcow2" +qemu-img convert -O qcow2 -c "${tmp_img_path}" "${output_img_name}" + +output_img_path=$(realpath "${output_img_name}") +echo "podvm image is generated: ${output_img_path}" + +popd diff --git a/podvm-mkosi/Makefile b/podvm-mkosi/Makefile index ddd4f0be2..470b1c55e 100644 --- a/podvm-mkosi/Makefile +++ b/podvm-mkosi/Makefile @@ -46,7 +46,12 @@ image: rm -rf resources/buildDebugImage rm -rf ./build @echo "Building image..." +ifeq ($(ARCH),s390x) + mkosi --profile production.conf + ../hack/build-s390x-image.sh +else nix develop ..#podvm-mkosi --command mkosi --environment=VARIANT_ID=production +endif PHONY: image-debug image-debug: @@ -54,7 +59,12 @@ image-debug: touch resources/buildDebugImage rm -rf ./build @echo "Building debug image..." +ifeq ($(ARCH),s390x) + mkosi --profile debug.conf + ../hack/build-s390x-image.sh +else nix develop ..#podvm-mkosi --command mkosi --environment=VARIANT_ID=debug +endif PHONY: clean clean: diff --git a/podvm-mkosi/README.md b/podvm-mkosi/README.md index 249cc1cd7..b682b8acb 100644 --- a/podvm-mkosi/README.md +++ b/podvm-mkosi/README.md @@ -75,3 +75,27 @@ reduce complexity of configuration and CI and shall not be seen as open to-dos. - Deployed images cannot be customized with cloud-init. Runtime configuration data is retrieved from IMDS via the project's `process-user-data` tool. + +## Build s390x image +Since the [nix OS](https://nixos.org/download/#download-nix) does not support s390x, we can use the mkosi **ToolsTree** feature defined in `mkosi.conf` to download latest tools automatically: +``` +[Host] +ToolsTree=default +``` +And install **mkosi** from the repository: +```sh +git clone -b v21 https://github.com/systemd/mkosi +ln -s $PWD/mkosi/bin/mkosi /usr/local/bin/mkosi +mkosi --version +``` +Another issue is s390x does not support UEFI. Instead, we can first use **mkosi** to build non-bootable system files, then use **zipl** to generate the bootloader and finally create the bootable image. + +It requires a **s390x host** to build s390x image with make commands: +``` +make fedora-binaries-builder +make binaries +make image +# make image-debug +``` + +The final output is `build/podvm-s390x.qcow2`, which can be used as the Pod VM image in libvirt environment. diff --git a/podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/fedora-s390x.conf b/podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/fedora-s390x.conf new file mode 100644 index 000000000..2ca277b58 --- /dev/null +++ b/podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/fedora-s390x.conf @@ -0,0 +1,10 @@ +[Match] +Distribution=fedora + +Architecture=s390x + +[Content] +Packages=kernel-core + +[Host] +ToolsTree=default diff --git a/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora-bootable.conf b/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora-bootable.conf new file mode 100644 index 000000000..5ba2eafc7 --- /dev/null +++ b/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora-bootable.conf @@ -0,0 +1,7 @@ +[Match] +Distribution=fedora + +Architecture=!s390x + +[Content] +Packages=systemd-boot diff --git a/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora-s390x.conf b/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora-s390x.conf new file mode 100644 index 000000000..2d5ad9695 --- /dev/null +++ b/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora-s390x.conf @@ -0,0 +1,18 @@ +[Match] +Distribution=fedora + +Architecture=s390x + +[Content] +Bootable=no +Packages=s390utils + dhclient + NetworkManager + cloud-init + cloud-utils-growpart + +[Output] +Format=directory + +[Host] +ToolsTree=default diff --git a/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora.conf b/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora.conf index 32b07a0d5..12f7c1739 100644 --- a/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora.conf +++ b/podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora.conf @@ -15,7 +15,6 @@ Packages= udev util-linux systemd - systemd-boot systemd-networkd systemd-resolved dbus diff --git a/podvm-mkosi/mkosi.presets/system/mkosi.finalize.chroot b/podvm-mkosi/mkosi.presets/system/mkosi.finalize.chroot new file mode 100755 index 000000000..9a3c9a548 --- /dev/null +++ b/podvm-mkosi/mkosi.presets/system/mkosi.finalize.chroot @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +if [[ "${ARCHITECTURE}" == "s390x" ]]; then + # enable cloud-init services + systemctl enable cloud-init-local.service + systemctl enable cloud-init.service + systemctl enable cloud-config.service + systemctl enable cloud-final.service + + # disable this service since we already have "NetworkManager-wait-online.service" + systemctl disable systemd-networkd-wait-online.service +fi diff --git a/podvm-mkosi/mkosi.profiles/debug.conf b/podvm-mkosi/mkosi.profiles/debug.conf new file mode 100644 index 000000000..b5b8a2a14 --- /dev/null +++ b/podvm-mkosi/mkosi.profiles/debug.conf @@ -0,0 +1,2 @@ +[Content] +Environment=VARIANT_ID=debug diff --git a/podvm-mkosi/mkosi.profiles/production.conf b/podvm-mkosi/mkosi.profiles/production.conf new file mode 100644 index 000000000..6a6c932e2 --- /dev/null +++ b/podvm-mkosi/mkosi.profiles/production.conf @@ -0,0 +1,2 @@ +[Content] +Environment=VARIANT_ID=production