Hello World

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
}