mk-vmimage.sh revision 272793
1#!/bin/sh 2#- 3# Copyright (c) 2014 The FreeBSD Foundation 4# All rights reserved. 5# 6# This software was developed by Glen Barber under sponsorship 7# from the FreeBSD Foundation. 8# 9# Redistribution and use in source and binary forms, with or without 10# modification, are permitted provided that the following conditions 11# are met: 12# 1. Redistributions of source code must retain the above copyright 13# notice, this list of conditions and the following disclaimer. 14# 2. Redistributions in binary form must reproduce the above copyright 15# notice, this list of conditions and the following disclaimer in the 16# documentation and/or other materials provided with the distribution. 17# 18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28# SUCH DAMAGE. 29# 30# mk-vmimage.sh: Create virtual machine disk images in various formats. 31# 32# $FreeBSD: projects/release-vmimage/release/amd64/mk-vmimage.sh 272793 2014-10-09 03:29:52Z gjb $ 33# 34 35PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin" 36export PATH 37 38vm_prebuild_setup() { 39 return 0 40} 41 42vm_setup() { 43 return 0 44} 45 46vm_postbuild_setup() { 47 return 0 48} 49 50usage_vm_base() { 51 echo -n "$(basename ${0}) vm-base <base image> <source tree>" 52 echo " <dest dir> <disk image size>" 53 return 0 54} 55 56usage_vm_image() { 57 echo -n "$(basename ${0}) vm-image <base image> <image format>" 58 echo " <output image>" 59 return 0 60} 61 62usage() { 63 echo "Usage:" 64 echo "$(basename ${0}) [vm-base|vm-image] [...]" 65 echo 66 usage_vm_base 67 echo 68 usage_vm_image 69 exit 1 70} 71 72panic() { 73 msg="${@}" 74 printf "${msg}\n" 75 if [ ! -z "${mddev}" ]; then 76 mdconfig -d -u ${mddev} 77 fi 78 case ${cmd} in 79 vm-base) 80 # If the vm-base target fails, the vm-image target 81 # cannot possibly succeed. Touch the .TARGET file 82 # so it is not attempted. 83 touch vm-image 84 ;; 85 *) 86 # FALLTHROUGH 87 ;; 88 esac 89 # Do not allow one failure case to chain through any remaining image 90 # builds. 91 return 1 92} 93 94vm_create_baseimage() { 95 # Creates the UFS root filesystem for the virtual machine disk, 96 # written to the formatted disk image with mkimg(1). 97 # 98 # Arguments: 99 # vm-base <base image> <source tree> <dest dir> <disk image size> 100 101 VMBASE="${1}" 102 WORLDDIR="${2}" 103 DESTDIR="${3}" 104 VMSIZE="${4}" 105 106 if [ -z "${VMBASE}" -o -z "${WORLDDIR}" -o -z "${DESTDIR}" \ 107 -o -z "${VMSIZE}" ]; then 108 usage 109 fi 110 111 i=0 112 mkdir -p ${DESTDIR} 113 truncate -s ${VMSIZE} ${VMBASE} 114 mddev=$(mdconfig -f ${VMBASE}) 115 newfs -j /dev/${mddev} 116 mount /dev/${mddev} ${DESTDIR} 117 cd ${WORLDDIR} && \ 118 make DESTDIR=${DESTDIR} \ 119 installworld installkernel distribution || \ 120 panic "\n\nCannot install the base system to ${DESTDIR}." 121 chroot ${DESTDIR} /usr/bin/newaliases 122 echo '# Custom /etc/fstab for FreeBSD VM images' \ 123 > ${DESTDIR}/etc/fstab 124 echo '/dev/gpt/rootfs / ufs rw 2 2' \ 125 >> ${DESTDIR}/etc/fstab 126 echo '/dev/gpt/swapfs none swap sw 0 0' \ 127 >> ${DESTDIR}/etc/fstab 128 sync 129 while ! umount ${DESTDIR}; do 130 i=$(( $i + 1 )) 131 if [ $i -ge 10 ]; then 132 # This should never happen. But, it has happened. 133 msg="Cannot umount(8) ${DESTDIR}\n" 134 msg="${msg}Something has gone horribly wrong." 135 panic "${msg}" 136 fi 137 sleep 1 138 done 139 140 return 0 141} 142 143vm_create_vmdisk() { 144 # Creates the virtual machine disk image from the raw disk image. 145 # 146 # Arguments: 147 # vm-image <base image> <image format> <output image>" 148 149 VMBASE="${1}" 150 FORMAT="${2}" 151 VMIMAGE="${3}" 152 153 if [ -z "${VMBASE}" -o -z "${FORMAT}" -o -z "${VMIMAGE}" ]; then 154 usage 155 fi 156 157 mkimg_version=$(mkimg --version 2>/dev/null | awk '{print $2}') 158 159 # We need mkimg(1) '--version' output, at minimum, to be able to 160 # tell what virtual machine disk image formats are available. 161 # Bail if mkimg(1) reports an empty '--version' value. 162 if [ -z "${mkimg_version}" ]; then 163 msg="Cannot determine mkimg(1) version.\n" 164 msg="${msg}Cannot continue without a known mkimg(1) version." 165 panic "${msg}" 166 fi 167 168 if ! mkimg --formats 2>/dev/null | grep -q ${FORMAT}; then 169 panic "'${FORMAT}' is not supported by this mkimg(1).\n" 170 fi 171 172 case ${FORMAT} in 173 vhd) 174 mkimg_format=vhdf 175 ;; 176 *) 177 mkimg_format=${FORMAT} 178 ;; 179 esac 180 181 mkimg -f ${mkimg_format} -s gpt \ 182 -b /boot/pmbr -p freebsd-boot/bootfs:=/boot/gptboot \ 183 -p freebsd-swap/swapfs::1G \ 184 -p freebsd-ufs/rootfs:=${VMBASE} \ 185 -o ${VMIMAGE} 186 187 return 0 188} 189 190main() { 191 cmd="${1}" 192 shift 1 193 194 case ${cmd} in 195 vm-base) 196 eval vm_create_baseimage "$@" || return 0 197 ;; 198 vm-image) 199 eval vm_create_vmdisk "$@" || return 0 200 ;; 201 *|\?) 202 usage 203 ;; 204 esac 205 206 return 0 207} 208 209main "$@" 210