From 2832bc47e1030910485b1ae6e4646a8e9f2b28d9 Mon Sep 17 00:00:00 2001 From: Leo Simons Date: Mon, 21 Jul 2014 14:50:08 +0200 Subject: [PATCH] CLOUDSTACK-7143: improve build.sh ergonomics Added a bunch of possible arguments / environment variables, see the new usage function for details (or run ./build.sh help). Creates a new template with a unique name on every invocation, resulting in a new virtualbox instance with a unique name. This makes it possible to build multiple boxes at the same time, in parallel (including for example on a multiuser box), and reduces the chance of failed build results conflicting with each other. Inject the version given on the command line (if any) into the created image. --- tools/appliance/build.sh | 201 +++++++++++++++++++++++++++++++-------- 1 file changed, 159 insertions(+), 42 deletions(-) diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh index 57d2298bd70..5d74b610df7 100755 --- a/tools/appliance/build.sh +++ b/tools/appliance/build.sh @@ -1,4 +1,6 @@ -#!/bin/bash -xl +#!/bin/bash -l +# note: the -l is needed here for bash to always make a login shell and load rvm if it hasn't been loaded +# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -16,10 +18,90 @@ # specific language governing permissions and limitations # under the License. -set -x +# build script which wraps around veewee and virtualbox to create the systemvm template -appliance="${1:-systemvmtemplate}" -arch="i386" +function usage() { + cat </dev/null && usage +echo $@ | grep '\-h' >/dev/null && usage + +# requires 32-bit vhd-util and faketime binaries to be available (even for 64 bit builds) +# Something like (on centos 6.5)... +# * faketime +# wget -q http://bits.xensource.com/oss-xen/release/4.2.0/xen-4.2.0.tar.gz +# sudo yum -y install libuuid.i686 +# cd repo/libfaketime/ +# vim Makefile +# # (tune 32 bit) +# make +# sudo make install +# * vhd-util +# sudo yum -y install python-devel dev86 iasl iasl-devel libuuid libuuid-devel \ +# glib-devel glib2 glib2-devel yajl yajl-devel +# wget -q http://bits.xensource.com/oss-xen/release/4.2.0/xen-4.2.0.tar.gz +# tar xzvf xen-4.2.0.tar.gz +# cd xen-4.2.0/tools/ +# wget https://github.com/citrix-openstack/xenserver-utils/raw/master/blktap2.patch -qO - | patch -p0 +# ./configure --disable-monitors --disable-ocamltools --disable-rombios --disable-seabios +# make +# sudo cp ./blktap2/vhd/lib/libvhd.so.1.0 /usr/lib64/ +# ldconfig +# sudo ldconfig +# sudo cp blktap2/vhd/vhd-util /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver +# faketime 2010-01-01 vhd-util convert + +set -e + +### +### Configuration +### +# whether to show DEBUG logs +DEBUG="${DEBUG:-}" +# whether to have other commands trace their actions +TRACE="${TRACE:-0}" +JENKINS_HOME=${JENKINS_HOME:-} +if [[ ! -z "${JENKINS_HOME}" ]]; then + DEBUG=1 +fi +VEEWEE_ARGS="${VEEWEE_ARGS:-}" +if [[ "${VEEWEE_ARGS}" == "" && "${TRACE}" == "1" ]]; then + VEEWEE_ARGS="${VEEWEE_ARGS} --debug" +fi +VEEWEE_BUILD_ARGS="${VEEWEE_BUILD_ARGS:-${VEEWEE_ARGS} --nogui --auto}" + +# which veewee definition to use +appliance="${1:-${appliance:-systemvmtemplate}}" + +# optional version tag to put into the image filename +version="${2:-${version:-}}" + +# branch tag to put into the image filename, populated from `git status` if unset +branch="${3:-${branch:-}}" + +# optional (jenkins) build number tag to put into the image filename +BUILD_NUMBER="${4:-${BUILD_NUMBER:-}}" + +arch="${arch:-i386}" if [ "${appliance}" == "systemvm64template" ]; then arch="amd64" export VM_ARCH="${arch}" @@ -27,42 +109,76 @@ if [ "${appliance}" == "systemvm64template" ]; then cp -r definitions/systemvmtemplate definitions/systemvm64template fi -build_date=`date +%Y-%m-%d` - -# set fixed or leave empty to use git to determine -branch= - -if [ -z "$branch" ] ; then - branch=`(git name-rev --no-undefined --name-only HEAD 2>/dev/null || echo unknown) | sed -e 's/remotes\/.*\///g'` +# while building with vbox, we need a quite unique appliance name in order to prevent conflicts with multiple +# concurrent executors on jenkins +if [ -z "${branch}" ] ; then + branch=`(git name-rev --no-undefined --name-only HEAD 2>/dev/null || echo unknown) | sed -e 's/remotes\/.*\///g'` fi -rootdir=$PWD +branch_tag= +if [ ! -z "${branch}" ]; then + branch_tag="-${branch}" +fi + +version_tag= +if [ ! -z "${version}" ]; then + if [ ! -z "${BUILD_NUMBER}" ]; then + version="${version}.${BUILD_NUMBER}" + fi + version_tag="-${version}" +elif [ ! -z "${BUILD_NUMBER}" ]; then + version="${BUILD_NUMBER}" + version_tag="-${BUILD_NUMBER}" +fi + +appliance_build_name=${appliance}${branch_tag}${version_tag} + +# how to tell sed to use extended regular expressions +os=`uname` +sed_regex_option="-E" +if [ "${os}" == "Linux" ]; then + sed_regex_option="-r" +fi + +# logging support +if [[ "${DEBUG}" == "1" ]]; then + set -x +fi + +# Create custom template definition +if [ "${appliance}" != "${appliance_build_name}" ]; then + cp -r "definitions/${appliance}" "definitions/${appliance_build_name}" + set +e + sed ${sed_regex_option} -i -e "s/^CLOUDSTACK_RELEASE=.+/CLOUDSTACK_RELEASE=${version}/" \ + "definitions/${appliance_build_name}/configure_systemvm_services.sh" + set -e +fi # Initialize veewee and dependencies bundle # Clean and start building the appliance -bundle exec veewee vbox destroy $appliance -bundle exec veewee vbox build $appliance --nogui --auto -bundle exec veewee vbox halt $appliance +bundle exec veewee vbox destroy ${appliance_build_name} ${VEEWEE_ARGS} +bundle exec veewee vbox build ${appliance_build_name} ${VEEWEE_BUILD_ARGS} +bundle exec veewee vbox halt ${appliance_build_name} ${VEEWEE_ARGS} -while [[ `vboxmanage list runningvms | grep $appliance | wc -l` -ne 0 ]]; +while [[ `vboxmanage list runningvms | grep ${appliance_build_name} | wc -l` -ne 0 ]]; do - echo "Waiting for $appliance to shutdown" + echo "Waiting for ${appliance_build_name} to shutdown" sleep 2; done # Get appliance uuids -machine_uuid=`vboxmanage showvminfo $appliance | grep UUID | head -1 | awk '{print $2}'` -hdd_uuid=`vboxmanage showvminfo $appliance | grep vdi | head -1 | awk '{print $8}' | cut -d ')' -f 1` -hdd_path=`vboxmanage list hdds | grep "$appliance\/" | grep vdi | cut -c 14- | sed 's/^ *//'` +machine_uuid=`vboxmanage showvminfo ${appliance_build_name} | grep UUID | head -1 | awk '{print $2}'` +hdd_uuid=`vboxmanage showvminfo ${appliance_build_name} | grep vdi | head -1 | awk '{print $8}' | cut -d ')' -f 1` +hdd_path=`vboxmanage list hdds | grep "${appliance_build_name}\/" | grep vdi | cut -c 14- | sed 's/^ *//'` # Remove any shared folder -shared_folders=`vboxmanage showvminfo $appliance | grep Name | grep Host` +shared_folders=`vboxmanage showvminfo ${appliance_build_name} | grep Name | grep Host` while [ "$shared_folders" != "" ] do - vboxmanage sharedfolder remove $appliance --name "`echo $shared_folders | head -1 | cut -c 8- | cut -d \' -f 1`" - shared_folders=`vboxmanage showvminfo $appliance | grep Name | grep Host` + vboxmanage sharedfolder remove ${appliance_build_name} --name "`echo $shared_folders | head -1 | cut -c 8- | cut -d \' -f 1`" + shared_folders=`vboxmanage showvminfo ${appliance_build_name} | grep Name | grep Host` done # Compact the virtual hdd @@ -78,12 +194,12 @@ if [ $? == 0 ]; then set -e vboxmanage internalcommands converttoraw -format vdi "$hdd_path" img.raw vhd-util convert -s 0 -t 1 -i img.raw -o stagefixed.vhd - faketime '2010-01-01' vhd-util convert -s 1 -t 2 -i stagefixed.vhd -o $appliance-$branch-xen.vhd + faketime '2010-01-01' vhd-util convert -s 1 -t 2 -i stagefixed.vhd -o ${appliance_build_name}-xen.vhd rm *.bak - bzip2 $appliance-$branch-xen.vhd - echo "$appliance exported for XenServer: dist/$appliance-$branch-xen.vhd.bz2" + bzip2 ${appliance_build_name}-xen.vhd + echo "${appliance_build_name} exported for XenServer: dist/${appliance_build_name}-xen.vhd.bz2" else - echo "** Skipping $appliance export for XenServer: faketime or vhd-util command is missing. **" + echo "** Skipping ${appliance_build_name} export for XenServer: faketime or vhd-util command is missing. **" echo "** faketime source code is available from https://github.com/wolfcw/libfaketime **" fi @@ -92,27 +208,28 @@ set -e # Export for KVM vboxmanage internalcommands converttoraw -format vdi "$hdd_path" raw.img -qemu-img convert -f raw -c -O qcow2 raw.img $appliance-$branch-kvm.qcow2 +qemu-img convert -f raw -c -O qcow2 raw.img ${appliance_build_name}-kvm.qcow2 rm raw.img -bzip2 $appliance-$branch-kvm.qcow2 -echo "$appliance exported for KVM: dist/$appliance-$branch-kvm.qcow2.bz2" +bzip2 ${appliance_build_name}-kvm.qcow2 +echo "${appliance_build_name} exported for KVM: dist/${appliance_build_name}-kvm.qcow2.bz2" # Export both ova and vmdk for VMWare -vboxmanage clonehd $hdd_uuid $appliance-$branch-vmware.vmdk --format VMDK -bzip2 $appliance-$branch-vmware.vmdk -echo "$appliance exported for VMWare: dist/$appliance-$branch-vmware.vmdk.bz2" -vboxmanage export $machine_uuid --output $appliance-$branch-vmware.ovf -mv $appliance-$branch-vmware.ovf $appliance-$branch-vmware.ovf-orig -java -cp convert Convert convert_ovf_vbox_to_esx.xslt $appliance-$branch-vmware.ovf-orig $appliance-$branch-vmware.ovf -tar -cf $appliance-$branch-vmware.ova $appliance-$branch-vmware.ovf $appliance-$branch-vmware-disk[0-9].vmdk -rm -f $appliance-$branch-vmware.ovf $appliance-$branch-vmware.ovf-orig $appliance-$branch-vmware-disk[0-9].vmdk -echo "$appliance exported for VMWare: dist/$appliance-$branch-vmware.ova" +vboxmanage clonehd $hdd_uuid ${appliance_build_name}-vmware.vmdk --format VMDK +bzip2 ${appliance_build_name}-vmware.vmdk +echo "${appliance_build_name} exported for VMWare: dist/${appliance_build_name}-vmware.vmdk.bz2" +vboxmanage export $machine_uuid --output ${appliance_build_name}-vmware.ovf +mv ${appliance_build_name}-vmware.ovf ${appliance_build_name}-vmware.ovf-orig +java -cp convert Convert convert_ovf_vbox_to_esx.xslt ${appliance_build_name}-vmware.ovf-orig ${appliance_build_name}-vmware.ovf +tar -cf ${appliance_build_name}-vmware.ova ${appliance_build_name}-vmware.ovf ${appliance_build_name}-vmware-disk[0-9].vmdk +rm -f ${appliance_build_name}-vmware.ovf ${appliance_build_name}-vmware.ovf-orig ${appliance_build_name}-vmware-disk[0-9].vmdk +echo "${appliance_build_name} exported for VMWare: dist/${appliance_build_name}-vmware.ova" # Export for HyperV -vboxmanage clonehd $hdd_uuid $appliance-$branch-hyperv.vhd --format VHD +vboxmanage clonehd $hdd_uuid ${appliance_build_name}-hyperv.vhd --format VHD # HyperV doesn't support import a zipped image from S3, but we create a zipped version to save space on the jenkins box -zip $appliance-$branch-hyperv.vhd.zip $appliance-$branch-hyperv.vhd -echo "$appliance exported for HyperV: dist/$appliance-$branch-hyperv.vhd" +zip ${appliance_build_name}-hyperv.vhd.zip ${appliance_build_name}-hyperv.vhd +echo "${appliance_build_name} exported for HyperV: dist/${appliance_build_name}-hyperv.vhd" mv *-hyperv.vhd *-hyperv.vhd.zip *.bz2 *.ova dist/ +rm -rf "definitions/${appliance_build_name}"