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