From d8391a3e7619c7f304d1ec0f16f4fd0907b6bc68 Mon Sep 17 00:00:00 2001 From: Stefan Catargiu <13122921+5kt@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:02:39 +0000 Subject: [PATCH] Add demo iso --- features/_iso | 1 - features/_iso/README.md | 21 +++++ features/_iso/exec.config | 1 + .../etc/kernel/cmdline.d/99-serial.cfg | 1 + .../_iso/file.include/opt/install/install.sh | 59 +++++++++++++ .../opt/install/repart/00-efi.conf | 8 ++ .../opt/install/repart/10-root.conf | 9 ++ features/_iso/image.iso | 85 +++++++++++++++++++ features/_iso/info.yaml | 6 ++ features/_iso/pkg.include | 8 ++ features/_iso/test/autologin.disable | 0 features/_iso/test/test_capabilities.py | 1 + features/_iso/test/test_packages_musthave.py | 1 + flavors.yaml | 8 ++ 14 files changed, 208 insertions(+), 1 deletion(-) delete mode 120000 features/_iso create mode 100644 features/_iso/README.md create mode 100755 features/_iso/exec.config create mode 100644 features/_iso/file.include/etc/kernel/cmdline.d/99-serial.cfg create mode 100755 features/_iso/file.include/opt/install/install.sh create mode 100644 features/_iso/file.include/opt/install/repart/00-efi.conf create mode 100644 features/_iso/file.include/opt/install/repart/10-root.conf create mode 100755 features/_iso/image.iso create mode 100644 features/_iso/info.yaml create mode 100644 features/_iso/pkg.include create mode 100644 features/_iso/test/autologin.disable create mode 100644 features/_iso/test/test_capabilities.py create mode 100644 features/_iso/test/test_packages_musthave.py diff --git a/features/_iso b/features/_iso deleted file mode 120000 index d7ebec9b..00000000 --- a/features/_iso +++ /dev/null @@ -1 +0,0 @@ -../gardenlinux/features/_iso \ No newline at end of file diff --git a/features/_iso/README.md b/features/_iso/README.md new file mode 100644 index 00000000..41b572d0 --- /dev/null +++ b/features/_iso/README.md @@ -0,0 +1,21 @@ +## Feature: _iso + +## !! USE THIS FOR DEMO PURPOSES ONLY !! + +### Description + + +This feature flag creates an `.iso` artifact of Garden Linux. +The root user has a hardcoded password _gardenlinux_ + + +### Features +This feature simply creates a bootable `.iso` image as an additional artifact. + +### Meta +||| +|---|---| +|type|flag| +|artifact|None| +|included_features|None| +|excluded_features|None| diff --git a/features/_iso/exec.config b/features/_iso/exec.config new file mode 100755 index 00000000..c8536047 --- /dev/null +++ b/features/_iso/exec.config @@ -0,0 +1 @@ +echo "root:gardenlinux" | chpasswd -c YESCRYPT diff --git a/features/_iso/file.include/etc/kernel/cmdline.d/99-serial.cfg b/features/_iso/file.include/etc/kernel/cmdline.d/99-serial.cfg new file mode 100644 index 00000000..e438d02d --- /dev/null +++ b/features/_iso/file.include/etc/kernel/cmdline.d/99-serial.cfg @@ -0,0 +1 @@ +CMDLINE_LINUX="$CMDLINE_LINUX console=ttyS0,115200" diff --git a/features/_iso/file.include/opt/install/install.sh b/features/_iso/file.include/opt/install/install.sh new file mode 100755 index 00000000..906f4831 --- /dev/null +++ b/features/_iso/file.include/opt/install/install.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +set -ue + +thisDir=$(readlink -f $(dirname "${BASH_SOURCE[0]}")) + +targetDisk="$1" + +pushd "$thisDir" + +# remove all HD related boot entries +for e in $(efibootmgr | awk '$NF ~ /^HD/ { print $1 }' | sed "s/Boot\([0-9A-F]*\)./\1/"); do + echo "Removing entry $e" + efibootmgr -B -b "$e" > /dev/null +done + +# prepare disk for repart +sgdisk -Z "$targetDisk" +sgdisk -o "$targetDisk" + +# actually partition and populate with data +mkdir -p /run/source +mount --bind / /run/source +systemd-repart --definitions repart/ --json=pretty --dry-run=off --copy-source=/run/source/ "$targetDisk" + +sleep 5 + +# prepare mounts for chroot env +target="/run/chroot" +mkdir "$target" +mount /dev/disk/by-label/ROOT "$target" +mount /dev/disk/by-label/ESP "$target/efi" + +# prepare extra mounts +pushd "$target" > /dev/null +mount -t proc proc proc +mount -t sysfs sys sys +mount --bind /dev dev + +# regenerate initrd and generate loader entries +chroot "$target" dracut -f /boot/initrd.img-"$(uname -r)" + +if mount --bind /sys/firmware/efi/efivars "$target/sys/firmware/efi/efivars"; then + # efi + chroot "$target" bootctl install + chroot "$target" kernel-install add "$(uname -r)" "/boot/vmlinuz-$(uname -r)" "/boot/initrd.img-$(uname -r)" +else + # legacy + chroot "${target}" sfdisk --part-attrs "${targetDisk}" 1 LegacyBIOSBootable + chroot "${target}" dd if="/usr/lib/SYSLINUX/gptmbr.bin" of="${targetDisk}" bs=440 count=1 conv=notrunc + chroot "${target}" mkdir -p /efi/syslinux + chroot "${target}" cp /usr/lib/syslinux/modules/bios/menu.c32 /efi/syslinux/ + chroot "${target}" cp /usr/lib/syslinux/modules/bios/libutil.c32 /efi/syslinux/ + chroot "${target}" syslinux --directory syslinux --install /dev/disk/by-label/ESP + mkdir /run/chroot/efi/Default + chroot "$target" kernel-install add "$(uname -r)" "/boot/vmlinuz-$(uname -r)" "/boot/initrd.img-$(uname -r)" + chroot "${target}" update-syslinux +fi + +echo "Safe to reboot" diff --git a/features/_iso/file.include/opt/install/repart/00-efi.conf b/features/_iso/file.include/opt/install/repart/00-efi.conf new file mode 100644 index 00000000..d71d8caa --- /dev/null +++ b/features/_iso/file.include/opt/install/repart/00-efi.conf @@ -0,0 +1,8 @@ +# modify only the size to fit your needs +[Partition] +Type=esp +Format=vfat +SizeMinBytes=1024M +SizeMaxBytes=1024M +Label=ESP +MountPoint=/efi diff --git a/features/_iso/file.include/opt/install/repart/10-root.conf b/features/_iso/file.include/opt/install/repart/10-root.conf new file mode 100644 index 00000000..617337f0 --- /dev/null +++ b/features/_iso/file.include/opt/install/repart/10-root.conf @@ -0,0 +1,9 @@ +# modify only the size to fit your needs, do not specify the size to use whatever space is left on disk +[Partition] +Type=root +#SizeMinBytes=2G +#SizeMaxBytes=2G +CopyFiles=/ +CopyFiles=/boot +Label=ROOT +MountPoint=/ diff --git a/features/_iso/image.iso b/features/_iso/image.iso new file mode 100755 index 00000000..2c875f5a --- /dev/null +++ b/features/_iso/image.iso @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +set -euo pipefail + +input="$(realpath -- "$1")" +output="$(realpath -- "$2")" + +dir="$(mktemp -d)" +pushd "$dir" > /dev/null + +export PATH="/builder/image.d:$PATH" + +chroot_dir="$(mktemp -d)" +mount -t tmpfs tmpfs "$chroot_dir" +tar --extract --xattrs --xattrs-include '*' --directory "$chroot_dir" < "$input" + +mount --rbind --make-rprivate /proc "$chroot_dir/proc" +mount --rbind --make-rprivate /sys "$chroot_dir/sys" +mount --rbind --make-rprivate /dev "$chroot_dir/dev" +mount --bind /usr/bin/false "${chroot_dir}/usr/bin/systemd-detect-virt" + +kernel=$(echo "${chroot_dir}"/boot/vmlinuz-* | tr " " '\n' | cut -d- -f 2- | sort -V | tail -1) +chroot "$chroot_dir" dracut -f /tmp/initrd "${kernel}" -m "bash systemd systemd-initrd kernel-modules kernel-modules-extra terminfo dracut-systemd shutdown dmsquash-live" --reproducible + +# we use ukify because dracut 059 and systemd 254 don't mix, dracut generate a broken uki +# https://github.com/dracutdevs/dracut/issues/2431 +# TODO: fix when dracut is fixed +#chroot "${chroot_dir}" dracut -f /tmp/unified ${kernel} --uefi --kernel-cmdline "console=tty0 console=ttyS0,115200 rd.live.squashimg=squashfs.img root=live:CDLABEL=GardenlinuxISO rd.live.overlay.overlayfs rd.live.dir=live rd.live.ram" -m "bash systemd systemd-initrd kernel-modules kernel-modules-extra terminfo dracut-systemd shutdown dmsquash-live" --reproducible +chroot "${chroot_dir}" /lib/systemd/ukify build --output=/tmp/unified --linux=/boot/vmlinuz-"${kernel}" --initrd=/tmp/initrd --cmdline="console=tty0 console=ttyS0,115200 rd.live.squashimg=squashfs.img root=live:CDLABEL=GardenlinuxISO rd.live.overlay.overlayfs rd.live.dir=live rd.live.ram" + +umount -l "$chroot_dir/proc" +umount -l "$chroot_dir/sys" +umount -l "$chroot_dir/dev" +umount "${chroot_dir}/usr/bin/systemd-detect-virt" + +mkdir CD_root +mkdir CD_root/{isolinux,images,kernel,boot,boot/images,boot/syslinux,live} + +mksquashfs "$chroot_dir" "CD_root/live/squashfs.img" -comp lzo +cp "${chroot_dir}/boot/"vmlinuz* "CD_root/boot/images/vmlinuz" +mv "${chroot_dir}/tmp/"initrd* "CD_root/boot/images/initrd" +mv "${chroot_dir}/tmp/unified" bootx64.efi + +#TODO: determine proper size +dd if=/dev/zero of=efiboot.img bs=512 count=131072 +mkfs.msdos -F 16 -n 'EFIBOOTISO' efiboot.img +mmd -i efiboot.img ::EFI +mmd -i efiboot.img ::EFI/BOOT +mcopy -i efiboot.img bootx64.efi ::EFI/BOOT/BOOTX64.EFI + +mv efiboot.img CD_root/isolinux/ +cp "${chroot_dir}/usr/lib/ISOLINUX/isolinux.bin" CD_root/isolinux/ +cp "${chroot_dir}/usr/lib/ISOLINUX/isohdpfx.bin" CD_root/isolinux/ +cp "${chroot_dir}/usr/lib/syslinux/modules/bios/ldlinux.c32" CD_root/isolinux + +cat << EOF > CD_root/isolinux/isolinux.cfg +PATH /boot/syslinux +DEFAULT loadconfig + +LABEL loadconfig + CONFIG /boot/syslinux/syslinux.cfg +EOF + +cat << EOF > CD_root/boot/syslinux/syslinux.cfg +MENU TITLE gardenlinux +DEFAULT GardenlinuxRam + +LABEL GardenlinuxRam +MENU LABEL Gardenlinux Live in RAM +LINUX /boot/images/vmlinuz console=tty0 console=ttyS0,115200 rd.live.squashimg=squashfs.img root=live:CDLABEL=GardenlinuxISO rd.live.overlay.overlayfs rd.live.dir=live rd.live.ram +INITRD /boot/images/initrd +EOF + +# TODO: make this reproducible +xorriso -as mkisofs \ + -volid "GardenlinuxISO" \ + -o "${output}" \ + -isohybrid-mbr "${chroot_dir}/usr/lib/ISOLINUX/isohdpfx.bin" \ + -c isolinux/boot.cat \ + -b isolinux/isolinux.bin \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -eltorito-alt-boot \ + -e isolinux/efiboot.img \ + -no-emul-boot \ + -isohybrid-gpt-basdat \ + CD_root diff --git a/features/_iso/info.yaml b/features/_iso/info.yaml new file mode 100644 index 00000000..302d84a9 --- /dev/null +++ b/features/_iso/info.yaml @@ -0,0 +1,6 @@ +description: "iso" +type: flag +features: + exclude: + - _selinux + - sap diff --git a/features/_iso/pkg.include b/features/_iso/pkg.include new file mode 100644 index 00000000..b70528d8 --- /dev/null +++ b/features/_iso/pkg.include @@ -0,0 +1,8 @@ +dracut +dracut-core +dracut-live +binutils +isolinux +python3-pefile +systemd-ukify +gdisk diff --git a/features/_iso/test/autologin.disable b/features/_iso/test/autologin.disable new file mode 100644 index 00000000..e69de29b diff --git a/features/_iso/test/test_capabilities.py b/features/_iso/test/test_capabilities.py new file mode 100644 index 00000000..c0048aee --- /dev/null +++ b/features/_iso/test/test_capabilities.py @@ -0,0 +1 @@ +from helper.tests.capabilities import capabilities as test_capabilities diff --git a/features/_iso/test/test_packages_musthave.py b/features/_iso/test/test_packages_musthave.py new file mode 100644 index 00000000..4b2783d2 --- /dev/null +++ b/features/_iso/test/test_packages_musthave.py @@ -0,0 +1 @@ +from helper.tests.packages_musthave import packages_musthave as test_packages_musthave diff --git a/flavors.yaml b/flavors.yaml index 5dd93a8a..a99b5107 100644 --- a/flavors.yaml +++ b/flavors.yaml @@ -41,6 +41,14 @@ targets: test: true test-platform: false publish: false + - features: + - sci + - _iso + arch: amd64 + build: true + test: true + test-platform: false + publish: false # this is needed as bare_flavors step in build.yml is currently hard wired - name: bare category: container