Skip to content

Commit

Permalink
podvm-mkosi: build s390x fedora image
Browse files Browse the repository at this point in the history
Package system with mkosi and generate bootloader
with zipl

Signed-off-by: Lei Li <genjuro214@gmail.com>
Signed-off-by: Lei Li <cdlleili@cn.ibm.com>
  • Loading branch information
Lei Li committed Mar 20, 2024
1 parent b499f84 commit e1da2f5
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 1 deletion.
10 changes: 10 additions & 0 deletions podvm-mkosi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,25 @@ 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:
@echo "Enabling debug preset..."
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:
Expand Down
24 changes: 24 additions & 0 deletions podvm-mkosi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
92 changes: 92 additions & 0 deletions podvm-mkosi/build-s390x-image.sh
Original file line number Diff line number Diff line change
@@ -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 <<END > ${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

10 changes: 10 additions & 0 deletions podvm-mkosi/mkosi.presets/initrd/mkosi.conf.d/fedora-s390x.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Match]
Distribution=fedora

Architecture=s390x

[Content]
Packages=kernel-core

[Host]
ToolsTree=default
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[Match]
Distribution=fedora

Architecture=!s390x

[Content]
Packages=systemd-boot
18 changes: 18 additions & 0 deletions podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora-s390x.conf
Original file line number Diff line number Diff line change
@@ -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
1 change: 0 additions & 1 deletion podvm-mkosi/mkosi.presets/system/mkosi.conf.d/fedora.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ Packages=
udev
util-linux
systemd
systemd-boot
systemd-networkd
systemd-resolved
dbus
Expand Down
2 changes: 2 additions & 0 deletions podvm-mkosi/mkosi.profiles/debug.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Content]
Environment=VARIANT_ID=Debug
2 changes: 2 additions & 0 deletions podvm-mkosi/mkosi.profiles/production.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Content]
Environment=VARIANT_ID=Production

0 comments on commit e1da2f5

Please sign in to comment.