From 522e424f4f6c008e946f3822052c3ce9e693374d Mon Sep 17 00:00:00 2001 From: Nikolay Govorov Date: Wed, 8 Jul 2026 01:26:24 +0100 Subject: Rework freebsd image --- images/freebsd/genimg | 324 +++++++++++++++++++----------------------- 1 file changed, 146 insertions(+), 178 deletions(-) diff --git a/images/freebsd/genimg b/images/freebsd/genimg index 59500f8..521bb50 100755 --- a/images/freebsd/genimg +++ b/images/freebsd/genimg @@ -6,135 +6,86 @@ self=$(dirname "$(readlink -f "$0")") cd "$self" +with_ports=false + +while [ $# -gt 0 ]; do + case $1 in + --with-ports) + with_ports=true + shift + ;; + --no-with-ports) + with_ports=false + shift + ;; + --) + shift + break + ;; + -*) + echo "Unknown option $1" >&2 + exit 1 + ;; + *) + break + ;; + esac +done + version=${1:-} arch="${2:-amd64}" -repo=FreeBSD - -# Build a RELEASE image from the published distribution tarballs. -genimg() { - dist_base="https://download.freebsd.org/ftp/releases/$arch/$release" - - dist_files="kernel.txz base.txz base-dbg.txz" - dist_dir="/usr/freebsd-dist/$arch/$release" - mkdir -p "$dist_dir" - for f in $dist_files; do - fetch -m -o "$dist_dir/$f" "$dist_base/$f" - done - - cleanup() { - sync || true - umount /mnt/dev || true - umount /mnt || true - mdconfig -du md0 || true - } - trap cleanup EXIT - - rm -f disk.img - truncate -s 8G disk.img - mdconfig -a -t vnode -f disk.img -u md0 - gpart create -s gpt /dev/md0 - gpart add -t freebsd-boot -l bootfs -b 40 -s 512K md0 - gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 md0 - gpart add -t freebsd-ufs -l rootfs -b 1M md0 - newfs -U /dev/md0p2 - - mount /dev/md0p2 /mnt - - mkdir -p /mnt/dev - mount -t devfs devfs /mnt/dev - - for f in $dist_files; do - tar -C /mnt -xJf "$dist_dir/$f" - done - - echo "/dev/gpt/rootfs / ufs rw,noatime 1 1" >/mnt/etc/fstab - touch /mnt/firstboot - echo 'autoboot_delay="-1"' >>/mnt/boot/loader.conf +case $version in +14.x) + release="14.4-RELEASE" + ;; +15.x) + release="15.1-RELEASE" + ;; +current) + release="16.0" + ;; +*) + echo "usage: ${0##*/} <14.x|15.x|current> [arch]" >&2 + exit 1 + ;; +esac - cat >>/mnt/etc/rc.conf </mnt/etc/resolv.conf - echo "nameserver 9.9.9.9" >>/mnt/etc/resolv.conf - echo "nameserver 1.1.1.1" >>/mnt/etc/resolv.conf - tzsetup -s -C /mnt UTC +rel=${release%%.*} +out="$version/$arch" +rootfs=disk +reposdir=$(pwd)/$rootfs/usr/local/etc/pkg/repos - cat >>/mnt/etc/ssh/sshd_config </mnt/usr/local/etc/pkg/repos/FreeBSD.conf </dev/null || true + chflags -R noschg "$rootfs" || true + rm -rf "$rootfs" disk.img || true } -EOF - - # freebsd-update is only supported for RELEASE - if [ "${release%-RELEASE}" != "$release" ]; then - env PAGER=true /usr/sbin/freebsd-update \ - -b /mnt \ - --currently-running "$release" \ - --not-running-from-cron -F \ - fetch install - fi - - env ASSUME_ALWAYS_YES=YES pkg -c /mnt bootstrap -f - # TODO: remove bash - env ASSUME_ALWAYS_YES=YES pkg -c /mnt install git mercurial bash sudo curl - - git clone https://github.com/freebsd/freebsd-ports /mnt/usr/ports --depth=1 --single-branch - - pw -R /mnt groupadd sudo - pw -R /mnt useradd -n build -u 1000 -s /usr/local/bin/bash -m -w none -G sudo - echo "%sudo ALL=(ALL) NOPASSWD: ALL" >>/mnt/usr/local/etc/sudoers +trap cleanup EXIT - cleanup - trap : EXIT +rm -rf "$rootfs" disk.img +mkdir -p "$rootfs" +mkdir -p "$reposdir" - mkdir -p "$out" - qemu-img convert -f raw -O qcow2 disk.img "$out"/root.img.qcow2 - rm disk.img - - # Filesystem will be enlarged by growfs(7) on next startup - qemu-img resize "$out"/root.img.qcow2 24G -} - -# Build an image entirely from pkg base (used for -CURRENT, which has no -# published release tarballs). -genpkgimg() { - rel=${release%%.*} - - cleanup() { - umount disk/usr/share/keys/pkg || true - chflags -R noschg disk || true - rm -rf disk || true - } - trap cleanup EXIT - - rm -f disk.img - mkdir disk - mkdir -p disk/usr/local/etc/pkg/repos - # pkg -R needs absolute path - reposdir=$(pwd)/disk/usr/local/etc/pkg/repos - - cat >${reposdir}/FreeBSD.conf <"$reposdir"/FreeBSD.conf <>"$reposdir"/FreeBSD.conf <disk/boot/loader.conf + pkg -C /dev/null -R "$reposdir" -r "$rootfs" rquery -g "%n" "FreeBSD*" | + grep -vE "(lib32|dbg|kernel|src|tests)" | + xargs pkg -C /dev/null -R "$reposdir" -r "$rootfs" install -y + if pkg -C /dev/null -R "$reposdir" -r "$rootfs" install -y FreeBSD-kernel-generic-nodebug; then + echo "kernel=kernel.GENERIC-NODEBUG" >"$rootfs"/boot/loader.conf else - pkg -C /dev/null -R ${reposdir} -r disk install -y FreeBSD-kernel-generic + pkg -C /dev/null -R "$reposdir" -r "$rootfs" install -y FreeBSD-kernel-generic fi + ;; - echo "/dev/gpt/rootfs / ufs rw,noatime 1 1" >disk/etc/fstab - touch disk/firstboot - echo 'autoboot_delay="-1"' >>disk/boot/loader.conf +*) + # RELEASE: extract the published distribution tarballs into the tree. + dist_base="https://download.freebsd.org/ftp/releases/$arch/$release" + dist_files="kernel.txz base.txz" + dist_dir="/usr/freebsd-dist/$arch/$release" + + mkdir -p "$dist_dir" + for f in $dist_files; do + fetch -m -o "$dist_dir/$f" "$dist_base/$f" + done + for f in $dist_files; do + tar -C "$rootfs" -xJf "$dist_dir/$f" + done + + # Apply security patches (only defined for -RELEASE). + if [ "${release%-RELEASE}" != "$release" ]; then + env PAGER=true /usr/sbin/freebsd-update \ + -b "$rootfs" \ + --currently-running "$release" \ + --not-running-from-cron -F \ + fetch install + fi + ;; + +esac - cat >>disk/etc/rc.conf <"$rootfs"/etc/fstab +touch "$rootfs"/firstboot +echo 'autoboot_delay="-1"' >>"$rootfs"/boot/loader.conf + +cat >>"$rootfs"/etc/rc.conf <disk/etc/resolv.conf <"$rootfs"/etc/resolv.conf <>disk/etc/ssh/sshd_config <>"$rootfs"/etc/ssh/sshd_config <>disk/usr/local/etc/sudoers - - makefs -s 5g -B little -o label=rootfs -o version=2 -o softupdates=1 disk.img disk - mkdir -p "$out" - mkimg -s gpt \ - -b disk/boot/pmbr \ - -C 16G \ - -p freebsd-boot:=disk/boot/gptboot \ - -p freebsd-ufs/rootfs:=disk.img \ - -f qcow2 \ - -o "$out"/root.img.qcow2 - - cleanup - trap : EXIT - - rm disk.img -} - -out="$version/$arch" - -case $version in -14.x) - release="14.4-RELEASE" - genimg - ;; -15.x) - release="15.1-RELEASE" - repo="FreeBSD-ports" - genimg - ;; -current) - release="16.0" - genpkgimg - ;; -*) - echo "usage: ${0##*/} <14.x|15.x|current> [arch]" >&2 - exit 1 - ;; -esac +pw -R "$rootfs" groupadd sudo +pw -R "$rootfs" useradd -n build -u 1000 -s /bin/sh -m -w none -G sudo +echo "%sudo ALL=(ALL) NOPASSWD: ALL" >>"$rootfs"/usr/local/etc/sudoers + +# Build the UFS image straight from the directory tree, then wrap it in a +# bootable GPT qcow2 -- no md(4), mount or raw->qcow2 conversion needed. +makefs -s 8g -B little -o label=rootfs -o version=2 -o softupdates=1 disk.img "$rootfs" +mkdir -p "$out" +mkimg -s gpt \ + -b "$rootfs"/boot/pmbr \ + -C 16G \ + -p freebsd-boot:="$rootfs"/boot/gptboot \ + -p freebsd-ufs/rootfs:=disk.img \ + -f qcow2 \ + -o "$out"/root.img.qcow2 + +cleanup +trap : EXIT -- Gilti