-
Notifications
You must be signed in to change notification settings - Fork 73
/
relaunch
110 lines (88 loc) · 4.04 KB
/
relaunch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/bin/bash
PATH=/usr/local/bin/:$PATH
if [ "$1" = "" ]; then echo "USER ERROR: please specify a configuration file"; exit -1; fi
DIR=$(readlink -m $(dirname $0))
PATH=.:$PATH . $1 || exit -1
if [ "$ec2spotter_image_name" = "" ]
then
echo "image name not specified";
exit -1;
fi
SELF=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
IMAGE_ID=$(aws ec2 describe-images --filters Name=tag-key,Values="Name" Name=tag-value,Values=$ec2spotter_image_name --owners self \
|jq -r '.Images[0].ImageId')
if [ "$ec2spotter_reuse_images" != 1 ] && [ $IMAGE_ID != "null" ] && [ $IMAGE_ID != "" ]
then
aws ec2 deregister-image --image-id $IMAGE_ID
fi
if [ "$ec2spotter_reuse_images" != 1 ]
then
echo "Creating AMI image."
sync
IMAGE_ID=$(aws ec2 create-image --instance-id $SELF --no-reboot --name $ec2spotter_image_name | jq -r '.ImageId')
while [ ! $(aws ec2 describe-images --image-ids $IMAGE_ID | jq -r '.Images[0].State') = "available" ]
do
sleep 5
echo "Waiting for image $IMAGE_ID"
done
SNAPSHOT_ID=$(aws ec2 describe-images --image-id $IMAGE_ID |jq -r '.Images[0].BlockDeviceMappings[0].Ebs.SnapshotId')
aws ec2 create-tags --resources $IMAGE_ID $SNAPSHOT_ID --tags Key=Name,Value=$ec2spotter_image_name
else
echo "Re-using image with id=$IMAGE_ID"
fi
REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')
PUB_KEY=$(wget -q -O - http://169.254.169.254/latest/meta-data/public-keys | awk -F= '{print $2}')
HOSTNAME=$(hostname)
# Setup the script that runs in the spot instance. It is responsible for cleaning up the temporary objects created during launch.
cat >user-data.tmp <<EOF
#!/bin/sh
my_id=\$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
my_root_vol_id=\$(aws ec2 describe-instances --instance-id \$my_id | jq -r '.Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId')
aws ec2 create-tags --resources \$my_id \$my_root_vol_id --tags Key=Name,Value="${ec2spotter_image_name}-spot"
echo '@reboot $DIR/self-spot' > /tmp/crontab
crontab -l >> /tmp/crontab
crontab < /tmp/crontab
echo $SELF > /etc/ec2spotter
echo $HOSTNAME > /etc/hostname
echo "echo Launching new spot instance: \$my_id $ec2spotter_elastic_ip, spotted by: $SELF $ec2spotter_control_ip; aws ec2 associate-address --instance-id \$my_id --allocation-id $ec2spotter_elastic_ip --allow-reassociation; aws ec2 associate-address --instance-id $SELF --allocation-id $ec2spotter_control_ip --allow-reassociation" | at now + 5 minutes
shutdown -r now
EOF
userData=$(base64 user-data.tmp | tr -d '\n');
sortedPrices=$(aws ec2 describe-spot-price-history --product-descriptions Linux/UNIX --instance-types $ec2spotter_instance_type --max-items 25 | jq -r '.SpotPriceHistory | sort_by(.SpotPrice)')
medianPrice=$(echo $sortedPrices| jq -r '.[18].SpotPrice')
cheapZone=$(echo $sortedPrices | jq -r '.[0].AvailabilityZone')
echo "Selected medianPrice=$medianPrice in zone $cheapZone" >&2
echo "Absolute lowest price was " $(echo $sortedPrices| jq -r '.[0].SpotPrice') >&2
echo "Absolute highest price was " $(echo $sortedPrices| jq -r '.[24].SpotPrice') >&2
cat >specs.tmp <<EOF
{
"KeyName" : "$PUB_KEY",
"InstanceType": "$ec2spotter_instance_type",
"ImageId" : "$IMAGE_ID",
"UserData" : "${userData}",
"Placement": {
"AvailabilityZone": "$cheapZone"
},
"BlockDeviceMappings": [
{
"DeviceName" : "/dev/sda1",
"Ebs": {
"VolumeSize": $ec2spotter_volume_size,
"DeleteOnTermination": true,
"VolumeType" : "gp2"
}
}
]
}
EOF
targetPrice=$medianPrice
#if [ $targetPrice -gt $ec2spotter_bid_price ]
#then
# targetPrice=$ec2spotter_bid_price
# echo "targetPrice capped at $ec2spotter_bid_price" >&2
#fi
SPOT_JSON=$(aws ec2 request-spot-instances --spot-price $targetPrice --type one-time --launch-specification file://specs.tmp --region ${REGION})
SPOT_ID=$(echo $SPOT_JSON | jq -r '.SpotInstanceRequests[0].SpotInstanceRequestId')
echo SPOT_ID=$SPOT_ID
aws ec2 create-tags --resources ${SPOT_ID} --tags Key=Name,Value=${ec2spotter_image_name} --region ${REGION}
echo $SPOT_JSON > spot.tmp