aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat
-rwxr-xr-ximages/freebsd/genimg324+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