mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-06 16:40:47 +00:00
65190700cb
Currently there is no support for generating armv7 vm images in the release artifacts. In fact in terms of release artifacts and architecture there is no good reason to have a vm release artifact for armv7 as those are mostly used in SOCs or embedded boards. However considering that developers actually do need an easy way to test armv7 with a vm running this is really important. As part of pre-commit ci for developers this can be really helpful for the end developers. Approved by: cperciva, imp, re Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D43952
332 lines
7.7 KiB
Bash
332 lines
7.7 KiB
Bash
#!/bin/sh
|
|
#
|
|
#
|
|
#
|
|
# Common functions for virtual machine image build scripts.
|
|
#
|
|
|
|
scriptdir=$(dirname $(realpath $0))
|
|
. ${scriptdir}/../../tools/boot/install-boot.sh
|
|
|
|
export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
|
|
trap "cleanup" INT QUIT TRAP ABRT TERM
|
|
|
|
# Platform-specific large-scale setup
|
|
# Most platforms use GPT, so put that as default, then special cases
|
|
PARTSCHEME=gpt
|
|
ROOTLABEL="gpt"
|
|
case "${TARGET}:${TARGET_ARCH}" in
|
|
powerpc:powerpc*)
|
|
PARTSCHEME=mbr
|
|
ROOTLABEL="ufs"
|
|
NOSWAP=yes # Can't label swap partition with MBR, so no swap
|
|
;;
|
|
esac
|
|
|
|
err() {
|
|
printf "${@}\n"
|
|
cleanup
|
|
return 1
|
|
}
|
|
|
|
cleanup() {
|
|
if [ -c "${DESTDIR}/dev/null" ]; then
|
|
umount_loop ${DESTDIR}/dev 2>/dev/null
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
vm_create_base() {
|
|
|
|
mkdir -p ${DESTDIR}
|
|
|
|
return 0
|
|
}
|
|
|
|
vm_copy_base() {
|
|
# Defunct
|
|
}
|
|
|
|
vm_install_base() {
|
|
# Installs the FreeBSD userland/kernel to the virtual machine disk.
|
|
|
|
cd ${WORLDDIR} && \
|
|
make DESTDIR=${DESTDIR} \
|
|
installworld installkernel distribution || \
|
|
err "\n\nCannot install the base system to ${DESTDIR}."
|
|
|
|
# Bootstrap etcupdate(8) database.
|
|
mkdir -p ${DESTDIR}/var/db/etcupdate
|
|
etcupdate extract -B \
|
|
-M "TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH}" \
|
|
-s ${WORLDDIR} -d ${DESTDIR}/var/db/etcupdate
|
|
|
|
echo '# Custom /etc/fstab for FreeBSD VM images' \
|
|
> ${DESTDIR}/etc/fstab
|
|
if [ "${VMFS}" != zfs ]; then
|
|
echo "/dev/${ROOTLABEL}/rootfs / ${VMFS} rw 1 1" \
|
|
>> ${DESTDIR}/etc/fstab
|
|
fi
|
|
if [ -z "${NOSWAP}" ]; then
|
|
echo '/dev/gpt/swapfs none swap sw 0 0' \
|
|
>> ${DESTDIR}/etc/fstab
|
|
fi
|
|
|
|
local hostname
|
|
hostname="$(echo $(uname -o) | tr '[:upper:]' '[:lower:]')"
|
|
echo "hostname=\"${hostname}\"" >> ${DESTDIR}/etc/rc.conf
|
|
if [ "${VMFS}" = zfs ]; then
|
|
echo "zfs_enable=\"YES\"" >> ${DESTDIR}/etc/rc.conf
|
|
echo "zpool_reguid=\"zroot\"" >> ${DESTDIR}/etc/rc.conf
|
|
echo "zpool_upgrade=\"zroot\"" >> ${DESTDIR}/etc/rc.conf
|
|
fi
|
|
|
|
if ! [ -z "${QEMUSTATIC}" ]; then
|
|
export EMULATOR=/qemu
|
|
cp ${QEMUSTATIC} ${DESTDIR}/${EMULATOR}
|
|
fi
|
|
|
|
mkdir -p ${DESTDIR}/dev
|
|
mount -t devfs devfs ${DESTDIR}/dev
|
|
chroot ${DESTDIR} ${EMULATOR} /usr/bin/newaliases
|
|
chroot ${DESTDIR} ${EMULATOR} /bin/sh /etc/rc.d/ldconfig forcestart
|
|
umount_loop ${DESTDIR}/dev
|
|
|
|
cp /etc/resolv.conf ${DESTDIR}/etc/resolv.conf
|
|
|
|
if [ "${VMFS}" = zfs ]; then
|
|
echo "kern.geom.label.disk_ident.enable=0" >> ${DESTDIR}/boot/loader.conf
|
|
echo "zfs_load=YES" >> ${DESTDIR}/boot/loader.conf
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
vm_extra_install_base() {
|
|
# Prototype. When overridden, runs extra post-installworld commands
|
|
# as needed, based on the target virtual machine image or cloud
|
|
# provider image target.
|
|
|
|
return 0
|
|
}
|
|
|
|
vm_extra_enable_services() {
|
|
if [ ! -z "${VM_RC_LIST}" ]; then
|
|
for _rcvar in ${VM_RC_LIST}; do
|
|
echo ${_rcvar}_enable="YES" >> ${DESTDIR}/etc/rc.conf
|
|
done
|
|
fi
|
|
|
|
if [ -z "${VMCONFIG}" -o -c "${VMCONFIG}" ]; then
|
|
echo 'ifconfig_DEFAULT="DHCP inet6 accept_rtadv"' >> \
|
|
${DESTDIR}/etc/rc.conf
|
|
# Expand the filesystem to fill the disk.
|
|
echo 'growfs_enable="YES"' >> ${DESTDIR}/etc/rc.conf
|
|
touch ${DESTDIR}/firstboot
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
vm_extra_install_packages() {
|
|
if [ -z "${VM_EXTRA_PACKAGES}" ]; then
|
|
return 0
|
|
fi
|
|
mkdir -p ${DESTDIR}/dev
|
|
mount -t devfs devfs ${DESTDIR}/dev
|
|
chroot ${DESTDIR} ${EMULATOR} env ASSUME_ALWAYS_YES=yes \
|
|
/usr/sbin/pkg bootstrap -y
|
|
for p in ${VM_EXTRA_PACKAGES}; do
|
|
chroot ${DESTDIR} ${EMULATOR} env ASSUME_ALWAYS_YES=yes \
|
|
/usr/sbin/pkg install -y ${p}
|
|
done
|
|
umount_loop ${DESTDIR}/dev
|
|
|
|
return 0
|
|
}
|
|
|
|
vm_extra_install_ports() {
|
|
# Prototype. When overridden, installs additional ports within the
|
|
# virtual machine environment.
|
|
|
|
return 0
|
|
}
|
|
|
|
vm_extra_pre_umount() {
|
|
# Prototype. When overridden, performs additional tasks within the
|
|
# virtual machine environment prior to unmounting the filesystem.
|
|
# Note: When overriding this function, removing resolv.conf in the
|
|
# disk image must be included.
|
|
|
|
if ! [ -z "${QEMUSTATIC}" ]; then
|
|
rm -f ${DESTDIR}/${EMULATOR}
|
|
fi
|
|
rm -f ${DESTDIR}/etc/resolv.conf
|
|
return 0
|
|
}
|
|
|
|
vm_extra_pkg_rmcache() {
|
|
if [ -e ${DESTDIR}/usr/local/sbin/pkg ]; then
|
|
chroot ${DESTDIR} ${EMULATOR} env ASSUME_ALWAYS_YES=yes \
|
|
/usr/local/sbin/pkg clean -y -a
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
buildfs() {
|
|
local md tmppool
|
|
|
|
case "${VMFS}" in
|
|
ufs)
|
|
makefs ${MAKEFSARGS} -o label=rootfs -o version=2 -o softupdates=1 \
|
|
${VMBASE} ${DESTDIR}
|
|
;;
|
|
zfs)
|
|
makefs -t zfs ${MAKEFSARGS} \
|
|
-o poolname=zroot -o bootfs=zroot/ROOT/default -o rootpath=/ \
|
|
-o fs=zroot\;mountpoint=none \
|
|
-o fs=zroot/ROOT\;mountpoint=none \
|
|
-o fs=zroot/ROOT/default\;mountpoint=/ \
|
|
-o fs=zroot/home\;mountpoint=/home \
|
|
-o fs=zroot/tmp\;mountpoint=/tmp\;exec=on\;setuid=off \
|
|
-o fs=zroot/usr\;mountpoint=/usr\;canmount=off \
|
|
-o fs=zroot/usr/ports\;setuid=off \
|
|
-o fs=zroot/usr/src \
|
|
-o fs=zroot/usr/obj \
|
|
-o fs=zroot/var\;mountpoint=/var\;canmount=off \
|
|
-o fs=zroot/var/audit\;setuid=off\;exec=off \
|
|
-o fs=zroot/var/crash\;setuid=off\;exec=off \
|
|
-o fs=zroot/var/log\;setuid=off\;exec=off \
|
|
-o fs=zroot/var/mail\;atime=on \
|
|
-o fs=zroot/var/tmp\;setuid=off \
|
|
${VMBASE} ${DESTDIR}
|
|
;;
|
|
*)
|
|
echo "Unexpected VMFS value '${VMFS}'"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
umount_loop() {
|
|
DIR=$1
|
|
i=0
|
|
sync
|
|
while ! umount ${DIR}; do
|
|
i=$(( $i + 1 ))
|
|
if [ $i -ge 10 ]; then
|
|
# This should never happen. But, it has happened.
|
|
echo "Cannot umount(8) ${DIR}"
|
|
echo "Something has gone horribly wrong."
|
|
return 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|
|
vm_create_disk() {
|
|
local BOOTFILES BOOTPARTSOFFSET FSPARTTYPE X86GPTBOOTFILE
|
|
|
|
if [ -z "${NOSWAP}" ]; then
|
|
SWAPOPT="-p freebsd-swap/swapfs::${SWAPSIZE}"
|
|
fi
|
|
|
|
if [ -n "${VM_BOOTPARTSOFFSET}" ]; then
|
|
BOOTPARTSOFFSET=":${VM_BOOTPARTSOFFSET}"
|
|
fi
|
|
|
|
case "${VMFS}" in
|
|
ufs)
|
|
FSPARTTYPE=freebsd-ufs
|
|
X86GPTBOOTFILE=i386/gptboot/gptboot
|
|
;;
|
|
zfs)
|
|
FSPARTTYPE=freebsd-zfs
|
|
X86GPTBOOTFILE=i386/gptzfsboot/gptzfsboot
|
|
;;
|
|
*)
|
|
echo "Unexpected VMFS value '${VMFS}'"
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
echo "Creating image... Please wait."
|
|
echo
|
|
|
|
BOOTFILES="$(env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
|
|
WITH_UNIFIED_OBJDIR=yes \
|
|
make -C ${WORLDDIR}/stand -V .OBJDIR)"
|
|
BOOTFILES="$(realpath ${BOOTFILES})"
|
|
MAKEFSARGS="-s ${VMSIZE}"
|
|
|
|
case "${TARGET}:${TARGET_ARCH}" in
|
|
amd64:amd64 | i386:i386)
|
|
ESP=yes
|
|
BOOTPARTS="-b ${BOOTFILES}/i386/pmbr/pmbr \
|
|
-p freebsd-boot/bootfs:=${BOOTFILES}/${X86GPTBOOTFILE}${BOOTPARTSOFFSET}"
|
|
ROOTFSPART="-p ${FSPARTTYPE}/rootfs:=${VMBASE}"
|
|
MAKEFSARGS="$MAKEFSARGS -B little"
|
|
;;
|
|
arm:armv7 | arm64:aarch64 | riscv:riscv64*)
|
|
ESP=yes
|
|
BOOTPARTS=
|
|
ROOTFSPART="-p ${FSPARTTYPE}/rootfs:=${VMBASE}"
|
|
MAKEFSARGS="$MAKEFSARGS -B little"
|
|
;;
|
|
powerpc:powerpc*)
|
|
ESP=no
|
|
BOOTPARTS="-p prepboot:=${BOOTFILES}/powerpc/boot1.chrp/boot1.elf -a 1"
|
|
ROOTFSPART="-p freebsd:=${VMBASE}"
|
|
if [ ${TARGET_ARCH} = powerpc64le ]; then
|
|
MAKEFSARGS="$MAKEFSARGS -B little"
|
|
else
|
|
MAKEFSARGS="$MAKEFSARGS -B big"
|
|
fi
|
|
;;
|
|
*)
|
|
echo "vmimage.subr: unsupported target '${TARGET}:${TARGET_ARCH}'" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [ ${ESP} = "yes" ]; then
|
|
# Create an ESP
|
|
espfilename=$(mktemp /tmp/efiboot.XXXXXX)
|
|
make_esp_file ${espfilename} ${fat32min} ${BOOTFILES}/efi/loader_lua/loader_lua.efi
|
|
BOOTPARTS="${BOOTPARTS} -p efi/efiesp:=${espfilename}"
|
|
|
|
# Add this to fstab
|
|
mkdir -p ${DESTDIR}/boot/efi
|
|
echo "/dev/${ROOTLABEL}/efiesp /boot/efi msdosfs rw 2 2" \
|
|
>> ${DESTDIR}/etc/fstab
|
|
fi
|
|
|
|
echo "Building filesystem... Please wait."
|
|
buildfs
|
|
|
|
echo "Building final disk image... Please wait."
|
|
mkimg -s ${PARTSCHEME} -f ${VMFORMAT} \
|
|
${BOOTPARTS} \
|
|
${SWAPOPT} \
|
|
${ROOTFSPART} \
|
|
-o ${VMIMAGE}
|
|
|
|
echo "Disk image ${VMIMAGE} created."
|
|
|
|
if [ ${ESP} = "yes" ]; then
|
|
rm ${espfilename}
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
vm_extra_create_disk() {
|
|
|
|
return 0
|
|
}
|
|
|