diff --git a/podvm-mkosi/Makefile b/podvm-mkosi/Makefile index ddd4f0be2..4ae3f57ff 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 + ./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 + ./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/build-s390x-image.sh b/podvm-mkosi/build-s390x-image.sh new file mode 100755 index 000000000..02272a81d --- /dev/null +++ b/podvm-mkosi/build-s390x-image.sh @@ -0,0 +1,92 @@ +#!/bin/bash + +set -eu + +pushd 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" + +# enable cloud-init services +chroot $dst_mnt systemctl enable cloud-init-local.service +chroot $dst_mnt systemctl enable cloud-init.service +chroot $dst_mnt systemctl enable cloud-config.service +chroot $dst_mnt systemctl enable cloud-final.service + +# disable this service since we already have "NetworkManager-wait-online.service" +chroot $dst_mnt systemctl disable systemd-networkd-wait-online.service + +# 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" + +qemu-img convert -O qcow2 -c "$tmp_img_path" "podvm-s390x.qcow2" +echo "podvm image is generated: $(realpath podvm-s390x.qcow2)" + +popd + 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.profiles/debug.conf b/podvm-mkosi/mkosi.profiles/debug.conf new file mode 100644 index 000000000..920b42627 --- /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..7d5e767ef --- /dev/null +++ b/podvm-mkosi/mkosi.profiles/production.conf @@ -0,0 +1,2 @@ +[Content] +Environment=VARIANT_ID=Production