diff --git a/release/Makefile.vm b/release/Makefile.vm index b711d7891f11..0dc7bdbe1fe5 100644 --- a/release/Makefile.vm +++ b/release/Makefile.vm @@ -1,286 +1,291 @@ # # # # Makefile for building virtual machine and cloud provider disk images. # VMTARGETS= vm-image VMFORMATS?= vhd vmdk qcow2 raw .if ${TARGET_ARCH} == riscv64 VMSIZE?= 6144m .else VMSIZE?= 5120m .endif VMFS?= ufs VMFSLIST?= ufs zfs SWAPSIZE?= 1g VMBASE?= vm VHD_DESC= Azure, VirtualPC, Hyper-V, Xen disk image VMDK_DESC= VMWare, VirtualBox disk image QCOW2_DESC= Qemu, KVM disk image RAW_DESC= Unformatted raw disk image .if defined(WITHOUT_QEMU) CLOUDWARE_TYPES?= \ BASIC-CI .else CLOUDWARE_TYPES?= AZURE \ BASIC-CI \ BASIC-CLOUDINIT \ EC2 \ GCE \ ORACLE \ VAGRANT .endif AZURE_FORMAT= vhdf AZURE_FSLIST?= ufs zfs AZURE_DESC= Microsoft Azure platform image BASIC-CI_FORMAT= raw BASIC-CI_FSLIST?= ufs BASIC-CI_DESC= Image for CI BASIC-CLOUDINIT_FORMAT= raw qcow2 BASIC-CLOUDINIT_FSLIST?= ufs zfs BASIC-CLOUDINIT_DESC?= Images for VM with cloudinit disk config support EC2_FORMAT= raw EC2_FSLIST?= ufs zfs EC2_FLAVOURS?= BASE CLOUD-INIT SMALL EC2-BASE_DESC= Amazon EC2 image EC2-CLOUD-INIT_DESC= Amazon EC2 Cloud-Init image EC2-SMALL_DESC= Amazon EC2 small image GCE_FORMAT= raw GCE_FSLIST?= ufs zfs GCE_DESC= Google Compute Engine image ORACLE_FORMAT= raw ORACLE_FSLIST?= ufs zfs ORACLE_DESC= Oracle Cloud Infrastructure image OPENSTACK_FORMAT=qcow2 OPENSTACK_FSLIST?= ufs OPENSTACK_DESC= OpenStack platform image VAGRANT_FORMAT= vmdk VAGRANT_FSLIST?= ufs VAGRANT_FLAVOURS?= VIRTUALBOX VMWARE VAGRANT-VIRTUALBOX_DESC= Vagrant Image for VirtualBox VAGRANT-VMWARE_DESC= Vagrant Image for VMWare .for _CWT in ${CLOUDWARE_TYPES} . if defined(${_CWT}_FLAVOURS) . for _CWF in ${${_CWT}_FLAVOURS} CLOUDWARE_GEN+= ${_CWT}-${_CWF} ${_CWT}-${_CWF}_FORMAT?= ${${_CWT}_FORMAT} ${_CWT}-${_CWF}_FSLIST?= ${${_CWT}_FSLIST} ${_CWT}-${_CWF}_DESC?= ${${_CWT}_DESC} . endfor . else CLOUDWARE_GEN+= ${_CWT} . endif .endfor CLOUDWARE?= ${CLOUDWARE_GEN} .for _V in TYPE BRANCH REVISION . if !defined(${_V}) || empty(${_V}) ${_V}!= eval $$(awk '/^${_V}=/{print}' ${.CURDIR}/../sys/conf/newvers.sh); echo $$${_V} . endif .endfor emulator-portinstall: .if !exists(/usr/local/bin/qemu-${TARGET_ARCH}-static) .if exists(${PORTSDIR}/emulators/qemu-user-static/Makefile) env - UNAME_r=${UNAME_r} PATH=$$PATH \ make -C ${PORTSDIR}/emulators/qemu-user-static \ BATCH=1 WRKDIRPREFIX=/tmp/ports DISTDIR=/tmp/distfiles \ all install clean .else .if !exists(/usr/local/sbin/pkg-static) env ASSUME_ALWAYS_YES=yes pkg bootstrap -y .endif env ASSUME_ALWAYS_YES=yes pkg install -y emulators/qemu-user-static .endif .endif touch ${.TARGET} .if ${TARGET_ARCH} != ${MACHINE_ARCH} && !defined(WITHOUT_QEMU) .if ( ${TARGET_ARCH} != "i386" ) || ( ${MACHINE_ARCH} != "amd64" ) QEMUSTATIC=/usr/local/bin/qemu-${TARGET_ARCH}-static QEMUTGT=emulator-portinstall .endif .endif QEMUTGT?= .if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE) +.if (defined(WITHOUT_QEMU) && !defined(NO_ROOT)) || \ + (!defined(WITHOUT_QEMU) && defined(NO_ROOT)) +.error WITHOUT_QEMU requires NO_ROOT (and vice versa) +.endif . for _CW in ${CLOUDWARE} . if exists(${.CURDIR}/tools/${_CW:tl}.conf) && !defined(${_CW:tu}CONF) ${_CW:tu}CONF?= ${.CURDIR}/tools/${_CW:tl}.conf . endif . for _FS in ${${_CW:tu}_FSLIST} . for _FMT in ${${_CW:tu}_FORMAT} CLOUDTARGETS+= cw-${_CW:tl}-${_FS}-${_FMT} CLEANDIRS+= cw-${_CW:tl}-${_FS}-${_FMT} CLEANFILES+= ${_CW:tl}.${_FS}.${_FMT}.img \ ${_CW:tl}.${_FS}.${_FMT} \ ${_CW:tl}.${_FS}.${_FMT}.raw ${_CW:tu}${_FS:tu}${_FMT:tu}IMAGE= ${_CW:tl}.${_FS}.${_FMT} cw-${_CW:tl}-${_FS}-${_FMT}: ${QEMUTGT} mkdir -p ${.OBJDIR}/${.TARGET} env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} SWAPSIZE=${SWAPSIZE} \ QEMUSTATIC=${QEMUSTATIC} \ WITHOUT_QEMU=${WITHOUT_QEMU:Dtrue} \ + NO_ROOT=${NO_ROOT:Dtrue} \ ${.CURDIR}/scripts/mk-vmimage.sh \ -C ${.CURDIR}/tools/vmimage.subr -d ${.OBJDIR}/${.TARGET} -F ${_FS} \ -i ${.OBJDIR}/${_CW:tl}.${_FS}.${_FMT}.img -s ${VMSIZE} -f ${_FMT} \ -S ${WORLDDIR} -o ${.OBJDIR}/${${_CW:tu}${_FS:tu}${_FMT:tu}IMAGE} -c ${${_CW:tu}CONF} touch ${.TARGET} . endfor . endfor # Hardlinks from "foo.${FMT}" to "foo-${VMFS}.${FMT}". These can go away once # all of the cloudware code knows how to handle multiple filesystem images (or # at least knows the name of the UFS image). . for _FMT in ${${_CW:tu}_FORMAT} CLOUDTARGETS+= cw-${_CW:tl}-${_FMT} CLEANFILES+= ${_CW:tl}.${_FMT} ${_CW:tu}${_FMT:tu}IMAGE= ${_CW:tl}.${_FMT} cw-${_CW:tl}-${_FMT}: cw-${_CW:tl}-${VMFS}-${_FMT} ln -f ${${_CW:tu}${VMFS:tu}${_FMT:tu}IMAGE} ${${_CW:tu}${_FMT:tu}IMAGE} . endfor # Targets without a disk format listed are the first disk format on the list . for _FS in ${${_CW:tu}_FSLIST} ${_CW:tu}${_FS:tu}IMAGE= ${_CW:tl}.${_FS}.${${_CW:tu}_FORMAT:[1]} cw-${_CW:tl}-${_FS}: cw-${_CW:tl}-${_FS}-${${_CW:tu}_FORMAT:[1]} . endfor ${_CW:tu}IMAGE= ${_CW:tl}.${${_CW:tu}_FORMAT:[1]} cw-${_CW:tl}: cw-${_CW:tl}-${${_CW:tu}_FORMAT:[1]} . endfor .endif .if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) CLEANFILES+= vm-image . for FORMAT in ${VMFORMATS} . for FS in ${VMFSLIST} CLEANDIRS+= vm-image-${FORMAT}-${FS} CLEANFILES+= ${FORMAT}.${FS}.img CLEANFILES+= ${VMBASE}.${FS}.${FORMAT} . endfor . endfor .endif vm-base: vm-image vm-image: ${QEMUTGT} .if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) . for FORMAT in ${VMFORMATS} . for FS in ${VMFSLIST} mkdir -p ${.OBJDIR}/${.TARGET}-${FORMAT}-${FS} env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} SWAPSIZE=${SWAPSIZE} \ QEMUSTATIC=${QEMUSTATIC} \ WITHOUT_QEMU=${WITHOUT_QEMU:Dtrue} \ ${.CURDIR}/scripts/mk-vmimage.sh \ -C ${.CURDIR}/tools/vmimage.subr \ -d ${.OBJDIR}/${.TARGET}-${FORMAT}-${FS} -F ${FS} \ -i ${.OBJDIR}/${FORMAT}.${FS}.img -s ${VMSIZE} -f ${FORMAT} \ -S ${WORLDDIR} -o ${.OBJDIR}/${VMBASE}.${FS}.${FORMAT} . endfor . endfor .endif touch ${.TARGET} vm-cloudware: ${CLOUDTARGETS} list-vmtargets: list-cloudware @${ECHO} @${ECHO} "Supported virtual machine disk image formats:" .for FORMAT in ${VMFORMATS:tu} @${ECHO} " ${FORMAT:tl}: ${${FORMAT}_DESC}" .endfor list-cloudware: .if !empty(CLOUDWARE) @${ECHO} @${ECHO} "Supported cloud hosting provider images:" . for _CW in ${CLOUDWARE} @${ECHO} " ${_CW:tu}: ${${_CW:tu}_DESC}" . endfor .endif vm-install: .if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) mkdir -p ${DESTDIR}/vmimages . for FORMAT in ${VMFORMATS} . for FS in ${VMFSLIST} cp -p ${VMBASE}.${FS}.${FORMAT} \ ${DESTDIR}/vmimages/${OSRELEASE}-${FS}.${FORMAT} . endfor . endfor . if defined(WITH_COMPRESSED_VMIMAGES) && !empty(WITH_COMPRESSED_VMIMAGES) . for FORMAT in ${VMFORMATS} . for FS in ${VMFSLIST} # Don't keep the originals. There is a copy in ${.OBJDIR} if needed. ${XZ_CMD} ${DESTDIR}/vmimages/${OSRELEASE}-${FS}.${FORMAT} . endfor . endfor . endif cd ${DESTDIR}/vmimages && sha512 ${OSRELEASE}* > \ ${DESTDIR}/vmimages/CHECKSUM.SHA512 cd ${DESTDIR}/vmimages && sha256 ${OSRELEASE}* > \ ${DESTDIR}/vmimages/CHECKSUM.SHA256 .endif cloud-install-BASIC-CI: mkdir -p ${DESTDIR}/ciimages .for _FS in ${BASIC-CI_FSLIST} . for _FMT in ${BASIC-CI_FORMAT} cp -p ${.OBJDIR}/${BASIC-CI${_FS:tu}${_FMT:tu}IMAGE} \ ${DESTDIR}/ciimages/${OSRELEASE}-BASIC-CI-${_FS}.${_FMT} ${XZ_CMD} ${DESTDIR}/ciimages/${OSRELEASE}-BASIC-CI-${_FS}.${_FMT} . endfor .endfor cd ${DESTDIR}/ciimages && sha512 ${OSRELEASE}* > \ ${DESTDIR}/ciimages/CHECKSUM.SHA512 cd ${DESTDIR}/ciimages && sha256 ${OSRELEASE}* > \ ${DESTDIR}/ciimages/CHECKSUM.SHA256 cloud-install-BASIC-CLOUDINIT: mkdir -p ${DESTDIR}/vmimages .for _FS in ${BASIC-CLOUDINIT_FSLIST} . for _FMT in ${BASIC-CLOUDINIT_FORMAT} cp -p ${.OBJDIR}/${BASIC-CLOUDINIT${_FS:tu}${_FMT:tu}IMAGE} \ ${DESTDIR}/vmimages/${OSRELEASE}-BASIC-CLOUDINIT-${_FS}.${_FMT} ${XZ_CMD} ${DESTDIR}/vmimages/${OSRELEASE}-BASIC-CLOUDINIT-${_FS}.${_FMT} . endfor .endfor cd ${DESTDIR}/vmimages && sha512 ${OSRELEASE}* > \ ${DESTDIR}/vmimages/CHECKSUM.SHA512 cd ${DESTDIR}/vmimages && sha256 ${OSRELEASE}* > \ ${DESTDIR}/vmimages/CHECKSUM.SHA256 CLOUD_INSTALL_TGTS= .if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) . for _CW in ${CLOUDWARE} . if target(cloud-install-${_CW}) CLOUD_INSTALL_TGTS+= cloud-install-${_CW} . endif . endfor .endif cloud-install: ${CLOUD_INSTALL_TGTS} .if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) vm-release: ${VMTARGETS} .else vm-release: .endif .if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE) cloudware-release: ${CLOUDTARGETS} .else cloudware-release: .endif .include "${.CURDIR}/Makefile.azure" .include "${.CURDIR}/Makefile.ec2" .include "${.CURDIR}/Makefile.firecracker" .include "${.CURDIR}/Makefile.gce" .include "${.CURDIR}/Makefile.oracle" .include "${.CURDIR}/Makefile.vagrant" .include "${.CURDIR}/Makefile.inc1" diff --git a/release/tools/basic-ci.conf b/release/tools/basic-ci.conf index 5acc04b1e530..12c9abb15fb1 100644 --- a/release/tools/basic-ci.conf +++ b/release/tools/basic-ci.conf @@ -1,34 +1,36 @@ #!/bin/sh # # # Should be enough for base image, image can be resized in needed export VMSIZE=5g # Set to a list of third-party software to enable in rc.conf(5). export VM_RC_LIST="sshd growfs" vm_extra_pre_umount() { cat << EOF >> ${DESTDIR}/etc/rc.conf dumpdev="AUTO" ifconfig_DEFAULT="DHCP" sshd_enable="YES" EOF cat << EOF >> ${DESTDIR}/boot/loader.conf autoboot_delay="-1" beastie_disable="YES" loader_logo="none" console="comconsole,vidconsole" EOF + metalog_add_data ./boot/loader.conf + cat <> ${DESTDIR}/etc/ssh/sshd_config PermitRootLogin yes PasswordAuthentication yes PermitEmptyPasswords yes UsePAM no EOF - touch ${DESTDIR}/firstboot + touch_firstboot return 0 } diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr index e7bd351c035c..c647097e8ced 100644 --- a/release/tools/vmimage.subr +++ b/release/tools/vmimage.subr @@ -1,347 +1,368 @@ #!/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 } +metalog_add_data() { + if [ -n "${NO_ROOT}" ]; then + echo "$1 type=file uname=root gname=wheel mode=0644" >> \ + ${DESTDIR}/METALOG + fi +} + 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} ${INSTALLOPTS} \ 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 \ - -L /dev/stdout + -L /dev/stdout ${NO_ROOT:+-N} + if [ -n "${NO_ROOT}" ]; then + # Reroot etcupdate's internal METALOG to the whole tree + sed -n 's,^\.,./var/db/etcupdate/current,p' \ + ${DESTDIR}/var/db/etcupdate/current/METALOG | \ + env -i LC_COLLATE=C sort >> ${DESTDIR}/METALOG + rm ${DESTDIR}/var/db/etcupdate/current/METALOG + fi 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 + metalog_add_data ./etc/fstab local hostname hostname="$(echo $(uname -o) | tr '[:upper:]' '[:lower:]')" echo "hostname=\"${hostname}\"" >> ${DESTDIR}/etc/rc.conf + metalog_add_data ./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 echo "kern.geom.label.disk_ident.enable=0" >> ${DESTDIR}/boot/loader.conf echo "zfs_load=YES" >> ${DESTDIR}/boot/loader.conf + metalog_add_data ./boot/loader.conf fi return 0 } vm_emulation_setup() { if [ -n "${WITHOUT_QEMU}" ]; then return 0 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 cp /etc/resolv.conf ${DESTDIR}/etc/resolv.conf 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 [ -n "${WITHOUT_QEMU}" ]; then return 0 fi if [ -z "${VM_EXTRA_PACKAGES}" ]; then return 0 fi 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 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. return 0 } vm_emulation_cleanup() { if [ -n "${WITHOUT_QEMU}" ]; then return 0 fi if ! [ -z "${QEMUSTATIC}" ]; then rm -f ${DESTDIR}/${EMULATOR} fi rm -f ${DESTDIR}/etc/resolv.conf umount_loop ${DESTDIR}/dev 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} + cd ${DESTDIR} && makefs ${MAKEFSARGS} -o label=rootfs -o version=2 -o softupdates=1 \ + ${VMBASE} .${NO_ROOT:+/METALOG} ;; zfs) - makefs -t zfs ${MAKEFSARGS} \ + cd ${DESTDIR} && 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=/\;canmount=noauto \ -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} + ${VMBASE} .${NO_ROOT:+/METALOG} ;; *) 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 if [ -n "${CONFIG_DRIVE}" ]; then CONFIG_DRIVE="-p freebsd/config-drive::${CONFIG_DRIVE_SIZE}" 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}" + MAKEFSARGS="-s ${VMSIZE} -D" 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/efiboot0:=${espfilename}" # Add this to fstab mkdir -p ${DESTDIR}/boot/efi echo "/dev/${ROOTLABEL}/efiboot0 /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} \ ${CONFIG_DRIVE} \ ${ROOTFSPART} \ -o ${VMIMAGE} echo "Disk image ${VMIMAGE} created." if [ ${ESP} = "yes" ]; then rm ${espfilename} fi return 0 } vm_extra_create_disk() { return 0 } +touch_firstboot() { + touch ${DESTDIR}/firstboot + metalog_add_data ./firstboot +}