]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - release/tools/vmimage.subr
MFC r280299, r280840, r280846, r280879, r280881, r280884, r280928,
[FreeBSD/stable/10.git] / release / tools / vmimage.subr
1 #!/bin/sh
2 #
3 # $FreeBSD$
4 #
5 #
6 # Common functions for virtual machine image build scripts.
7 #
8
9 export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
10 trap "cleanup" INT QUIT TRAP ABRT TERM
11
12 write_partition_layout() {
13         if [ -z "${NOSWAP}" ]; then
14                 SWAPOPT="-p freebsd-swap/swapfs::1G"
15         fi
16
17         _OBJDIR="$(make -C ${WORLDDIR} -V .OBJDIR)"
18         if [ -d "${_OBJDIR%%/usr/src}/${TARGET}.${TARGET_ARCH}" ]; then
19                 BOOTFILES="/${_OBJDIR%%/usr/src}/${TARGET}.${TARGET_ARCH}/usr/src/sys/boot"
20         else
21                 BOOTFILES="/${_OBJDIR}/sys/boot"
22         fi
23
24         case "${TARGET}:${TARGET_ARCH}" in
25                 amd64:amd64 | i386:i386)
26                         mkimg -s gpt -b ${BOOTFILES}/i386/pmbr/pmbr \
27                                 -p freebsd-boot/bootfs:=${BOOTFILES}/i386/gptboot/gptboot \
28                                 ${SWAPOPT} \
29                                 -p freebsd-ufs/rootfs:=${VMBASE} \
30                                 -o ${VMIMAGE}
31                         ;;
32                 powerpc:powerpc*)
33                         mkimg -s apm \
34                                 -p apple-boot/bootfs:=${BOOTFILES}/powerpc/boot1.chrp/boot1.hfs \
35                                 ${SWAPOPT} \
36                                 -p freebsd-ufs/rootfs:=${VMBASE} \
37                                 -o ${VMIMAGE}
38                         ;;
39                 *)
40                         # ENOTSUPP
41                         return 1
42                         ;;
43         esac
44
45         return 0
46 }
47
48 err() {
49         printf "${@}\n"
50         cleanup
51         return 1
52 }
53
54 cleanup() {
55         if [ -c "${DESTDIR}/dev/null" ]; then
56                 umount_loop ${DESTDIR}/dev 2>/dev/null
57         fi
58         umount_loop ${DESTDIR}
59         if [ ! -z "${mddev}" ]; then
60                 mdconfig -d -u ${mddev}
61         fi
62
63         return 0
64 }
65
66 vm_create_base() {
67         # Creates the UFS root filesystem for the virtual machine disk,
68         # written to the formatted disk image with mkimg(1).
69
70         mkdir -p ${DESTDIR}
71         truncate -s ${VMSIZE} ${VMBASE}
72         mddev=$(mdconfig -f ${VMBASE})
73         newfs /dev/${mddev}
74         mount /dev/${mddev} ${DESTDIR}
75
76         return 0
77 }
78
79 vm_copy_base() {
80         # Creates a new UFS root filesystem and copies the contents of the
81         # current root filesystem into it.  This produces a "clean" disk
82         # image without any remnants of files which were created temporarily
83         # during image-creation and have since been deleted (e.g., downloaded
84         # package archives).
85
86         mkdir -p ${DESTDIR}/old
87         mdold=$(mdconfig -f ${VMBASE})
88         mount /dev/${mdold} ${DESTDIR}/old
89
90         truncate -s ${VMSIZE} ${VMBASE}.tmp
91         mkdir -p ${DESTDIR}/new
92         mdnew=$(mdconfig -f ${VMBASE}.tmp)
93         newfs /dev/${mdnew}
94         mount /dev/${mdnew} ${DESTDIR}/new
95
96         tar -cf- -C ${DESTDIR}/old . | tar -xUf- -C ${DESTDIR}/new
97
98         umount_loop /dev/${mdold}
99         rmdir ${DESTDIR}/old
100         mdconfig -d -u ${mdold}
101
102         umount_loop /dev/${mdnew}
103         rmdir ${DESTDIR}/new
104         tunefs -j enable /dev/${mdnew}
105         mdconfig -d -u ${mdnew}
106         mv ${VMBASE}.tmp ${VMBASE}
107 }
108
109 vm_install_base() {
110         # Installs the FreeBSD userland/kernel to the virtual machine disk.
111
112         cd ${WORLDDIR} && \
113                 make DESTDIR=${DESTDIR} \
114                 installworld installkernel distribution || \
115                 err "\n\nCannot install the base system to ${DESTDIR}."
116
117         echo '# Custom /etc/fstab for FreeBSD VM images' \
118                 > ${DESTDIR}/etc/fstab
119         echo '/dev/gpt/rootfs   /       ufs     rw      1       1' \
120                 >> ${DESTDIR}/etc/fstab
121         if [ -z "${NOSWAP}" ]; then
122                 echo '/dev/gpt/swapfs  none    swap    sw      0       0' \
123                         >> ${DESTDIR}/etc/fstab
124         fi
125
126         mkdir -p ${DESTDIR}/dev
127         mount -t devfs devfs ${DESTDIR}/dev
128         chroot ${DESTDIR} /usr/bin/newaliases
129         chroot ${DESTDIR} /etc/rc.d/ldconfig forcestart
130         umount_loop ${DESTDIR}/dev
131
132         cp /etc/resolv.conf ${DESTDIR}/etc/resolv.conf
133
134         return 0
135 }
136
137 vm_extra_install_base() {
138         # Prototype.  When overridden, runs extra post-installworld commands
139         # as needed, based on the target virtual machine image or cloud
140         # provider image target.
141
142         return 0
143 }
144
145 vm_extra_enable_services() {
146         if [ ! -z "${VM_RC_LIST}" ]; then
147                 for _rcvar in ${VM_RC_LIST}; do
148                         echo ${_rcvar}_enable="YES" >> ${DESTDIR}/etc/rc.conf
149                 done
150         fi
151
152         return 0
153 }
154
155 vm_extra_install_packages() {
156         if [ -z "${VM_EXTRA_PACKAGES}" ]; then
157                 return 0
158         fi
159         mkdir -p ${DESTDIR}/dev
160         mount -t devfs devfs ${DESTDIR}/dev
161         chroot ${DESTDIR} env ASSUME_ALWAYS_YES=yes \
162                 /usr/sbin/pkg bootstrap -y
163         chroot ${DESTDIR} env ASSUME_ALWAYS_YES=yes \
164                 /usr/sbin/pkg install -y ${VM_EXTRA_PACKAGES}
165         umount_loop ${DESTDIR}/dev
166
167         return 0
168 }
169
170 vm_extra_install_ports() {
171         # Prototype.  When overridden, installs additional ports within the
172         # virtual machine environment.
173
174         return 0
175 }
176
177 vm_extra_pre_umount() {
178         # Prototype.  When overridden, installs additional ports within the
179         # virtual machine environment.
180
181         rm -f ${DESTDIR}/etc/resolv.conf
182         return 0
183 }
184
185 vm_extra_pkg_rmcache() {
186         if [ -e ${DESTDIR}/usr/local/sbin/pkg ]; then
187                 chroot ${DESTDIR} env ASSUME_ALWAYS_YES=yes \
188                         /usr/local/sbin/pkg clean -y -a
189         fi
190
191         return 0
192 }
193
194 umount_loop() {
195         DIR=$1
196         i=0
197         sync
198         while ! umount ${DIR}; do
199                 i=$(( $i + 1 ))
200                 if [ $i -ge 10 ]; then
201                         # This should never happen.  But, it has happened.
202                         echo "Cannot umount(8) ${DIR}"
203                         echo "Something has gone horribly wrong."
204                         return 1
205                 fi
206                 sleep 1
207         done
208
209         return 0
210 }
211
212 vm_create_disk() {
213         echo "Creating image...  Please wait."
214         echo
215
216         write_partition_layout || return 1
217
218         return 0
219 }
220
221 vm_extra_create_disk() {
222
223         return 0
224 }
225