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