diff options
Diffstat
| -rwxr-xr-x | images/freebsd/genimg | 324 | +146 −178 |
1 files 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 <<EOF -ntpd_enable=YES -sshd_enable=YES -growfs_enable=YES -hostname="build" -ifconfig_DEFAULT="inet 10.0.2.15 netmask 255.255.255.0" -defaultrouter="10.0.2.2" -EOF - echo "nameserver 8.8.8.8" >/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 <<EOF -PermitRootLogin yes -PasswordAuthentication yes -PermitEmptyPasswords yes -UsePAM no -EOF +export ABI="FreeBSD:$rel:$arch" +export IGNORE_OSVERSION=yes - mkdir -p /mnt/usr/local/etc/pkg/repos/ - cat >/mnt/usr/local/etc/pkg/repos/FreeBSD.conf <<EOF -$repo: { - url: pkg+http://pkg.FreeBSD.org/\$\{ABI\}/latest - enabled: yes +cleanup() { + umount "$rootfs"/usr/share/keys/pkg 2>/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 <<EOF +# Package repository used both to install the base (on -CURRENT) and to add +# tooling below. ${ABI} is expanded by pkg, not the shell. +cat >"$reposdir"/FreeBSD.conf <<EOF FreeBSD: { url: pkg+http://pkg.FreeBSD.org/\$\{ABI\}/latest enabled: yes mirror_type: srv signature_type: fingerprint } +EOF + +case $version in + +current) + # -CURRENT has no release tarballs; assemble the base from pkg base. + cat >>"$reposdir"/FreeBSD.conf <<EOF FreeBSD-base: { url: pkg+http://pkg.FreeBSD.org/\$\{ABI\}/base_latest enabled: yes @@ -142,26 +93,68 @@ FreeBSD-base: { signature_type: fingerprint } EOF - export ABI="FreeBSD:$rel:$arch" - export IGNORE_OSVERSION=yes - mkdir -p disk/usr/share/keys/pkg - mount -t nullfs /usr/share/keys/pkg disk/usr/share/keys/pkg - pkg -C /dev/null -R ${reposdir} -r disk update - umount disk/usr/share/keys/pkg + # The base is not installed yet, so borrow the host's signing keys for + # the first fetch. + mkdir -p "$rootfs"/usr/share/keys/pkg + mount -t nullfs /usr/share/keys/pkg "$rootfs"/usr/share/keys/pkg + pkg -C /dev/null -R "$reposdir" -r "$rootfs" update + umount "$rootfs"/usr/share/keys/pkg # XXX replace by group FreeBSD-base the day it is implemented :D - pkg -C /dev/null -R ${reposdir} -r disk rquery -g "%n" "FreeBSD*" | grep -vE "(lib32|dbg|kernel|src|tests)" | - xargs pkg -C /dev/null -R ${reposdir} -r disk install -y - if pkg -C /dev/null -R ${reposdir} -r disk install -y FreeBSD-kernel-generic-nodebug; then - echo "kernel=kernel.GENERIC-NODEBUG" >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 <<EOF +# --- Common: tooling, guest configuration, image assembly. --- +# pkg runs on the host against the alternate root, so it uses the host's +# resolver; the guest resolv.conf written below is purely for runtime. +pkg -C /dev/null -R "$reposdir" -r "$rootfs" update +pkg -C /dev/null -R "$reposdir" -r "$rootfs" install -y \ + pkg git-lite mercurial sudo curl +pkg -C /dev/null -R "$reposdir" -r "$rootfs" clean -ay + + +if [ "$with_ports" = true ]; then + git clone https://github.com/freebsd/freebsd-ports "$rootfs"/usr/ports \ + --depth=1 --single-branch +fi + +echo "/dev/gpt/rootfs / ufs rw,noatime 1 1" >"$rootfs"/etc/fstab +touch "$rootfs"/firstboot +echo 'autoboot_delay="-1"' >>"$rootfs"/boot/loader.conf + +cat >>"$rootfs"/etc/rc.conf <<EOF ntpd_enable=YES sshd_enable=YES growfs_enable=YES @@ -169,61 +162,36 @@ hostname="build" ifconfig_DEFAULT="inet 10.0.2.15 netmask 255.255.255.0" defaultrouter="10.0.2.2" EOF - cat >disk/etc/resolv.conf <<EOF + +cat >"$rootfs"/etc/resolv.conf <<EOF nameserver 8.8.8.8 -nameserver 8.8.4.4 +nameserver 9.9.9.9 +nameserver 1.1.1.1 EOF - tzsetup -s -C disk UTC +tzsetup -s -C "$rootfs" UTC - cat >>disk/etc/ssh/sshd_config <<EOF +cat >>"$rootfs"/etc/ssh/sshd_config <<EOF PermitRootLogin yes PasswordAuthentication yes PermitEmptyPasswords yes UsePAM no EOF - # TODO: remove bash - pkg -r disk -R ${reposdir} install -y pkg git-lite mercurial bash sudo curl - pkg -r disk -R ${reposdir} clean -ay - - pw -R disk groupadd sudo - pw -R disk useradd -n build -u 1000 -s /usr/local/bin/bash -m -w none -G sudo - echo "%sudo ALL=(ALL) NOPASSWD: ALL" >>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 |
