From a68d274b869a4f3698d4e2bfbcd2e5715500cc3c Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Sun, 28 Sep 2014 01:45:20 +0000 Subject: [PATCH 01/10] Initial commit to include virtual machine images as part of the FreeBSD release builds. This adds a make(1) environment variable requirement, WITH_VMIMAGES, which triggers the virtual machine image targets when not defined to an empty value. Relevant user-driven variables include: o VMFORMATS: The virtual machine image formats to create. Valid formats are provided by running 'mkimg --formats' o VMSIZE: The size of the resulting virtual machine image. Typical compression is roughly 140Mb, regardless of the target size (10GB, 15GB, 20GB, 40GB sizes have been tested with the same result). o VMBASE: The prefix of the virtual machine disk images. The VMBASE make(1) environment variable is suffixed with each format in VMFORMATS for each individual disk image, as well as '.img' for the source UFS filesystem passed to mkimg(1). This also includes a new script, mk-vmimage.sh, based on how the VM images for 10.0-RELEASE, 9.3-RELEASE, and 10.1-RELEASE were created (mk-vmimage.sh in ^/user/gjb/thermite/). With the order in which the stages need to occur, as well as sanity-checking error cases, it makes much more sense to execute a shell script called from make(1), using env(1) to set specific parameters for the target image than it does to do this in make(1) directly. Sponsored by: The FreeBSD Foundation --- release/Makefile | 53 ++++++++++++ release/scripts/mk-vmimage.sh | 157 ++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+) create mode 100755 release/scripts/mk-vmimage.sh diff --git a/release/Makefile b/release/Makefile index 6b4517dc437..434a130ac39 100644 --- a/release/Makefile +++ b/release/Makefile @@ -23,6 +23,7 @@ # 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 # TARGET/TARGET_ARCH: architecture of built release # @@ -94,6 +95,11 @@ IMAGES+= memstick.img IMAGES+= mini-memstick.img .endif +VMTARGETS= vm-base vm-image +VMFORMATS?= vhd vmdk qcow2 raw +VMSIZE?= 20G # size in Gb +VMBASE?= vm # name of the filesystem image + CLEANFILES= packagesystem *.txz MANIFEST system ${IMAGES} .if defined(WITH_COMPRESSED_IMAGES) && !empty(WITH_COMPRESSED_IMAGES) . for I in ${IMAGES} @@ -103,7 +109,16 @@ CLEANFILES+= ${I}.xz .if defined(WITH_DVD) && !empty(WITH_DVD) CLEANFILES+= pkg-stage .endif +.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) +CLEANFILES+= ${VMBASE}.img +. for FORMAT in ${VMFORMATS} +CLEANFILES+= vm.${FORMAT} +. endfor +.endif CLEANDIRS= dist ftp release bootonly dvd +.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) +CLEANDIRS+= ${VMTARGETS} +.endif beforeclean: chflags -R noschg . .include @@ -277,3 +292,41 @@ install: .endfor cd ${DESTDIR} && sha256 ${OSRELEASE}* > ${DESTDIR}/CHECKSUM.SHA256 cd ${DESTDIR} && md5 ${OSRELEASE}* > ${DESTDIR}/CHECKSUM.MD5 +.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) + mkdir -p ${DESTDIR}/vmimages +. for FORMAT in ${VMFORMATS} + cp -p ${VMBASE}.${FORMAT} \ + ${DESTDIR}/vmimages/${OSRELEASE}.${FORMAT} +. endfor +. if defined(WITH_COMPRESSED_IMAGES) && !empty(WITH_COMPRESSED_IMAGES) +# This is very time consuming, so defer it after the images are moved to +# the DESTDIR. +. for FORMAT in ${VMFORMATS} + # Don't keep the originals. There is a copy in ${.OBJDIR} if needed. + ${XZCMD} ${DESTDIR}/vmimages/${OSRELEASE}.${FORMAT} +. endfor +. endif + cd ${DESTDIR}/vmimages && sha256 ${OSRELEASE}* > \ + ${DESTDIR}/vmimages/CHECKSUM.SHA256 + cd ${DESTDIR}/vmimages && md5 ${OSRELEASE}* > \ + ${DESTDIR}/vmimages/CHECKSUM.MD5 +.endif + +vm-base: +.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) + env IMAKE=${IMAKE} WORLDDIR=${WORLDDIR} \ + VMBASE=${VMBASE}.img VMSIZE=${VMSIZE} DESTDIR=${.TARGET} \ + TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ + ${.CURDIR}/scripts/mk-vmimage.sh ${.TARGET} +.endif + touch ${.TARGET} + +vm-image: vm-base +.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) +. for FORMAT in ${VMFORMATS} + env FORMAT=${FORMAT} VMIMAGE=${VMBASE}.${FORMAT} VMBASE=${VMBASE}.img \ + TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ + ${.CURDIR}/scripts/mk-vmimage.sh ${.TARGET} +. endfor +.endif + touch ${.TARGET} diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh new file mode 100755 index 00000000000..597d1433af3 --- /dev/null +++ b/release/scripts/mk-vmimage.sh @@ -0,0 +1,157 @@ +#!/bin/sh +#- +# Copyright (c) 2014 The FreeBSD Foundation +# All rights reserved. +# +# This software was developed by Glen Barber under sponsorship +# from the FreeBSD Foundation. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# mk-vmimage.sh: Create virtual machine disk images in various formats. +# +# $FreeBSD$ +# + +PATH="/bin:/usr/bin:/sbin:/usr/sbin" +export PATH + +usage() { + echo "$(basename ${0}) [...]" + if [ -z "${MAKEFLAGS}" ]; then + echo "It is probably not safe to run this by hand yet..." + fi + exit 1 +} + +panic() { + rc="${1}" + shift 1 + msg="${@}" + printf "${msg}\n" + if [ ! -z "${mddev}" ]; then + mdconfig -d -u ${mddev} + fi + # Do not allow one failure case to chain through any remaining image + # builds. + exit 0 +} + +vm_create_baseimage() { + # Creates the UFS root filesystem for the virtual machine disk, + # written to the formatted disk image with mkimg(1). + i=0 + mkdir -p ${DESTDIR} + truncate -s ${VMSIZE} ${VMBASE} + mddev=$(mdconfig -f ${VMBASE}) + newfs -L root -j ${mddev} + mount ${mddev} ${DESTDIR} + cd ${WORLDDIR} && \ + ${IMAKE} DESTDIR=${DESTDIR} \ + installworld installkernel distribution || \ + panic 1 "\n\nCannot install the base system to ${DESTDIR}." + chroot ${DESTDIR} /usr/bin/newaliases + echo '# Custom /etc/fstab for FreeBSD VM images' \ + # > ${DESTDIR}/etc/fstab + echo '/dev/gpt/rootfs / ufs rw 2 2' \ + # >> ${DESTDIR}/etc/fstab + echo '/dev/gpt/swapfs none swap sw 0 0' \ + # >> ${DESTDIR}/etc/fstab + sync + while ! umount ${DESTDIR}; do + i=$(( $i + 1 )) + if [ $i -ge 10 ]; then + # This should never happen. But, it has happened. + msg="Cannot umount(8) ${DESTDIR}\n" + msg="${msg}Something has gone horribly wrong." + panic 1 "${msg}" + fi + sleep 1 + done + + return 0 +} + +vm_create_vmdisk() { + mkimg_version=$(mkimg --version 2>/dev/null | awk '{print $2}') + + # We need mkimg(1) '--version' output, at minimum, to be able to + # tell what virtual machine disk image formats are available. + # Bail if mkimg(1) reports an empty '--version' value. + if [ -z "${mkimg_version}" ]; then + msg="Cannot determine mkimg(1) version.\n" + msg="${msg}Cannot continue without a known mkimg(1) version." + panic 0 "${msg}" + fi + + if ! mkimg --formats 2>/dev/null | grep -q ${FORMAT}; then + panic 0 "Format ${FORMAT} is not supported with this mkimg(1)\n" + fi + + case ${FORMAT} in + vhd) + mkimg_format=vhdf + ;; + *) + mkimg_format=${FORMAT} + ;; + esac + + set -x + mkimg -f ${mkimg_format} -s gpt \ + -b /boot/pmbr -p freebsd-boot/bootfs:=/boot/gptboot \ + -p freebsd-swap/swapfs::1G \ + -p freebsd-ufs/rootfs:=${VMBASE} \ + -o ${VMIMAGE} + + return 0 +} + +main() { + cmd="${1}" + + case ${TARGET}/${TARGET_ARCH} in + amd64/amd64|i386/i386) + # FALLTHROUGH + ;; + *) + # EX_CANTCREAT + return 0 + ;; + esac + + case ${cmd} in + vm-base) + eval vm_create_baseimage "$@" || return 0 + ;; + vm-image) + eval vm_create_vmdisk "$@" || return 0 + ;; + *|\?) + usage + ;; + esac + + return 0 +} + +main "$@" From c925095689efc8a01b72d8a4c0ff1799d8343a92 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Sun, 28 Sep 2014 01:53:02 +0000 Subject: [PATCH 02/10] Use VMBASE in place of a hard-coded filename in the CLEANFILES list. Sponsored by: The FreeBSD Foundation --- release/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/Makefile b/release/Makefile index 434a130ac39..70eb5a244ff 100644 --- a/release/Makefile +++ b/release/Makefile @@ -112,7 +112,7 @@ CLEANFILES+= pkg-stage .if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) CLEANFILES+= ${VMBASE}.img . for FORMAT in ${VMFORMATS} -CLEANFILES+= vm.${FORMAT} +CLEANFILES+= ${VMBASE}.${FORMAT} . endfor .endif CLEANDIRS= dist ftp release bootonly dvd From 8234f86da8ede83438521a2f3a7802bb582f0f06 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Sun, 28 Sep 2014 17:16:45 +0000 Subject: [PATCH 03/10] Remove a 'set -x' that snuck in during testing. Sponsored by: The FreeBSD Foundation --- release/scripts/mk-vmimage.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh index 597d1433af3..884c5a571cf 100755 --- a/release/scripts/mk-vmimage.sh +++ b/release/scripts/mk-vmimage.sh @@ -116,7 +116,6 @@ vm_create_vmdisk() { ;; esac - set -x mkimg -f ${mkimg_format} -s gpt \ -b /boot/pmbr -p freebsd-boot/bootfs:=/boot/gptboot \ -p freebsd-swap/swapfs::1G \ From 4e187d25faa14ce292251623d3553d2e7f8d25cf Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Sun, 28 Sep 2014 17:53:10 +0000 Subject: [PATCH 04/10] release/Makefile: Connect the virtual machine image build to the release target if WITH_VMIMAGES is set to a non-empty value. release/release.sh: Add WITH_VMIMAGES to RELEASE_RMAKEFLAGS. release/release.conf.sample: Add commented entries for tuning the release build if the WITH_VMIMAGES make(1) environment variable is set to a non-empty value. Sponsored by: The FreeBSD Foundation --- release/Makefile | 3 +++ release/release.conf.sample | 17 +++++++++++++++++ release/release.sh | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/release/Makefile b/release/Makefile index 70eb5a244ff..ade92ff92aa 100644 --- a/release/Makefile +++ b/release/Makefile @@ -278,6 +278,9 @@ ftp: packagesystem release: ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} obj ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${RELEASE_TARGETS} +.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) + ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${VMTARGETS} +.endif install: .if defined(DESTDIR) && !empty(DESTDIR) diff --git a/release/release.conf.sample b/release/release.conf.sample index bdd5a8a05d9..9acc0e2d820 100644 --- a/release/release.conf.sample +++ b/release/release.conf.sample @@ -77,3 +77,20 @@ PORTBRANCH="ports/head@rHEAD" ## as TARGET/TARGET_ARCH. #CHROOT_MAKEENV= +## Set to a non-empty value to build virtual machine images as part of the +## release build. +#WITH_VMIMAGES= + +## If WITH_VMIMAGES is set to a non-empty value, this is the name of the +## file to use for the installed userland/kernel. +#VMBASE="vm" + +## If WITH_VMIMAGES is set to a non-empty value, this is the size of the +## virtual machine disk filesystem. Valid size values are described in +## the truncate(1) manual page. +#VMSIZE="20G" + +## If WITH_VMIMAGES is set to a non-empty value, this is a list of disk +## image formats to create. Valid values are listed in the mkimg(1) +## manual page, as well as 'mkimg --formats' output. +#VMFORMATS="vhdf vmdk qcow2 raw" diff --git a/release/release.sh b/release/release.sh index e99c403d22b..e7f0c39f158 100755 --- a/release/release.sh +++ b/release/release.sh @@ -169,7 +169,7 @@ CHROOT_DMAKEFLAGS="${CONF_FILES}" RELEASE_WMAKEFLAGS="${MAKE_FLAGS} ${WORLD_FLAGS} ${ARCH_FLAGS} ${CONF_FILES}" RELEASE_KMAKEFLAGS="${MAKE_FLAGS} ${KERNEL_FLAGS} KERNCONF=\"${KERNEL}\" ${ARCH_FLAGS} ${CONF_FILES}" RELEASE_RMAKEFLAGS="${ARCH_FLAGS} KERNCONF=\"${KERNEL}\" ${CONF_FILES} \ - ${DOCPORTS} WITH_DVD=${WITH_DVD}" + ${DOCPORTS} WITH_DVD=${WITH_DVD} WITH_VMIMAGES=${WITH_VMIMAGES}" # Force src checkout if configured FORCE_SRC_KEY= From f54137c33145752ab340a21d34d1a9df3389df35 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Sun, 28 Sep 2014 20:06:02 +0000 Subject: [PATCH 05/10] release/Makefile: Include .OBJDIR in DESTDIR in the vm-base target. release/release.sh: Provide the full path to mddev. Sponsored by: The FreeBSD Foundation --- release/Makefile | 3 ++- release/scripts/mk-vmimage.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/release/Makefile b/release/Makefile index ade92ff92aa..7fdea8521d3 100644 --- a/release/Makefile +++ b/release/Makefile @@ -318,7 +318,8 @@ install: vm-base: .if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) env IMAKE=${IMAKE} WORLDDIR=${WORLDDIR} \ - VMBASE=${VMBASE}.img VMSIZE=${VMSIZE} DESTDIR=${.TARGET} \ + VMBASE=${VMBASE}.img VMSIZE=${VMSIZE} \ + DESTDIR=${.OBJDIR}/${.TARGET} \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ ${.CURDIR}/scripts/mk-vmimage.sh ${.TARGET} .endif diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh index 884c5a571cf..d33b4c0e4a7 100755 --- a/release/scripts/mk-vmimage.sh +++ b/release/scripts/mk-vmimage.sh @@ -64,7 +64,7 @@ vm_create_baseimage() { truncate -s ${VMSIZE} ${VMBASE} mddev=$(mdconfig -f ${VMBASE}) newfs -L root -j ${mddev} - mount ${mddev} ${DESTDIR} + mount /dev/${mddev} ${DESTDIR} cd ${WORLDDIR} && \ ${IMAKE} DESTDIR=${DESTDIR} \ installworld installkernel distribution || \ From 79a94b12ae95bd01e1ff92f647d99526e1c79d49 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Sun, 28 Sep 2014 21:13:30 +0000 Subject: [PATCH 06/10] Fix UFS label for the root filesystem. Sponsored by: The FreeBSD Foundation --- release/scripts/mk-vmimage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh index d33b4c0e4a7..8e79e2998a5 100755 --- a/release/scripts/mk-vmimage.sh +++ b/release/scripts/mk-vmimage.sh @@ -63,7 +63,7 @@ vm_create_baseimage() { mkdir -p ${DESTDIR} truncate -s ${VMSIZE} ${VMBASE} mddev=$(mdconfig -f ${VMBASE}) - newfs -L root -j ${mddev} + newfs -L rootfs -j /dev/${mddev} mount /dev/${mddev} ${DESTDIR} cd ${WORLDDIR} && \ ${IMAKE} DESTDIR=${DESTDIR} \ From 5baa1b2730e0499cf04d953d6ea3923863fb36fe Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Sun, 28 Sep 2014 21:15:30 +0000 Subject: [PATCH 07/10] Remove comments left in accidentally while testing, so the VM /etc/fstab is actually created. Sponsored by: The FreeBSD Foundation --- release/scripts/mk-vmimage.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh index 8e79e2998a5..ef4daa7c34e 100755 --- a/release/scripts/mk-vmimage.sh +++ b/release/scripts/mk-vmimage.sh @@ -71,11 +71,11 @@ vm_create_baseimage() { panic 1 "\n\nCannot install the base system to ${DESTDIR}." chroot ${DESTDIR} /usr/bin/newaliases echo '# Custom /etc/fstab for FreeBSD VM images' \ - # > ${DESTDIR}/etc/fstab + > ${DESTDIR}/etc/fstab echo '/dev/gpt/rootfs / ufs rw 2 2' \ - # >> ${DESTDIR}/etc/fstab + >> ${DESTDIR}/etc/fstab echo '/dev/gpt/swapfs none swap sw 0 0' \ - # >> ${DESTDIR}/etc/fstab + >> ${DESTDIR}/etc/fstab sync while ! umount ${DESTDIR}; do i=$(( $i + 1 )) From 1e2f9a549bab82b4b22a8f546f11ba8774d61948 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Sun, 28 Sep 2014 23:22:55 +0000 Subject: [PATCH 08/10] Remove the UFS label from the root filesystem since it is added by mkimg(1) as a gpt label, consistent with the fstab(5) entry. Sponsored by: The FreeBSD Foundation --- release/scripts/mk-vmimage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh index ef4daa7c34e..19a485f0b2c 100755 --- a/release/scripts/mk-vmimage.sh +++ b/release/scripts/mk-vmimage.sh @@ -63,7 +63,7 @@ vm_create_baseimage() { mkdir -p ${DESTDIR} truncate -s ${VMSIZE} ${VMBASE} mddev=$(mdconfig -f ${VMBASE}) - newfs -L rootfs -j /dev/${mddev} + newfs -j /dev/${mddev} mount /dev/${mddev} ${DESTDIR} cd ${WORLDDIR} && \ ${IMAKE} DESTDIR=${DESTDIR} \ From f6490fe596e86bc170f7617bfe12e99e8009f328 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Mon, 29 Sep 2014 01:17:42 +0000 Subject: [PATCH 09/10] Comment cleanup in panic() message when mkimg(1) does not support the requested disk image format. Sponsored by: The FreeBSD Foundation --- release/scripts/mk-vmimage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh index 19a485f0b2c..f4ccf0248d3 100755 --- a/release/scripts/mk-vmimage.sh +++ b/release/scripts/mk-vmimage.sh @@ -104,7 +104,7 @@ vm_create_vmdisk() { fi if ! mkimg --formats 2>/dev/null | grep -q ${FORMAT}; then - panic 0 "Format ${FORMAT} is not supported with this mkimg(1)\n" + panic 0 "'${FORMAT}' is not supported by this mkimg(1).\n" fi case ${FORMAT} in From fadf2a24feb64564f71961a632b9fbeb6c298d15 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Wed, 1 Oct 2014 17:05:40 +0000 Subject: [PATCH 10/10] Separate release/scripts/mk-vmimage.sh to machine-specific scripts, making it possible to mimic the functionality for non-x86 targets. Move echo output if MAKEFLAGS is empty outside of usage(). Remove TARGET/TARGET_ARCH evaluation. Sponsored by: The FreeBSD Foundation --- release/Makefile | 4 +- release/{scripts => amd64}/mk-vmimage.sh | 15 +-- release/i386/mk-vmimage.sh | 147 +++++++++++++++++++++++ 3 files changed, 152 insertions(+), 14 deletions(-) rename release/{scripts => amd64}/mk-vmimage.sh (96%) create mode 100755 release/i386/mk-vmimage.sh diff --git a/release/Makefile b/release/Makefile index 7fdea8521d3..6080898330b 100644 --- a/release/Makefile +++ b/release/Makefile @@ -321,7 +321,7 @@ vm-base: VMBASE=${VMBASE}.img VMSIZE=${VMSIZE} \ DESTDIR=${.OBJDIR}/${.TARGET} \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ - ${.CURDIR}/scripts/mk-vmimage.sh ${.TARGET} + ${.CURDIR}/${TARGET}/mk-vmimage.sh ${.TARGET} .endif touch ${.TARGET} @@ -330,7 +330,7 @@ vm-image: vm-base . for FORMAT in ${VMFORMATS} env FORMAT=${FORMAT} VMIMAGE=${VMBASE}.${FORMAT} VMBASE=${VMBASE}.img \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ - ${.CURDIR}/scripts/mk-vmimage.sh ${.TARGET} + ${.CURDIR}/${TARGET}/mk-vmimage.sh ${.TARGET} . endfor .endif touch ${.TARGET} diff --git a/release/scripts/mk-vmimage.sh b/release/amd64/mk-vmimage.sh similarity index 96% rename from release/scripts/mk-vmimage.sh rename to release/amd64/mk-vmimage.sh index f4ccf0248d3..b717efd6390 100755 --- a/release/scripts/mk-vmimage.sh +++ b/release/amd64/mk-vmimage.sh @@ -37,9 +37,6 @@ export PATH usage() { echo "$(basename ${0}) [...]" - if [ -z "${MAKEFLAGS}" ]; then - echo "It is probably not safe to run this by hand yet..." - fi exit 1 } @@ -128,15 +125,9 @@ vm_create_vmdisk() { main() { cmd="${1}" - case ${TARGET}/${TARGET_ARCH} in - amd64/amd64|i386/i386) - # FALLTHROUGH - ;; - *) - # EX_CANTCREAT - return 0 - ;; - esac + if [ -z "${MAKEFLAGS}" ]; then + echo "It is probably not safe to run this by hand yet..." + fi case ${cmd} in vm-base) diff --git a/release/i386/mk-vmimage.sh b/release/i386/mk-vmimage.sh new file mode 100755 index 00000000000..b717efd6390 --- /dev/null +++ b/release/i386/mk-vmimage.sh @@ -0,0 +1,147 @@ +#!/bin/sh +#- +# Copyright (c) 2014 The FreeBSD Foundation +# All rights reserved. +# +# This software was developed by Glen Barber under sponsorship +# from the FreeBSD Foundation. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# mk-vmimage.sh: Create virtual machine disk images in various formats. +# +# $FreeBSD$ +# + +PATH="/bin:/usr/bin:/sbin:/usr/sbin" +export PATH + +usage() { + echo "$(basename ${0}) [...]" + exit 1 +} + +panic() { + rc="${1}" + shift 1 + msg="${@}" + printf "${msg}\n" + if [ ! -z "${mddev}" ]; then + mdconfig -d -u ${mddev} + fi + # Do not allow one failure case to chain through any remaining image + # builds. + exit 0 +} + +vm_create_baseimage() { + # Creates the UFS root filesystem for the virtual machine disk, + # written to the formatted disk image with mkimg(1). + i=0 + mkdir -p ${DESTDIR} + truncate -s ${VMSIZE} ${VMBASE} + mddev=$(mdconfig -f ${VMBASE}) + newfs -j /dev/${mddev} + mount /dev/${mddev} ${DESTDIR} + cd ${WORLDDIR} && \ + ${IMAKE} DESTDIR=${DESTDIR} \ + installworld installkernel distribution || \ + panic 1 "\n\nCannot install the base system to ${DESTDIR}." + chroot ${DESTDIR} /usr/bin/newaliases + echo '# Custom /etc/fstab for FreeBSD VM images' \ + > ${DESTDIR}/etc/fstab + echo '/dev/gpt/rootfs / ufs rw 2 2' \ + >> ${DESTDIR}/etc/fstab + echo '/dev/gpt/swapfs none swap sw 0 0' \ + >> ${DESTDIR}/etc/fstab + sync + while ! umount ${DESTDIR}; do + i=$(( $i + 1 )) + if [ $i -ge 10 ]; then + # This should never happen. But, it has happened. + msg="Cannot umount(8) ${DESTDIR}\n" + msg="${msg}Something has gone horribly wrong." + panic 1 "${msg}" + fi + sleep 1 + done + + return 0 +} + +vm_create_vmdisk() { + mkimg_version=$(mkimg --version 2>/dev/null | awk '{print $2}') + + # We need mkimg(1) '--version' output, at minimum, to be able to + # tell what virtual machine disk image formats are available. + # Bail if mkimg(1) reports an empty '--version' value. + if [ -z "${mkimg_version}" ]; then + msg="Cannot determine mkimg(1) version.\n" + msg="${msg}Cannot continue without a known mkimg(1) version." + panic 0 "${msg}" + fi + + if ! mkimg --formats 2>/dev/null | grep -q ${FORMAT}; then + panic 0 "'${FORMAT}' is not supported by this mkimg(1).\n" + fi + + case ${FORMAT} in + vhd) + mkimg_format=vhdf + ;; + *) + mkimg_format=${FORMAT} + ;; + esac + + mkimg -f ${mkimg_format} -s gpt \ + -b /boot/pmbr -p freebsd-boot/bootfs:=/boot/gptboot \ + -p freebsd-swap/swapfs::1G \ + -p freebsd-ufs/rootfs:=${VMBASE} \ + -o ${VMIMAGE} + + return 0 +} + +main() { + cmd="${1}" + + if [ -z "${MAKEFLAGS}" ]; then + echo "It is probably not safe to run this by hand yet..." + fi + + case ${cmd} in + vm-base) + eval vm_create_baseimage "$@" || return 0 + ;; + vm-image) + eval vm_create_vmdisk "$@" || return 0 + ;; + *|\?) + usage + ;; + esac + + return 0 +} + +main "$@"