]> CyberLeo.Net >> Repos - FreeBSD/releng/10.1.git/blob - release/amd64/mk-vmimage.sh
Merge r273184, r273185 from stable/10:
[FreeBSD/releng/10.1.git] / release / amd64 / mk-vmimage.sh
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$
33 #
34
35 PATH="/bin:/usr/bin:/sbin:/usr/sbin"
36 export PATH
37
38 usage_vm_base() {
39         echo -n "$(basename ${0}) vm-base <base image> <source tree>"
40         echo    " <dest dir> <disk image size>"
41         return 0
42 }
43
44 usage_vm_image() {
45         echo -n "$(basename ${0}) vm-image <base image> <image format>"
46         echo    " <output image>"
47         return 0
48 }
49
50 usage() {
51         echo "Usage:"
52         echo "$(basename ${0}) [vm-base|vm-image] [...]"
53         echo
54         usage_vm_base
55         echo
56         usage_vm_image
57         exit 1
58 }
59
60 panic() {
61         rc="${1}"
62         shift 1
63         msg="${@}"
64         printf "${msg}\n"
65         if [ ! -z "${mddev}" ]; then
66                 mdconfig -d -u ${mddev}
67         fi
68         # Do not allow one failure case to chain through any remaining image
69         # builds.
70         exit 0
71 }
72
73 vm_create_baseimage() {
74         # Creates the UFS root filesystem for the virtual machine disk,
75         # written to the formatted disk image with mkimg(1).
76         #
77         # Arguments:
78         # vm-base <base image> <source tree> <dest dir> <disk image size>
79
80         VMBASE="${1}"
81         WORLDDIR="${2}"
82         DESTDIR="${3}"
83         VMSIZE="${4}"
84
85         if [ -z "${VMBASE}" -o -z "${WORLDDIR}" -o -z "${DESTDIR}" \
86                 -o -z "${VMSIZE}" ]; then
87                         usage
88         fi
89
90         i=0
91         mkdir -p ${DESTDIR}
92         truncate -s ${VMSIZE} ${VMBASE}
93         mddev=$(mdconfig -f ${VMBASE})
94         newfs -j /dev/${mddev}
95         mount /dev/${mddev} ${DESTDIR}
96         cd ${WORLDDIR} && \
97                 make DESTDIR=${DESTDIR} \
98                 installworld installkernel distribution || \
99                 panic 1 "\n\nCannot install the base system to ${DESTDIR}."
100         chroot ${DESTDIR} /usr/bin/newaliases
101         echo '# Custom /etc/fstab for FreeBSD VM images' \
102                 > ${DESTDIR}/etc/fstab
103         echo '/dev/gpt/rootfs   /       ufs     rw      2       2' \
104                 >> ${DESTDIR}/etc/fstab
105         echo '/dev/gpt/swapfs   none    swap    sw      0       0' \
106                 >> ${DESTDIR}/etc/fstab
107         sync
108         while ! umount ${DESTDIR}; do
109                 i=$(( $i + 1 ))
110                 if [ $i -ge 10 ]; then
111                         # This should never happen.  But, it has happened.
112                         msg="Cannot umount(8) ${DESTDIR}\n"
113                         msg="${msg}Something has gone horribly wrong."
114                         panic 1 "${msg}"
115                 fi
116                 sleep 1
117         done
118
119         return 0
120 }
121
122 vm_create_vmdisk() {
123         # Creates the virtual machine disk image from the raw disk image.
124         #
125         # Arguments:
126         # vm-image <base image> <image format> <output image>"
127
128         VMBASE="${1}"
129         FORMAT="${2}"
130         VMIMAGE="${3}"
131
132         if [ -z "${VMBASE}" -o -z "${FORMAT}" -o -z "${VMIMAGE}" ]; then
133                 usage
134         fi
135
136         mkimg_version=$(mkimg --version 2>/dev/null | awk '{print $2}')
137
138         # We need mkimg(1) '--version' output, at minimum, to be able to
139         # tell what virtual machine disk image formats are available.
140         # Bail if mkimg(1) reports an empty '--version' value.
141         if [ -z "${mkimg_version}" ]; then
142                 msg="Cannot determine mkimg(1) version.\n"
143                 msg="${msg}Cannot continue without a known mkimg(1) version."
144                 panic 0 "${msg}"
145         fi
146
147         if ! mkimg --formats 2>/dev/null | grep -q ${FORMAT}; then
148                 panic 0 "'${FORMAT}' is not supported by this mkimg(1).\n"
149         fi
150
151         case ${FORMAT} in
152                 vhd)
153                         mkimg_format=vhdf
154                         ;;
155                 *)
156                         mkimg_format=${FORMAT}
157                         ;;
158         esac
159
160         mkimg -f ${mkimg_format} -s gpt \
161                 -b /boot/pmbr -p freebsd-boot/bootfs:=/boot/gptboot \
162                 -p freebsd-swap/swapfs::1G \
163                 -p freebsd-ufs/rootfs:=${VMBASE} \
164                 -o ${VMIMAGE}
165
166         return 0
167 }
168
169 main() {
170         cmd="${1}"
171         shift 1
172
173         case ${cmd} in
174                 vm-base)
175                         eval vm_create_baseimage "$@" || return 0
176                         ;;
177                 vm-image)
178                         eval vm_create_vmdisk "$@" || return 0
179                         ;;
180                 *|\?)
181                         usage
182                         ;;
183         esac
184
185         return 0
186 }
187
188 main "$@"