1273076Sgjb#!/bin/sh 2273076Sgjb#- 3273076Sgjb# Copyright (c) 2014 The FreeBSD Foundation 4273076Sgjb# All rights reserved. 5273076Sgjb# 6273076Sgjb# This software was developed by Glen Barber under sponsorship 7273076Sgjb# from the FreeBSD Foundation. 8273076Sgjb# 9273076Sgjb# Redistribution and use in source and binary forms, with or without 10273076Sgjb# modification, are permitted provided that the following conditions 11273076Sgjb# are met: 12273076Sgjb# 1. Redistributions of source code must retain the above copyright 13273076Sgjb# notice, this list of conditions and the following disclaimer. 14273076Sgjb# 2. Redistributions in binary form must reproduce the above copyright 15273076Sgjb# notice, this list of conditions and the following disclaimer in the 16273076Sgjb# documentation and/or other materials provided with the distribution. 17273076Sgjb# 18273076Sgjb# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19273076Sgjb# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20273076Sgjb# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21273076Sgjb# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22273076Sgjb# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23273076Sgjb# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24273076Sgjb# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25273076Sgjb# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26273076Sgjb# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27273076Sgjb# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28273076Sgjb# SUCH DAMAGE. 29273076Sgjb# 30273076Sgjb# mk-azure.sh: Create virtual machine disk images for Microsoft Azure 31273076Sgjb# 32273076Sgjb# $FreeBSD$ 33273076Sgjb# 34273076Sgjb 35273076Sgjbexport PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin" 36273076Sgjb 37273076Sgjbusage() { 38273076Sgjb echo "Usage:" 39273076Sgjb echo -n "$(basename ${0}) vm-azure <base image>" 40273076Sgjb echo " <source tree> <dest dir> <disk image size> <vm image name>" 41273076Sgjb exit 1 42273076Sgjb} 43273076Sgjb 44273076Sgjbpanic() { 45273076Sgjb msg="${@}" 46273076Sgjb printf "${msg}\n" 47273076Sgjb if [ ! -z "${mddev}" ]; then 48273076Sgjb mdconfig -d -u ${mddev} 49273076Sgjb fi 50273076Sgjb # Do not allow one failure case to chain through any remaining image 51273076Sgjb # builds. 52273076Sgjb exit 0 53273076Sgjb} 54273076Sgjb 55273076Sgjbvm_create_azure() { 56273076Sgjb # Arguments: 57273076Sgjb # vm-azure <base image> <source tree> <dest dir> <disk image size> <vm image name> 58273076Sgjb 59273076Sgjb VMBASE="${1}" 60273076Sgjb WORLDDIR="${2}" 61273076Sgjb DESTDIR="${3}" 62273076Sgjb VMSIZE="${4}" 63273076Sgjb VMIMAGE="${5}" 64273076Sgjb 65273076Sgjb if [ -z "${VMBASE}" -o -z "${WORLDDIR}" -o -z "${DESTDIR}" \ 66273076Sgjb -o -z "${VMSIZE}" -o -z "${VMIMAGE}" ]; then 67273076Sgjb usage 68273076Sgjb fi 69273076Sgjb 70273096Sgjb trap "umount ${DESTDIR}/dev ${DESTDIR}" INT QUIT TRAP ABRT TERM 71273076Sgjb 72273076Sgjb i=0 73273076Sgjb mkdir -p ${DESTDIR} 74273076Sgjb truncate -s ${VMSIZE} ${VMBASE} 75273076Sgjb mddev=$(mdconfig -f ${VMBASE}) 76273076Sgjb newfs -j /dev/${mddev} 77273076Sgjb mkdir -p ${DESTDIR} 78273076Sgjb mount /dev/${mddev} ${DESTDIR} 79273076Sgjb make -C ${WORLDDIR} DESTDIR=$(realpath ${DESTDIR}) \ 80273076Sgjb installworld installkernel distribution || \ 81273076Sgjb panic 1 "\n\nCannot install the base system to ${DESTDIR}." 82273076Sgjb mount -t devfs devfs ${DESTDIR}/dev 83273076Sgjb chroot ${DESTDIR} /usr/bin/newaliases 84273076Sgjb echo '# Custom /etc/fstab for FreeBSD VM images' \ 85273076Sgjb > ${DESTDIR}/etc/fstab 86273076Sgjb echo '/dev/gpt/rootfs / ufs rw 2 2' \ 87273076Sgjb >> ${DESTDIR}/etc/fstab 88273076Sgjb # Although a swap partition is created, it is not used in Azure. 89273076Sgjb echo '#/dev/gpt/swapfs none swap sw 0 0' \ 90273076Sgjb >> ${DESTDIR}/etc/fstab 91273076Sgjb 92273076Sgjb chroot ${DESTDIR} /etc/rc.d/ldconfig forcestart 93273076Sgjb chroot ${DESTDIR} env ASSUME_ALWAYS_YES=yes /usr/sbin/pkg bootstrap -y 94273076Sgjb chroot ${DESTDIR} env ASSUME_ALWAYS_YES=yes /usr/sbin/pkg install -y \ 95273076Sgjb python python2 python27 py27-asn1 sudo bash 96273076Sgjb if [ ! -z "${VM_EXTRA_PACKAGES}" ]; then 97273076Sgjb chroot ${DESTDIR} env ASSUME_ALWAYS_YES=yes /usr/sbin/pkg install -y \ 98273076Sgjb ${VM_EXTRA_PACKAGES} 99273076Sgjb fi 100273076Sgjb 101273076Sgjb fetch -o ${DESTDIR}/usr/sbin/waagent \ 102273076Sgjb http://people.freebsd.org/~gjb/waagent 103273076Sgjb chmod +x ${DESTDIR}/usr/sbin/waagent 104273076Sgjb rm -f ${DESTDIR}/etc/resolv.conf 105273076Sgjb chroot ${DESTDIR} /usr/sbin/waagent -verbose -install 106273076Sgjb yes | chroot ${DESTDIR} /usr/sbin/waagent -deprovision 107273076Sgjb echo 'sshd_enable="YES"' > ${DESTDIR}/etc/rc.conf 108273076Sgjb echo 'ifconfig_hn0="SYNCDHCP"' >> ${DESTDIR}/etc/rc.conf 109273076Sgjb echo 'waagent_enable="YES"' >> ${DESTDIR}/etc/rc.conf 110273076Sgjb 111273076Sgjb echo 'console="comconsole vidconsole"' >> ${DESTDIR}/boot/loader.conf 112273076Sgjb echo 'comconsole_speed="115200"' >> ${DESTDIR}/boot/loader.conf 113273076Sgjb 114273076Sgjb if [ ! -z "${VM_RC_LIST}" ]; then 115273076Sgjb for _rcvar in ${VM_RC_LIST}; do 116273076Sgjb echo ${_rcvar}_enable="YES" >> ${DESTDIR}/etc/rc.conf 117273076Sgjb done 118273076Sgjb fi 119273076Sgjb 120273076Sgjb sync 121273076Sgjb 122273076Sgjb while ! umount ${DESTDIR}/dev ${DESTDIR}; do 123273076Sgjb i=$(( $i + 1 )) 124273076Sgjb if [ $i -ge 10 ]; then 125273076Sgjb # This should never happen. But, it has happened. 126273076Sgjb msg="Cannot umount(8) ${DESTDIR}\n" 127273076Sgjb msg="${msg}Something has gone horribly wrong." 128273076Sgjb panic 1 "${msg}" 129273076Sgjb fi 130273076Sgjb sleep 1 131273076Sgjb done 132273076Sgjb 133273096Sgjb echo "Creating image... Please wait." 134273096Sgjb 135273076Sgjb mkimg -f vhdf -s gpt \ 136273076Sgjb -b /boot/pmbr -p freebsd-boot/bootfs:=/boot/gptboot \ 137273076Sgjb -p freebsd-swap/swapfs::1G \ 138273076Sgjb -p freebsd-ufs/rootfs:=${VMBASE} \ 139273076Sgjb -o ${VMIMAGE}.raw 140273076Sgjb 141273076Sgjb if [ ! -x "/usr/local/bin/qemu-img" ]; then 142273076Sgjb env ASSUME_ALWAYS_YES=yes pkg install -y emulators/qemu-devel 143273076Sgjb fi 144273076Sgjb 145273076Sgjb size=$(qemu-img info -f raw --output json ${VMIMAGE}.raw | awk '/virtual-size/ {print $2}' | tr -d ',') 146273076Sgjb size=$(( ( ${size} / ( 1024 * 1024 ) + 1 ) * ( 1024 * 1024 ) )) 147273076Sgjb qemu-img resize ${VMIMAGE}.raw ${size} 148273076Sgjb qemu-img convert -f raw -o subformat=fixed -O vpc ${VMIMAGE}.raw ${VMIMAGE} 149273076Sgjb 150273076Sgjb return 0 151273076Sgjb} 152273076Sgjb 153273076Sgjbmain() { 154273076Sgjb cmd="${1}" 155273076Sgjb shift 1 156273076Sgjb 157273076Sgjb if [ -e "${AZURECONF}" -a ! -c "${AZURECONF}" ]; then 158273076Sgjb . ${AZURECONF} 159273076Sgjb fi 160273076Sgjb 161273076Sgjb case ${cmd} in 162273076Sgjb vm-azure) 163273076Sgjb eval vm_create_azure "$@" || return 0 164273076Sgjb ;; 165273076Sgjb *|\?) 166273076Sgjb usage 167273076Sgjb ;; 168273076Sgjb esac 169273076Sgjb 170273076Sgjb return 0 171273076Sgjb} 172273076Sgjb 173273076Sgjbmain "$@" 174