change the date
[tools/build.git] / build-vm-ec2
1 #
2 # EC2 specific functions
3 #
4 ################################################################
5 #
6 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License version 2 or 3 as
10 # published by the Free Software Foundation.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program (see the file COPYING); if not, write to the
19 # Free Software Foundation, Inc.,
20 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 #
22 ################################################################
23
24 BUILD_EC2_TYPE="t1.micro"
25
26 cloud_volume_attach_ec2() {
27     local VM_SERVER="$1"
28     local VM_VOL_NAME="$2"
29     local VM_VOL_DEV="$3"
30
31     temp_file=`mktemp`
32     if ! ec2-attach-volume "$VM_VOL_NAME" -d /dev/sdz -i `ec2-instance-id` --region "$BUILD_EC2_REGION" > "$temp_file"; then
33         rm -f "$temp_file"
34         cleanup_and_exit 1
35     fi
36     # wait that it becomes available
37     while true; do
38         state=`ec2_volume_state "$VM_VOL_NAME"`
39         test "$state" = attached && break
40         sleep 1
41     done
42     # print device node
43     grep ^ATTACHMENT "$temp_file" | awk '{ print $4 }'
44     rm -f "$temp_file"
45 }
46
47 cloud_volume_detach_ec2() {
48     local VM_SERVER="$1"
49     local VM_VOL_NAME="$2"
50     state=`ec2_volume_state "$VM_VOL_NAME"`
51     if test "$state" != available ; then
52         ec2-detach-volume "$VM_VOL_NAME" --region "$BUILD_EC2_REGION" || return 3
53     fi
54     return 0
55 }
56
57 vm_verify_options_ec2() {
58     # verify settings
59     if test -z "$AWS_ACCESS_KEY" -o -z "$AWS_ACCESS_KEY" ; then
60         echo "ERROR: No amazon EC2 environment set. Set AWS_ACCESS_KEY and AWS_SECRET_KEY."
61         cleanup_and_exit 3
62     fi
63     . /etc/profile.d/ec2.sh
64     EC2_INSTANCE_ID=`ec2-instance-id`
65     BUILD_EC2_AKI=
66     BUILD_EC2_ZONE=`ec2-meta-data placement/availability-zone`
67     BUILD_EC2_REGION=${BUILD_EC2_ZONE%?}
68     case "$BUILD_EC2_ZONE" in
69         us-east-1)      BUILD_EC2_AKI=aki-88aa75e1 ;;
70         us-west-1)      BUILD_EC2_AKI=aki-f77e26b2 ;;
71         us-west-2)      BUILD_EC2_AKI=aki-fc37bacc ;;
72         eu-west-1)      BUILD_EC2_AKI=aki-71665e05 ;;
73         ap-southeast-1) BUILD_EC2_AKI=aki-fe1354ac ;;
74         ap-southeast-2) BUILD_EC2_AKI=aki-3f990e05 ;;
75         ap-northeast-1) BUILD_EC2_AKI=aki-44992845 ;;
76         sa-east-1)      BUILD_EC2_AKI=aki-c48f51d9 ;;
77         us-gov-west-1)  BUILD_EC2_AKI=aki-79a4c05a ;;
78     esac
79     if test -z "$BUILD_EC2_AKI" ; then
80         echo "Unknown Amazon EC2 Zone: $BUILD_EC2_ZONE"
81         cleanup_and_exit 1
82     fi
83     if test -z "$BUILD_EC2_AKI" ; then
84         echo "ERROR: No image refering to kernel and ramdisk is defined in BUILD_EC2_AKI env."
85         cleanup_and_exit 3
86     fi
87     if test -z "$VM_VOLUME_NAME" ; then
88         echo "ERROR: No worker root VM volume name specified."
89         cleanup_and_exit 3
90     fi
91     if test -z "$VM_VOLUME_SWAP" ; then
92         echo "ERROR: No worker swap VM volume name specified."
93         cleanup_and_exit 3
94     fi
95
96     VM_SWAPDEV=/dev/sdb1        # in the vm
97 }
98
99 vm_attach_root_ec2() {
100     VM_IMAGE=`cloud_volume_attach_ec2 "$VM_SERVER" "$VM_VOLUME_NAME" "$VM_IMAGE"`
101     test "${VM_IMAGE:0:5}" = /dev/ || cleanup_and_exit 3
102 }
103
104 vm_attach_swap_ec2() {
105     VM_SWAP=`cloud_volume_attach_ec2 "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap" "$VM_SWAP"`
106     test "${VM_SWAP:0:5}" = /dev/ || cleanup_and_exit 3
107 }
108
109 vm_detach_root_ec2() {
110     cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_NAME"
111 }
112
113 vm_detach_swap_ec2() {
114     cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_SWAP"
115 }
116
117 vm_fixup_ec2() {
118     # No way to handle this via init= parameter here....
119     echo "#!/bin/sh"               >  "$BUILD_ROOT/sbin/init"
120     echo 'exec /.build/build "$@"' >> "$BUILD_ROOT/sbin/init"
121     chmod 0755 "$BUILD_ROOT/sbin/init"
122     # use the instance kernel, if no kernel got installed via preinstall
123     if ! test -e "$BUILD_ROOT/boot/vmlinuz"; then
124         cp /boot/vmlinuz-ec2 "$BUILD_ROOT/boot/vmlinuz"
125         cp /boot/initrd-ec2 "$BUILD_ROOT/boot/initrd"
126     fi
127     # install menu.lst for pv grub
128     if ! test -e "$BUILD_ROOT/boot/grub/menu.lst"; then
129         mkdir -p "$BUILD_ROOT/boot/grub"
130         echo "serial --unit=0 --speed=9600"                                                   >  "$BUILD_ROOT/boot/grub/menu.lst"
131         echo "terminal --dumb serial"                                                         >> "$BUILD_ROOT/boot/grub/menu.lst"
132         echo "default 0"                                                                      >> "$BUILD_ROOT/boot/grub/menu.lst"
133         echo "timeout 0"                                                                      >> "$BUILD_ROOT/boot/grub/menu.lst"
134         echo "hiddenmenu"                                                                     >> "$BUILD_ROOT/boot/grub/menu.lst"
135         echo ""                                                                               >> "$BUILD_ROOT/boot/grub/menu.lst"
136         echo "title default"                                                                  >> "$BUILD_ROOT/boot/grub/menu.lst"
137         echo "   root (hd0)"                                                                  >> "$BUILD_ROOT/boot/grub/menu.lst"
138         echo "   kernel /boot/vmlinuz root=/dev/sda1 xencons=xvc0 console=xvc0 splash=silent" >> "$BUILD_ROOT/boot/grub/menu.lst"
139         echo "   initrd /boot/initrd"                                                         >> "$BUILD_ROOT/boot/grub/menu.lst"
140     fi
141 }
142
143 vm_cleanup_ec2() {
144     cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_NAME"
145     cloud_volume_detach_ec2 "$VM_SERVER" "$VM_VOLUME_SWAP"
146     test -n "$EC2_EXTRACT_VOLUME_root" && cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_EXTRACT_VOLUME_root"
147     test -n "$EC2_EXTRACT_VOLUME_swap" && cloud_volume_detach_ec2 "$VM_SERVER" "$EC2_EXTRACT_VOLUME_swap"
148     test -n "$EC2_SNAP_root" && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
149     test -n "$EC2_SNAP_swap" && ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
150     test -n "$EC2_EXTRACT_VOLUME_root" && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_root"
151     test -n "$EC2_EXTRACT_VOLUME_swap" && ec2-delete-volume --region "$BUILD_EC2_REGION" "$EC2_EXTRACT_VOLUME_swap"
152 }
153
154 vm_kill_ec2() {
155     if ec2-describe-instance-status "$VM_BUILD_INSTANCE" --region "$BUILD_EC2_REGION" >/dev/null 2>&1 ; then
156         if ec2-terminate-instances "$VM_BUILD_INSTANCE" >/dev/null 2>&1 ; then
157             echo "could not kill EC2 instance $VM_BUILD_INSTANCE"
158             cleanup_and_exit 1
159         fi
160     fi
161 }
162
163 vm_startup_ec2() {
164     EC2_SNAP_root=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_NAME" | awk '{ print $2 }'`
165     if test "$EC2_SNAP_root" = "${EC2_SNAP_root#snap-}" ; then
166         echo "ERROR: Failed to create snapshot for root disk $VM_VOLUME_NAME"
167         cleanup_and_exit 3
168     fi
169     EC2_SNAP_swap=`ec2-create-snapshot --region "$BUILD_EC2_REGION" "$VM_VOLUME_SWAP" | awk '{ print $2 }'`
170     if test "$EC2_SNAP_swap" = "${EC2_SNAP_swap#snap-}" ; then
171         echo "ERROR: Failed to create snapshot for swap disk $VM_VOLUME_SWAP"
172         ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
173         cleanup_and_exit 3
174     fi
175     # wait for snapshots being processed
176     while true; do
177         c=`ec2-describe-snapshots --region "$BUILD_EC2_REGION" "$EC2_SNAP_root" "$EC2_SNAP_swap" | grep completed | wc -l`
178         test "$c" = 2 && break
179     done
180     EC2_AMI=`ec2-register --region "$BUILD_EC2_REGION" -n build-$VM_VOLUME_NAME  -a x86_64 -b "/dev/sda1=$EC2_SNAP_root::false" -b "/dev/sdb1=$EC2_SNAP_swap::false" --kernel "$BUILD_EC2_AKI" | awk '{ print $2 }'`
181     if test "$EC2_AMI" == "${EC2_AMI#ami-}" ; then
182         echo "ERROR: Failed to register the AMI"
183         ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
184         ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
185         cleanup_and_exit 3
186     fi
187     INSTANCE=`ec2-run-instances --region "$BUILD_EC2_REGION" -z "$BUILD_EC2_ZONE" -t $BUILD_EC2_TYPE --kernel "$BUILD_EC2_AKI" --instance-initiated-shutdown-behavior terminate "$EC2_AMI" | grep ^INSTANCE | awk '{ print $2 }'`
188     if test "$INSTANCE" == "${INSTANCE#i-}" ; then
189         echo "ERROR: Failed to run the instance for AMI $EC2_AMI"
190         ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI"
191         ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_root"
192         ec2-delete-snapshot --region "$BUILD_EC2_REGION" "$EC2_SNAP_swap"
193         cleanup_and_exit 3
194     fi
195     echo "Waiting for finishing the build. No log file until then on EC2 ...."
196     I=0
197     L=0
198     EC2_EXTRACT_VOLUME_root=
199     EC2_EXTRACT_VOLUME_swap=
200     temp_file=`mktemp`
201     while true; do
202         ec2-describe-instances --region "$BUILD_EC2_REGION" "$INSTANCE" > $temp_file
203         state=`grep ^INSTANCE "$temp_file"`
204         if test -z "$EC2_EXTRACT_VOLUME_root" ; then
205             EC2_EXTRACT_VOLUME_root=`grep ^BLOCKDEVICE $temp_file | grep /dev/sda1 | awk '{ print $3 }'`
206             EC2_EXTRACT_VOLUME_swap=`grep ^BLOCKDEVICE $temp_file | grep /dev/sdb1 | awk '{ print $3 }'`
207         fi
208         # the column of the state is at a differen position depending on the state :/
209 #       test "$state" = "${state/stopped/}" || break
210         test "$state" = "${state/terminated/}" || break
211         I=$(( $I + 1 ))
212         if test $I -gt 10 ; then
213            echo -n .
214            I=0
215            L=$(( $L + 1 ))
216         fi
217         if test $L -gt 10 ; then
218            # dump entire console log as raw here
219            ec2-get-console-output --region "$BUILD_EC2_REGION" -r "$INSTANCE"
220            L=0
221         fi
222         sleep 1
223     done
224     rm -f "$temp_file"
225     echo
226     ec2-deregister --region "$BUILD_EC2_REGION" "$EC2_AMI"
227     # snapshots get deleted after extract
228 }