diff --git a/release/Makefile b/release/Makefile index fb2a60130700..d131a36157d7 100644 --- a/release/Makefile +++ b/release/Makefile @@ -1,454 +1,455 @@ # # Makefile for building releases and release media. # # User-driven targets: # cdrom: Builds release CD-ROM media (disc1.iso) # dvdrom: Builds release DVD-ROM media (dvd1.iso) # memstick: Builds memory stick image (memstick.img) # mini-memstick: Builds minimal memory stick image (mini-memstick.img) # ftp: Sets up FTP distribution area (ftp) # release: Invokes real-release, vm-release, cloudware-release and oci-release targets # real-release: Build all media and FTP distribution area # vm-release: Build all virtual machine image targets # cloudware-release: Build all cloud hosting provider targets # oci-release: Build all OCI container images # install: Invokes the release-install, vm-install and oci-install targets # release-install: Copies all release installation media into ${DESTDIR} # vm-install: Copies all virtual machine images into ${DESTDIR} # cloud-install: Copies non-uploaded cloud images into ${DESTDIR} # oci-install: Copies all OCI container images into ${DESTDIR} # # Variables affecting the build process: # WORLDDIR: location of src tree -- must have built world and default kernel # (by default, the directory above this one) # NODISTSETS: if set, do not include dist sets or MANIFEST # NOPKGBASE: if set, include dist tarballs rather than pkgbase packages in -# disc1 and dvd1 installation media +# disc1 and dvd1 installation media and build VM/cloud images using +# make installkernel installworld. # PORTSDIR: location of ports tree to distribute (default: /usr/ports) # XTRADIR: xtra-bits-dir argument for /mkisoimages.sh # NOPKG: if set, do not distribute third-party packages # NOPORTS: if set, do not distribute ports tree # NOSRC: if set, do not distribute source tree # WITH_DVD: if set, generate dvd1.iso # WITH_COMPRESSED_IMAGES: if set, compress installation images with xz(1) # (uncompressed images are not removed) # WITH_VMIMAGES: if set, build virtual machine images with the release # WITH_COMPRESSED_VMIMAGES: if set, compress virtual machine disk images # with xz(1) (extremely time consuming) # WITH_CLOUDWARE: if set, build cloud hosting disk images with the release # TARGET/TARGET_ARCH: architecture of built release # WORLDDIR?= ${.CURDIR}/.. PORTSDIR?= /usr/ports .include "${WORLDDIR}/share/mk/bsd.compat.pre.mk" .if !defined(TARGET) || empty(TARGET) TARGET= ${MACHINE} .endif .if !defined(TARGET_ARCH) || empty(TARGET_ARCH) .if ${TARGET} == ${MACHINE} TARGET_ARCH= ${MACHINE_ARCH} .else TARGET_ARCH= ${TARGET} .endif .endif IMAKE= ${MAKE} TARGET_ARCH=${TARGET_ARCH} TARGET=${TARGET} \ -DNO_ROOT -DDB_FROM_SRC DISTDIR= dist # Define OSRELEASE by using newvers.sh .if !defined(OSRELEASE) || empty(OSRELEASE) .for _V in TYPE BRANCH REVISION ${_V}!= eval $$(awk '/^${_V}=/{print}' ${.CURDIR}/../sys/conf/newvers.sh); echo $$${_V} .endfor .for _V in ${TARGET_ARCH} .if !empty(TARGET:M${_V}) OSRELEASE= ${TYPE}-${REVISION}-${BRANCH}-${TARGET} VOLUME_LABEL= ${REVISION:C/[.-]/_/g}_${BRANCH:C/[.-]/_/g}_${TARGET} .else OSRELEASE= ${TYPE}-${REVISION}-${BRANCH}-${TARGET}-${TARGET_ARCH} VOLUME_LABEL= ${REVISION:C/[.-]/_/g}_${BRANCH:C/[.-]/_/g}_${TARGET_ARCH} .endif .endfor .endif .if ${.MAKE.OS} == "FreeBSD" # For installing packages into the release media. PKG_ENV+= INSTALL_AS_USER=yes PKG_ENV+= ASSUME_ALWAYS_YES=yes PKG_ARGS+= -o METALOG=METALOG PKG_ARGS+= -r ${.TARGET} PKG_REPO_ARGS= -o REPOS_DIR=${.CURDIR}/pkg_repos PKGBASE_REPO_ARGS=-o REPOS_DIR=${.OBJDIR}/pkgbase-repo-conf # Pass -f to make sure pkg writes to the METALOG even if the package # is already installed from a previous build PKG_INSTALL= env ${PKG_ENV} ${PKG_CMD} ${PKG_ARGS} ${PKG_REPO_ARGS} install -f PKG_CLEAN= env ${PKG_ENV} ${PKG_CMD} ${PKG_ARGS} ${PKG_REPO_ARGS} clean -a # This installs from the pkgbase repo we created during build. PKGBASE_INSTALL=env ${PKG_ENV} ${PKG_CMD} ${PKG_ARGS} ${PKGBASE_REPO_ARGS} install -f PKGBASE_CLEAN= env ${PKG_ENV} ${PKG_CMD} ${PKG_ARGS} ${PKGBASE_REPO_ARGS} clean -a .endif .if !defined(VOLUME_LABEL) || empty(VOLUME_LABEL) VOLUME_LABEL= FreeBSD_Install .endif .if !exists(${PORTSDIR}) NOPORTS= true .endif DISTRIBUTIONS= base.txz kernel.txz .if !defined(NOPORTS) DISTRIBUTIONS+= ports.txz .endif .if !defined(NOSRC) DISTRIBUTIONS+= src.txz .endif RELEASE_TARGETS= ftp IMAGES= .if exists(${.CURDIR}/${TARGET}/mkisoimages.sh) RELEASE_TARGETS+= cdrom IMAGES+= disc1.iso bootonly.iso . if defined(WITH_DVD) && !empty(WITH_DVD) RELEASE_TARGETS+= dvdrom IMAGES+= dvd1.iso . endif .endif .if exists(${.CURDIR}/${TARGET}/make-memstick.sh) RELEASE_TARGETS+= memstick.img RELEASE_TARGETS+= mini-memstick.img IMAGES+= memstick.img IMAGES+= mini-memstick.img .endif CLEANFILES= packagesystem *.txz MANIFEST release ${IMAGES} .if defined(WITH_COMPRESSED_IMAGES) && !empty(WITH_COMPRESSED_IMAGES) . for I in ${IMAGES} CLEANFILES+= ${I}.xz . endfor .endif .if defined(WITH_DVD) && !empty(WITH_DVD) CLEANFILES+= pkg-stage .endif CLEANDIRS= dist pkgdb pkgbase-repo pkgbase-repo-dir ftp disc1 disc1-disc1 disc1-memstick bootonly bootonly-bootonly bootonly-memstick dvd beforeclean: chflags -R noschg . .include clean: beforeclean # # Legacy distribution tarballs # base.txz: # Also (if enabled) tests, compat libs, and -dbg variants for all. mkdir -p ${DISTDIR} ( cd ${WORLDDIR} && ${IMAKE} distributeworld DISTDIR=${.OBJDIR}/${DISTDIR} ) # Bootstrap etcupdate(8) database. sh ${WORLDDIR}/usr.sbin/etcupdate/etcupdate.sh extract -B \ -m "${MAKE}" -M "TARGET_ARCH=${TARGET_ARCH} TARGET=${TARGET}" \ -s ${WORLDDIR} -d "${.OBJDIR}/${DISTDIR}/base/var/db/etcupdate" \ -L /dev/stdout -N echo "./var/db/etcupdate type=dir uname=root gname=wheel mode=0755" >> ${.OBJDIR}/${DISTDIR}/base.meta sed -n 's,^\.,./var/db/etcupdate/current,p' \ ${.OBJDIR}/${DISTDIR}/base/var/db/etcupdate/current/METALOG | \ env -i LC_COLLATE=C sort >> ${.OBJDIR}/${DISTDIR}/base.meta rm ${.OBJDIR}/${DISTDIR}/base/var/db/etcupdate/current/METALOG # Package all components ( cd ${WORLDDIR} && ${IMAKE} packageworld DISTDIR=${.OBJDIR}/${DISTDIR} ) mv ${DISTDIR}/*.txz . kernel.txz: # Also (if enabled) kernel-dbg.txz. mkdir -p ${DISTDIR} ( cd ${WORLDDIR} && ${IMAKE} distributekernel DISTDIR=${.OBJDIR}/${DISTDIR} ) ( cd ${WORLDDIR} && ${IMAKE} packagekernel DISTDIR=${.OBJDIR}/${DISTDIR} ) mv ${DISTDIR}/kernel*.txz . src.txz: mkdir -p ${DISTDIR}/usr rm -f ${DISTDIR}/usr/src ln -s ${WORLDDIR} ${DISTDIR}/usr/src ( cd ${DISTDIR} && ${TAR_XZ_CMD} -cLvf ${.OBJDIR}/src.txz \ --exclude .svn --exclude .zfs \ --exclude .git --exclude @ --exclude usr/src/release/dist \ --exclude usr/src/release/obj usr/src ) ports.txz: mkdir -p ${DISTDIR}/usr rm -f ${DISTDIR}/usr/ports ln -s ${PORTSDIR} ${DISTDIR}/usr/ports ( cd ${DISTDIR} && ${TAR_XZ_CMD} -cLvf ${.OBJDIR}/ports.txz \ --exclude .git --exclude .svn \ --exclude usr/ports/distfiles --exclude usr/ports/packages \ --exclude 'usr/ports/INDEX*' --exclude work usr/ports ) packagesystem: ${DISTRIBUTIONS} sh ${.CURDIR}/scripts/make-manifest.sh $$(ls *.txz | grep -v container) > MANIFEST touch ${.TARGET} .if !defined(NODISTSETS) disc1: packagesystem bootonly: packagesystem dvd: packagesystem .endif .if !defined(NOPKGBASE) || empty(NOPKGBASE) PKGBASE_REPO_DIR= pkgbase-repo-dir WSTAGEDIR!= ${IMAKE} -f Makefile.inc1 -C ${WORLDDIR} -V WSTAGEDIR PKG_ABI_FILE= ${WSTAGEDIR}/usr/bin/uname PKG_ABI= $$(${PKG_CMD} -o ABI_FILE=${PKG_ABI_FILE} config ABI) .endif pkgbase-repo: mkdir -p pkgbase-repo mkdir -p /tmp/ports /tmp/distfiles ( ${IMAKE} -C ${WORLDDIR} packages REPODIR=${.OBJDIR}/pkgbase-repo \ INCLUDE_PKG_IN_PKGBASE_REPO=YES BOOTSTRAP_PKG_FROM_PORTS=YES ) pkgbase-repo-dir: pkgbase-repo mkdir -p pkgbase-repo-dir printf "FreeBSD-base: { url: "file://%s", enabled: yes }" \ ${.OBJDIR}/pkgbase-repo/${PKG_ABI}/latest \ > pkgbase-repo-dir/FreeBSD-base.conf disc1: ${PKGBASE_REPO_DIR} # Install system mkdir -p ${.TARGET} ( cd ${WORLDDIR} && ${IMAKE} installworld installkernel distribution \ DESTDIR=${.OBJDIR}/${.TARGET} MK_AT=no \ MK_INSTALLLIB=no MK_MAIL=no \ ${_ALL_LIBCOMPATS:@v@MK_LIB$v=no@} \ MK_TOOLCHAIN=no \ MK_RESCUE=no MK_DICT=no \ MK_KERNEL_SYMBOLS=no MK_TESTS=no MK_DEBUG_FILES=no) .if !defined(NOPKGBASE) || empty(NOPKGBASE) # Create offline pkgbase repo on release media mkdir -p ${.TARGET}/usr/freebsd-packages/repos/ ${.CURDIR}/scripts/pkgbase-stage.lua disc \ ${.OBJDIR}/pkgbase-repo-dir \ ${.TARGET}/usr/freebsd-packages/offline \ "${_ALL_libcompats}" ${PKG_ABI} cp ${.CURDIR}/scripts/FreeBSD-base-offline.conf \ ${.TARGET}/usr/freebsd-packages/repos/ mtree -c -p ${.TARGET}/usr/freebsd-packages | \ mtree -C -k type,mode,link,size | \ sed 's|^\.|./usr/freebsd-packages|g' >> ${.TARGET}/METALOG .endif .if !defined(NODISTSETS) # Copy MANIFEST to provide legacy dist checksums in both modes mkdir -p ${.TARGET}/usr/freebsd-dist echo "./usr/freebsd-dist type=dir uname=root gname=wheel mode=0755" >> ${.TARGET}/METALOG cp MANIFEST ${.TARGET}/usr/freebsd-dist echo "./usr/freebsd-dist/MANIFEST type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG .if defined(NOPKGBASE) && !empty(NOPKGBASE) # Copy distfiles for dist in $$(ls *.txz | grep -v container | grep -vE -- '(${base ${_ALL_libcompats}:L:ts|})-dbg'); do \ cp $${dist} ${.TARGET}/usr/freebsd-dist; \ echo "./usr/freebsd-dist/$${dist} type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG; \ done .endif .endif .if ${.MAKE.OS} == "FreeBSD" && (!defined(NOPKG) || empty(NOPKG)) # Install packages onto release media. .if !defined(NOPKGBASE) || empty(NOPKGBASE) ${PKGBASE_INSTALL} pkg ${PKGBASE_CLEAN} .else ${PKG_INSTALL} pkg .endif ${PKG_INSTALL} wifi-firmware-kmod-release || true ${PKG_CLEAN} || true .endif # Set up installation environment ln -fs /tmp/bsdinstall_etc/resolv.conf ${.TARGET}/etc/resolv.conf echo sendmail_enable=\"NONE\" > ${.TARGET}/etc/rc.conf echo hostid_enable=\"NO\" >> ${.TARGET}/etc/rc.conf echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf echo kernels_autodetect=\"NO\" >> ${.TARGET}/boot/loader.conf echo loader_brand=\"install\" >> ${.TARGET}/boot/loader.conf echo loader_menu_multi_user_prompt=\"Installer\" >> ${.TARGET}/boot/loader.conf cp ${.CURDIR}/rc.local ${.TARGET}/etc echo "./etc/resolv.conf type=link uname=root gname=wheel mode=0644 link=/tmp/bsdinstall_etc/resolv.conf" >> ${.TARGET}/METALOG echo "./etc/rc.conf type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG echo "./etc/sysctl.conf type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG echo "./boot/loader.conf type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG echo "./etc/rc.local type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG touch ${.TARGET} bootonly: # Install system mkdir -p ${.TARGET} ( cd ${WORLDDIR} && ${IMAKE} installworld installkernel distribution \ DESTDIR=${.OBJDIR}/${.TARGET} MK_AT=no \ MK_GAMES=no \ MK_INSTALLLIB=no MK_MAIL=no \ ${_ALL_LIBCOMPATS:@v@MK_LIB$v=no@} \ MK_TOOLCHAIN=no \ MK_RESCUE=no MK_DICT=no \ MK_KERNEL_SYMBOLS=no MK_TESTS=no MK_DEBUG_FILES=no) .if !defined(NODISTSETS) # Copy manifest only (no distfiles) to get checksums mkdir -p ${.TARGET}/usr/freebsd-dist cp MANIFEST ${.TARGET}/usr/freebsd-dist echo "./usr/freebsd-dist type=dir uname=root gname=wheel mode=0755" >> ${.TARGET}/METALOG echo "./usr/freebsd-dist/MANIFEST type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG .endif .if ${.MAKE.OS} == "FreeBSD" && (!defined(NOPKG) || empty(NOPKG)) ${PKG_INSTALL} pkg || true ${PKG_INSTALL} wifi-firmware-iwlwifi-kmod wifi-firmware-rtw88-kmod || true ${PKG_CLEAN} || true .endif # Set up installation environment ln -fs /tmp/bsdinstall_etc/resolv.conf ${.TARGET}/etc/resolv.conf echo sendmail_enable=\"NONE\" > ${.TARGET}/etc/rc.conf echo hostid_enable=\"NO\" >> ${.TARGET}/etc/rc.conf echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf echo kernels_autodetect=\"NO\" >> ${.TARGET}/boot/loader.conf echo loader_brand=\"install\" >> ${.TARGET}/boot/loader.conf echo loader_menu_multi_user_prompt=\"Installer\" >> ${.TARGET}/boot/loader.conf cp ${.CURDIR}/rc.local ${.TARGET}/etc echo "./etc/resolv.conf type=link uname=root gname=wheel mode=0644 link=/tmp/bsdinstall_etc/resolv.conf" >> ${.TARGET}/METALOG echo "./etc/rc.conf type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG echo "./etc/sysctl.conf type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG echo "./boot/loader.conf type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG echo "./etc/rc.local type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG dvd: ${PKGBASE_REPO_DIR} # Install system mkdir -p ${.TARGET} ( cd ${WORLDDIR} && ${IMAKE} installworld installkernel distribution \ DESTDIR=${.OBJDIR}/${.TARGET} MK_RESCUE=no MK_KERNEL_SYMBOLS=no \ MK_TESTS=no MK_DEBUG_FILES=no) .if !defined(NOPKGBASE) || empty(NOPKGBASE) # Create offline pkgbase repo on release media mkdir -p ${.TARGET}/usr/freebsd-packages/repos/ ${.CURDIR}/scripts/pkgbase-stage.lua dvd \ ${.OBJDIR}/pkgbase-repo-dir \ ${.TARGET}/usr/freebsd-packages/offline \ "${_ALL_libcompats}" ${PKG_ABI} cp ${.CURDIR}/scripts/FreeBSD-base-offline.conf \ ${.TARGET}/usr/freebsd-packages/repos/ mtree -c -p ${.TARGET}/usr/freebsd-packages | \ mtree -C -k type,mode,link,size | \ sed 's|^\.|./usr/freebsd-packages|g' >> ${.TARGET}/METALOG .endif .if !defined(NODISTSETS) # Copy MANIFEST to provide legacy dist checksums in both modes mkdir -p ${.TARGET}/usr/freebsd-dist echo "./usr/freebsd-dist type=dir uname=root gname=wheel mode=0755" >> ${.TARGET}/METALOG cp MANIFEST ${.TARGET}/usr/freebsd-dist echo "./usr/freebsd-dist/MANIFEST type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG # Copy distfiles mkdir -p ${.TARGET}/usr/freebsd-dist for dist in $$(ls *.txz | grep -v container); do \ cp $${dist} ${.TARGET}/usr/freebsd-dist; \ echo "./usr/freebsd-dist/$${dist} type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG; \ done .endif .if ${.MAKE.OS} == "FreeBSD" && (!defined(NOPKG) || empty(NOPKG)) # Install packages onto release media. .if !defined(NOPKGBASE) || empty(NOPKGBASE) ${PKGBASE_INSTALL} pkg ${PKGBASE_CLEAN} .else ${PKG_INSTALL} pkg .endif ${PKG_INSTALL} wifi-firmware-kmod-release || true ${PKG_CLEAN} || true .endif # Set up installation environment ln -fs /tmp/bsdinstall_etc/resolv.conf ${.TARGET}/etc/resolv.conf echo sendmail_enable=\"NONE\" > ${.TARGET}/etc/rc.conf echo hostid_enable=\"NO\" >> ${.TARGET}/etc/rc.conf echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf echo kernels_autodetect=\"NO\" >> ${.TARGET}/boot/loader.conf echo loader_brand=\"install\" >> ${.TARGET}/boot/loader.conf echo loader_menu_multi_user_prompt=\"Installer\" >> ${.TARGET}/boot/loader.conf cp ${.CURDIR}/rc.local ${.TARGET}/etc echo "./etc/resolv.conf type=link uname=root gname=wheel mode=0644 link=/tmp/bsdinstall_etc/resolv.conf" >> ${.TARGET}/METALOG echo "./etc/rc.conf type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG echo "./etc/sysctl.conf type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG echo "./boot/loader.conf type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG echo "./etc/rc.local type=file uname=root gname=wheel mode=0644" >> ${.TARGET}/METALOG touch ${.TARGET} disc1-disc1 disc1-memstick: disc1 mkdir ${.TARGET} tar -cf- -C disc1 . | tar -xf- -C ${.TARGET} bootonly-bootonly bootonly-memstick: bootonly mkdir ${.TARGET} tar -cf- -C bootonly . | tar -xf- -C ${.TARGET} release.iso: disc1.iso disc1.iso: disc1-disc1 cd disc1-disc1 && sh ${.CURDIR}/${TARGET}/mkisoimages.sh -b ${VOLUME_LABEL}_CD ../${.TARGET} ./METALOG ${XTRADIR} dvd1.iso: dvd pkg-stage cd dvd && sh ${.CURDIR}/${TARGET}/mkisoimages.sh -b ${VOLUME_LABEL}_DVD ../${.TARGET} ./METALOG ${XTRADIR} bootonly.iso: bootonly-bootonly cd bootonly-bootonly && sh ${.CURDIR}/${TARGET}/mkisoimages.sh -b ${VOLUME_LABEL}_BO ../${.TARGET} ./METALOG ${XTRADIR} memstick: memstick.img memstick.img: disc1-memstick cd disc1-memstick && sh ${.CURDIR}/${TARGET}/make-memstick.sh ./METALOG ../${.TARGET} mini-memstick: mini-memstick.img mini-memstick.img: bootonly-memstick cd bootonly-memstick && sh ${.CURDIR}/${TARGET}/make-memstick.sh ./METALOG ../${.TARGET} pkg-stage: dvd .if !defined(NOPKG) || empty(NOPKG) env PORTSDIR=${PORTSDIR} REPOS_DIR=${.CURDIR}/pkg_repos/ \ sh ${.CURDIR}/scripts/pkg-stage.sh -N mkdir -p ${.OBJDIR}/dvd/packages/repos/ cp ${.CURDIR}/scripts/FreeBSD_install_cdrom.conf \ ${.OBJDIR}/dvd/packages/repos/ .endif touch ${.TARGET} cdrom: disc1.iso bootonly.iso dvdrom: dvd1.iso ftp: packagesystem rm -rf ftp mkdir -p ftp cp *.txz MANIFEST ftp rm -f ftp/container-*.txz release: real-release vm-release cloudware-release oci-release ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} release-done true release-done: touch release real-release: ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} obj ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${RELEASE_TARGETS} install: release-install vm-install oci-install .WAIT cloud-install release-install: .if defined(DESTDIR) && !empty(DESTDIR) mkdir -p ${DESTDIR} .endif cp -a ftp ${DESTDIR}/ .if !empty(IMAGES) .for I in ${IMAGES} cp -p ${I} ${DESTDIR}/${OSRELEASE}-${I} . if defined(WITH_COMPRESSED_IMAGES) && !empty(WITH_COMPRESSED_IMAGES) ${XZ_CMD} -k ${DESTDIR}/${OSRELEASE}-${I} . endif .endfor ( cd ${DESTDIR} && sha512 ${OSRELEASE}* > ${DESTDIR}/CHECKSUM.SHA512 ) ( cd ${DESTDIR} && sha256 ${OSRELEASE}* > ${DESTDIR}/CHECKSUM.SHA256 ) .endif .include "${.CURDIR}/Makefile.inc1" .include "${.CURDIR}/Makefile.vm" .include "${.CURDIR}/Makefile.oci" diff --git a/release/Makefile.vm b/release/Makefile.vm index 479547f76da1..eafd1d6abf71 100644 --- a/release/Makefile.vm +++ b/release/Makefile.vm @@ -1,303 +1,307 @@ # # 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 CLOUDWARE_TYPES?= AZURE \ BASIC-CI \ BASIC-CLOUDINIT \ EC2 \ GCE \ ORACLE \ VAGRANT 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 BUILDER CLOUD-INIT SMALL EC2-BASE_DESC= Amazon EC2 image EC2-BUILDER_DESC= Amazon EC2 AMI Builder 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(WITHOUT_QEMU) && !defined(NO_ROOT)) || \ (!defined(WITHOUT_QEMU) && defined(NO_ROOT)) .error WITHOUT_QEMU requires NO_ROOT (and vice versa) .endif .if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE) . 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} # Special handling: EC2 "AMI Builder" images need a copy of the "base" disk # built first. .if ${_CW} == EC2-BUILDER cw-${_CW:tl}-${_FS}-${_FMT}: cw-ec2-base-${_FS}-${_FMT} .endif -cw-${_CW:tl}-${_FS}-${_FMT}: ${QEMUTGT} +cw-${_CW:tl}-${_FS}-${_FMT}: ${QEMUTGT} ${PKGBASE_REPO_DIR} mkdir -p ${.OBJDIR}/${.TARGET} env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} SWAPSIZE=${SWAPSIZE} \ QEMUSTATIC=${QEMUSTATIC} \ EC2BASEIMG=${.OBJDIR}/${EC2-BASE${_FS:tu}${_FMT:tu}IMAGE} \ ${WITHOUT_QEMU:DWITHOUT_QEMU=true} \ ${NO_ROOT:DNO_ROOT=true} \ PKG_CMD=${PKG_CMD:Upkg} \ PKG_REPOS_DIR=${PKG_REPOS_DIR:U${.OBJDIR}/${.TARGET}/etc/pkg} \ PKG_REPO_NAME=${PKG_REPO_NAME:UFreeBSD-ports} \ PKG_INSTALL_EPOCH=${PKG_INSTALL_EPOCH:U${GITEPOCH}} \ + NOPKGBASE=${NOPKGBASE} \ + PKGBASE_REPO_DIR=${.OBJDIR}/pkgbase-repo-dir \ ${.CURDIR}/scripts/mk-vmimage.sh \ -C ${.CURDIR}/tools/vmimage.subr -d ${.OBJDIR}/${.TARGET} \ -F ${"${_CW:MEC2-BUILDER}" != "":?ufs:${_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} || true 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} || true . 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} +vm-image: ${QEMUTGT} ${PKGBASE_REPO_DIR} .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:DWITHOUT_QEMU=true} \ ${NO_ROOT:DNO_ROOT=true} \ PKG_CMD=${PKG_CMD:Upkg} \ PKG_REPOS_DIR=${PKG_REPOS_DIR:U${.OBJDIR}/${.TARGET}-${FORMAT}-${FS}/etc/pkg} \ PKG_REPO_NAME=${PKG_REPO_NAME:UFreeBSD-ports} \ PKG_INSTALL_EPOCH=${PKG_INSTALL_EPOCH:U${GITEPOCH}} \ + NOPKGBASE=${NOPKGBASE} \ + PKGBASE_REPO_DIR=${.OBJDIR}/pkgbase-repo-dir \ ${.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} || true . 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} -f ${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} -f ${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} -f ${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/ec2-builder.conf b/release/tools/ec2-builder.conf index 993dffc565eb..cf4276fc80ec 100644 --- a/release/tools/ec2-builder.conf +++ b/release/tools/ec2-builder.conf @@ -1,62 +1,71 @@ #!/bin/sh . ${WORLDDIR}/release/tools/ec2.conf # Build with a 7.9 GB partition; this is enough for our stripped-down # base system plus the compressed ec2-base image. export VMSIZE=8000m # Flags to installworld/kernel: We don't want debug symbols (kernel or # userland), 32-bit libraries, tests, or the debugger. export INSTALLOPTS="WITHOUT_DEBUG_FILES=YES WITHOUT_KERNEL_SYMBOLS=YES \ WITHOUT_LIB32=YES WITHOUT_TESTS=YES WITHOUT_LLDB=YES" +# Equivalent to INSTALLOPTS for pkgbase +vm_extra_filter_base_packages() { + grep -v \ + -e '.*-dbg$' \ + -e '.*-lib32$' \ + -e '^FreeBSD-tests.*' \ + -e '^FreeBSD-lldb.*' +} + # Packages to install into the image we're creating. In addition to packages # present on all EC2 AMIs, we install: # * ec2-scripts, which provides a range of EC2ification startup scripts, # * isc-dhcp44-client, used for IPv6 network setup, and # * py-awscli, to make it easier for users to create AMIs. export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} ec2-scripts \ isc-dhcp44-client devel/py-awscli" # Services to enable in rc.conf(5). export VM_RC_LIST="${VM_RC_LIST} ec2_configinit ec2_ephemeral_swap \ ec2_fetchkey ec2_loghostkey sshd" vm_extra_pre_umount() { # Any EC2 ephemeral disks seen when the system first boots will # be "new" disks; there is no "previous boot" when they might have # been seen and used already. touch ${DESTDIR}/var/db/ec2_ephemeral_diskseen metalog_add_data ./var/db/ec2_ephemeral_diskseen # Configuration common to all EC2 AMIs ec2_common # Standard FreeBSD network configuration ec2_base_networking # Grab a copy of the ec2-base disk image, and compress it zstd < ${EC2BASEIMG} > ${DESTDIR}/image.zst metalog_add_data ./image.zst # Disable fortune so we don't have extra noise at login chmod a-x ${DESTDIR}/usr/bin/fortune # Install the AMI-building script install -m 755 ${WORLDDIR}/release/tools/mkami.sh ${DESTDIR}/bin/mkami metalog_add_data ./bin/mkami 0755 # Install an /etc/rc which juggles disks around for us install -m 755 ${WORLDDIR}/release/tools/rc.amibuilder ${DESTDIR}/etc metalog_add_data ./etc/rc.amibuilder 0755 # We want to mount from the UFS disk and juggle disks first cat >> ${DESTDIR}/boot/loader.conf <<-EOF vfs.root.mountfrom="ufs:/dev/gpt/rootfs" init_script="/etc/rc.amibuilder" EOF metalog_add_data ./boot/loader.conf return 0 } diff --git a/release/tools/ec2-small.conf b/release/tools/ec2-small.conf index e2a348d6ba8f..32d02cbb79e4 100644 --- a/release/tools/ec2-small.conf +++ b/release/tools/ec2-small.conf @@ -1,45 +1,54 @@ #!/bin/sh . ${WORLDDIR}/release/tools/ec2.conf # Build with a 4.9 GB partition; the growfs rc.d script will expand # the partition to fill the root disk after the EC2 instance is launched. # Note that if this is set to G, we will end up with an GB disk # image since VMSIZE is the size of the filesystem partition, not the disk # which it resides within. (This overrides the default in ec2.conf.) export VMSIZE=5000m # Flags to installworld/kernel: We don't want debug symbols (kernel or # userland), 32-bit libraries, tests, or the debugger. export INSTALLOPTS="WITHOUT_DEBUG_FILES=YES WITHOUT_KERNEL_SYMBOLS=YES \ WITHOUT_LIB32=YES WITHOUT_TESTS=YES WITHOUT_LLDB=YES" +# Equivalent to INSTALLOPTS for pkgbase +vm_extra_filter_base_packages() { + grep -v \ + -e '.*-dbg$' \ + -e '.*-lib32$' \ + -e '^FreeBSD-tests.*' \ + -e '^FreeBSD-lldb.*' +} + # Packages to install into the image we're creating. In addition to packages # present on all EC2 AMIs, we install: # * ec2-scripts, which provides a range of EC2ification startup scripts, # * firstboot-freebsd-update, to install security updates at first boot, # * firstboot-pkgs, to install packages at first boot, and # * isc-dhcp44-client, used for IPv6 network setup. export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} ec2-scripts \ firstboot-freebsd-update firstboot-pkgs isc-dhcp44-client" # Services to enable in rc.conf(5). export VM_RC_LIST="${VM_RC_LIST} ec2_configinit ec2_ephemeral_swap \ ec2_fetchkey ec2_loghostkey firstboot_freebsd_update firstboot_pkgs \ growfs sshd" vm_extra_pre_umount() { # Any EC2 ephemeral disks seen when the system first boots will # be "new" disks; there is no "previous boot" when they might have # been seen and used already. touch ${DESTDIR}/var/db/ec2_ephemeral_diskseen metalog_add_data ./var/db/ec2_ephemeral_diskseen # Configuration common to all EC2 AMIs ec2_common # Standard FreeBSD network configuration ec2_base_networking return 0 } diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr index b3187efd6526..577abaac73cf 100644 --- a/release/tools/vmimage.subr +++ b/release/tools/vmimage.subr @@ -1,398 +1,426 @@ #!/bin/sh # # # # Common functions for virtual machine image build scripts. # scriptdir=$(dirname $(realpath $0)) . ${scriptdir}/../scripts/tools.subr . ${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() { local file mode type if [ -n "${NO_ROOT}" ]; then file=$1 if [ -f ${DESTDIR}/${file} ]; then type=file mode=${2:-0644} elif [ -d ${DESTDIR}/${file} ]; then type=dir mode=${2:-0755} else echo "metalog_add_data: ${file} not found" >&2 return 1 fi echo "${file} type=${type} uname=root gname=wheel mode=${mode}" >> \ ${DESTDIR}/METALOG fi } vm_create_base() { mkdir -p ${DESTDIR} return 0 } vm_copy_base() { # Defunct return 0 } +vm_filter_base_packages() { + # Reads a list of all base system packages from stdin. + # Writes a list of base system packages to install to stdout. + grep -v -e '^FreeBSD-src.*' -e '^FreeBSD-kernel.*' + # There are several kernel variants available in separate packages. + # For VMs it is sufficient to install only the generic kernel. + echo "FreeBSD-kernel-man" + echo "FreeBSD-kernel-generic" + echo "FreeBSD-kernel-generic-dbg" +} + +vm_extra_filter_base_packages() { + # Prototype. When overridden, allows further filtering of base system + # packages, reading package names from stdin and writing to stdout. + cat +} + 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}." + if [ -z "${NOPKGBASE}" ]; then + local pkg_cmd + pkg_cmd="pkg --rootdir ${DESTDIR} --repo-conf-dir ${PKGBASE_REPO_DIR} + -o ASSUME_ALWAYS_YES=yes -o IGNORE_OSVERSION=yes + -o INSTALL_AS_USER=yes " + $pkg_cmd update + selected=$($pkg_cmd rquery -U -r FreeBSD-base %n | \ + vm_filter_base_packages | vm_extra_filter_base_packages) + $pkg_cmd install -U -r FreeBSD-base $selected + else + cd ${WORLDDIR} && \ + make DESTDIR=${DESTDIR} ${INSTALLOPTS} \ + installworld installkernel distribution || \ + err "\n\nCannot install the base system to ${DESTDIR}." + fi # 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 ${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,noatime 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 [ -n "${QEMUSTATIC}" ]; then export EMULATOR=/qemu cp ${QEMUSTATIC} ${DESTDIR}/${EMULATOR} fi mkdir -p ${DESTDIR}/dev mount -t devfs devfs ${DESTDIR}/dev 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 [ -n "${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 fi return 0 } vm_extra_install_packages() { if [ -z "${VM_EXTRA_PACKAGES}" ]; then return 0 fi if [ -n "${NO_ROOT}" ]; then for pkg in ${VM_EXTRA_PACKAGES}; do INSTALL_AS_USER=yes \ ${PKG_CMD} \ -o METALOG=${DESTDIR}/METALOG.pkg \ -o REPOS_DIR=${PKG_REPOS_DIR} \ -o PKG_DBDIR=${DESTDIR}/var/db/pkg \ -r ${DESTDIR} \ install -y -r ${PKG_REPO_NAME} $pkg done metalog_add_data ./var/db/pkg/local.sqlite else if [ -n "${WITHOUT_QEMU}" ]; 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 fi 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 if [ -f ${DESTDIR}/METALOG.pkg ]; then cat ${DESTDIR}/METALOG.pkg >> ${DESTDIR}/METALOG fi case "${VMFS}" in ufs) cd ${DESTDIR} && ${MAKEFS} ${MAKEFSARGS} -o label=rootfs -o version=2 -o softupdates=1 \ ${VMBASE} .${NO_ROOT:+/METALOG} ;; zfs) 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} .${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} -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 # Add a marker file which indicates that this image has never # been booted. Some services run only upon the first boot. touch ${DESTDIR}/firstboot metalog_add_data ./firstboot 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 }