File build-vm-ec2 of Package build
#
# EC2 specific functions
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
EC2_BUILD_TYPE="t1.micro"
EC2_INSTANCE_ID=
EC2_VOLUME_ROOT=
EC2_VOLUME_SWAP=
cloud_volume_attach_ec2() {
local VM_SERVER="$1"
local VM_VOL_NAME="$2"
temp_file=`mktemp`
if ! ec2-attach-volume "$VM_VOL_NAME" -d /dev/sdz -i `ec2-instance-id` --region "$BUILD_EC2_REGION" > "$temp_file"; then
rm -f "$temp_file"
cleanup_and_exit 1
fi
# wait that it becomes available
while true; do
state=`ec2_volume_state "$VM_VOL_NAME"`
test "$state" = attached && break
sleep 1
done
# print device node
grep ^ATTACHMENT "$temp_file" | awk '{ print $4 }'
rm -f "$temp_file"
}
cloud_volume_detach_ec2() {
local VM_SERVER="$1"
local VM_VOL_NAME="$2"
state=`ec2_volume_state "$VM_VOL_NAME"`
if test "$state" != available ; then
ec2-detach-volume "$VM_VOL_NAME" --region "$BUILD_EC2_REGION" || return 3
fi
return 0
}
vm_wipe_ec2() {
# not yet implemented
:
}
vm_verify_options_ec2() {
EC2_VOLUME_ROOT="$VM_ROOT"
EC2_VOLUME_SWAP="$VM_SWAP"
VM_ROOT_TYPE=unattached
VM_SWAP_TYPE=unattached
if test -n "$KILL" -o -n "$DO_WIPE" ; then
return
fi
# verify settings
if test -z "$AWS_ACCESS_KEY" -o -z "$AWS_ACCESS_KEY" ; then
cleanup_and_exit 3 "ERROR: No amazon EC2 environment set. Set AWS_ACCESS_KEY and AWS_SECRET_KEY."
fi
. /etc/profile.d/ec2.sh
EC2_INSTANCE_ID=`ec2-instance-id`
BUILD_EC2_AKI=
BUILD_EC2_ZONE=`ec2-meta-data placement/availability-zone`
BUILD_EC2_REGION=${BUILD_EC2_ZONE%?}
case "$BUILD_EC2_ZONE" in
us-east-1) BUILD_EC2_AKI=aki-88aa75e1 ;;
us-west-1) BUILD_EC2_AKI=aki-f77e26b2 ;;
us-west-2) BUILD_EC2_AKI=aki-fc37bacc ;;
eu-west-1) BUILD_EC2_AKI=aki-71665e05 ;;
ap-southeast-1) BUILD_EC2_AKI=aki-fe1354ac ;;
ap-southeast-2) BUILD_EC2_AKI=aki-3f990e05 ;;
ap-northeast-1) BUILD_EC2_AKI=aki-44992845 ;;
sa-east-1) BUILD_EC2_AKI=aki-c48f51d9 ;;
us-gov-west-1) BUILD_EC2_AKI=aki-79a4c05a ;;
esac
if test -z "$BUILD_EC2_AKI" ; then
cleanup_and_exit 1 "Unknown Amazon EC2 Zone: $BUILD_EC2_ZONE"
fi
if test -z "$BUILD_EC2_AKI" ; then
cleanup_and_exit 3 "ERROR: No image refering to kernel and ramdisk is defined in BUILD_EC2_AKI env."
fi
if test -z "$VM_ROOT" ; then
cleanup_and_exit 3 "ERROR: No worker root VM volume name specified."
fi
if test -z "$VM_SWAP" ; then
cleanup_and_exit 3 "ERROR: No worker swap VM volume name specified."
fi
VM_SWAPDEV=/dev/sdb1 # in the vm
}
vm_attach_root_ec2() {
VM_ROOT=`cloud_volume_attach_ec2 "$VM_SERVER" "$EC2_VOLUME_ROOT"
test "${VM_ROOT:0:5}" = /dev/ || cleanup_and_exit 3
VM_ROOT_TYPE=device
}
vm_attach_swap_ec2() {
VM_SWAP=`cloud_volume_attach_ec2 "$VM_SERVER" "$EC2_VOLUME_SWAP"
test "${VM_SWAP:0:5}" = /dev/ || cleanup_and_exit 3
VM_SWAP_TYPE=device
}
vm_detach_root_ec2() {
test "$VM_ROOT_TYPE" = device && cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_VOLUME_ROOT"
VM_ROOT_TYPE=unattached
}
vm_detach_swap_ec2() {
test "$VM_SWAP_TYPE" = device && cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_VOLUME_SWAP"
VM_SWAP_TYPE=unattached
}
vm_fixup_ec2() {
# No way to handle this via init= parameter here....
buildroot_rm /sbin/init
echo "#!/bin/sh" > "$BUILD_ROOT/sbin/init"
echo 'exec /.build/build "$@"' >> "$BUILD_ROOT/sbin/init"
chmod 0755 "$BUILD_ROOT/sbin/init"
# use the instance kernel if no kernel got installed via preinstall
assert_dirs boot
if ! test -e "$BUILD_ROOT/boot/vmlinuz"; then
rm -f "$BUILD_ROOT/boot/vmlinuz" "$BUILD_ROOT/boot/initrd"
cp /boot/vmlinuz-ec2 "$BUILD_ROOT/boot/vmlinuz"
cp /boot/initrd-ec2 "$BUILD_ROOT/boot/initrd"
fi
# install menu.lst for pv grub
if ! test -e "$BUILD_ROOT/boot/grub/menu.lst"; then
assert_dirs boot/grub
mkdir -p "$BUILD_ROOT/boot/grub"
buildroot_rm /boot/grub/menu.lst
echo "serial --unit=0 --speed=9600" > "$BUILD_ROOT/boot/grub/menu.lst"
echo "terminal --dumb serial" >> "$BUILD_ROOT/boot/grub/menu.lst"
echo "default 0" >> "$BUILD_ROOT/boot/grub/menu.lst"
echo "timeout 0" >> "$BUILD_ROOT/boot/grub/menu.lst"
echo "hiddenmenu" >> "$BUILD_ROOT/boot/grub/menu.lst"
echo "" >> "$BUILD_ROOT/boot/grub/menu.lst"
echo "title default" >> "$BUILD_ROOT/boot/grub/menu.lst"
echo " root (hd0)" >> "$BUILD_ROOT/boot/grub/menu.lst"
echo " kernel /boot/vmlinuz root=/dev/sda1 xencons=xvc0 console=xvc0 splash=silent $vm_linux_kernel_parameter" >> "$BUILD_ROOT/boot/grub/menu.lst"
echo " initrd /boot/initrd" >> "$BUILD_ROOT/boot/grub/menu.lst"
fi
}
vm_cleanup_ec2() {
cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_VOLUME_ROOT"
cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_VOLUME_SWAP"
test -n "$EC2_SNAP_root" && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
test -n "$EC2_SNAP_swap" && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
test -n "$EC2_EXTRACT_VOLUME_root" && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_root"
test -n "$EC2_EXTRACT_VOLUME_swap" && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_swap"
}
vm_sysrq_ec2() {
:
}
vm_kill_ec2() {
if ec2-describe-instance-status "$VM_BUILD_INSTANCE" --region "$BUILD_EC2_REGION" >/dev/null 2>&1 ; then
if ec2-terminate-instances "$VM_BUILD_INSTANCE" >/dev/null 2>&1 ; then
cleanup_and_exit 1 "could not kill EC2 instance $VM_BUILD_INSTANCE"
fi
fi
}
vm_startup_ec2() {
EC2_SNAP_root=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$EC2_VOLUME_ROOT" | awk '{ print $2 }'`
if test "$EC2_SNAP_root" = "${EC2_SNAP_root#snap-}" ; then
cleanup_and_exit 3 "ERROR: Failed to create snapshot for root disk $EC2_VOLUME_ROOT"
fi
EC2_SNAP_swap=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$EC2_VOLUME_SWAP" | awk '{ print $2 }'`
if test "$EC2_SNAP_swap" = "${EC2_SNAP_swap#snap-}" ; then
echo "ERROR: Failed to create snapshot for swap disk $EC2_VOLUME_SWAP"
ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
cleanup_and_exit 3
fi
# wait for snapshots being processed
while true; do
c=`ec2-describe-snapshots --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" "$EC2_SNAP_swap" | grep completed | wc -l`
test "$c" = 2 && break
done
EC2_AMI=`ec2-register --region "$BUILD_EC2_REGION" -n build-$EC2_VOLUME_ROOT -a x86_64 -b "/dev/sda1=$EC2_SNAP_root::false" -b "/dev/sdb1=$EC2_SNAP_swap::false" --kernel "$BUILD_EC2_AKI" | awk '{ print $2 }'`
if test "$EC2_AMI" == "${EC2_AMI#ami-}" ; then
echo "ERROR: Failed to register the AMI"
ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
cleanup_and_exit 3
fi
INSTANCE=`ec2-run-instances --region "$BUILD_EC2_REGION" -z "$BUILD_EC2_ZONE" -t $EC2_BUILD_TYPE --kernel "$BUILD_EC2_AKI" --instance-initiated-shutdown-behavior terminate "$EC2_AMI" | grep ^INSTANCE | awk '{ print $2 }'`
if test "$INSTANCE" == "${INSTANCE#i-}" ; then
echo "ERROR: Failed to run the instance for AMI $EC2_AMI"
ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI"
ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
cleanup_and_exit 3
fi
echo "Waiting for finishing the build. No log file until then on EC2 ...."
I=0
L=0
EC2_EXTRACT_VOLUME_root=
EC2_EXTRACT_VOLUME_swap=
temp_file=`mktemp`
while true; do
ec2-describe-instances --region "$BUILD_EC2_REGION" "$INSTANCE" > $temp_file
state=`grep ^INSTANCE "$temp_file"`
if test -z "$EC2_EXTRACT_VOLUME_root" ; then
EC2_EXTRACT_VOLUME_root=`grep ^BLOCKDEVICE $temp_file | grep /dev/sda1 | awk '{ print $3 }'`
EC2_EXTRACT_VOLUME_swap=`grep ^BLOCKDEVICE $temp_file | grep /dev/sdb1 | awk '{ print $3 }'`
fi
# the column of the state is at a differen position depending on the state :/
# test "$state" = "${state/stopped/}" || break
test "$state" = "${state/terminated/}" || break
I=$(( $I + 1 ))
if test $I -gt 10 ; then
echo -n .
I=0
L=$(( $L + 1 ))
fi
if test $L -gt 10 ; then
# dump entire console log as raw here
ec2-get-console-output --region "$BUILD_EC2_REGION" -r "$INSTANCE"
L=0
fi
sleep 1
done
rm -f "$temp_file"
echo
ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI"
# switch to extract volumnes
EC2_VOLUME_ROOT=$EC2_EXTRACT_VOLUME_root
EC2_VOLUME_SWAP=$EC2_EXTRACT_VOLUME_swap
# snapshots get deleted after extract
}