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