-
Notifications
You must be signed in to change notification settings - Fork 3
/
restore_instance.py
129 lines (102 loc) · 3.81 KB
/
restore_instance.py
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import time
import logging
import boto.ec2
import boto.exception
from .config import (
INSTANCE_TYPE, DATA_VOLUME_SIZE, DATA_VOLUME_RATE, DATA_VOLUME_TYPE,
AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_AMI_IMAGE_ID,
AWS_KEY_NAME, AWS_SECURITY_GROUPS, AWS_SBNET_ID
)
logger = logging.getLogger('maas')
USER_SCRIPT_TEMPLATE = """#!/bin/bash -ex
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
## setup the ebs volume for data.
avail_blk=`lsblk -n -oNAME,MOUNTPOINT | grep -v '/$' | grep -v 'xvda' | awk -F' ' '{{print $1}}'`
if [ -z "$avail_blk" ]; then
echo "Don't have a mounted data blk device."
exit -1
fi
update_needed=`file -s /dev/$avail_blk | awk -F':' '{{print $2}}'`
setup_fs=`echo "$update_needed" | egrep -e '^[[:space:]]+data$' |wc -l`
if [ $setup_fs -eq 1 ]; then
echo "Setting up a file system for /dev/$avail_blk"
mkfs -t ext4 /dev/$avail_blk
fi
cp /etc/fstab /etc/fstab.orig
echo "/dev/$avail_blk /mnt/data ext4 defaults,nofail,nobootwait 0 2" >> /etc/fstab
mount -a
echo "{some_variable_to_pass}" >> /dev/null
judo service supervisor start
supervisorctl start all
"""
def create_bdm(size, type, rate, non_root_snap_id):
""" Create a pair of block-devices to attach to the instance.
"""
retry = 0
while (retry < 3):
try:
bd_root = boto.ec2.blockdevicemapping.BlockDeviceType()
bd_nonroot = boto.ec2.blockdevicemapping.BlockDeviceType()
size = int(size[:-1])
bd_nonroot.size = size
bd_nonroot.volume_type = type
if type == 'io1':
bd_nonroot.iops = rate
bd_nonroot.delete_on_termination = False
if non_root_snap_id:
bd_nonroot.snapshot_id = non_root_snap_id
bdmapping = boto.ec2.blockdevicemapping.BlockDeviceMapping()
bdmapping['/dev/sda1'] = bd_root
bdmapping['/dev/xvdf'] = bd_nonroot
return bdmapping
except (boto.exception.EC2ResponseError, AssertionError) as e:
retry += 1
logger.exception(e)
logger.error(e)
def try_to_create_ec2_instance():
try:
conn = boto.ec2.connect_to_region(
AWS_REGION,
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY
)
instance_type = INSTANCE_TYPE
data_volume_size = DATA_VOLUME_SIZE
data_volume_rate = DATA_VOLUME_RATE
data_volume_type = DATA_VOLUME_TYPE
bdm = create_bdm(data_volume_size, data_volume_type,
data_volume_rate)
some_variable_to_pass = "here is some data that you want to pass to server"
cmd = USER_SCRIPT_TEMPLATE.format(
some_variable_to_pass=some_variable_to_pass,
)
logger.debug(cmd)
user_data = cmd
reservation = conn.run_instances(
AWS_AMI_IMAGE_ID,
instance_type=instance_type,
key_name=AWS_KEY_NAME,
security_group_ids=AWS_SECURITY_GROUPS,
subnet_id=AWS_SBNET_ID,
block_device_map=bdm,
user_data=user_data,
)
instance = reservation.instances[0]
while instance.update() != "running":
time.sleep(5)
instance.update()
# Check that instances got an IP and proper name
assert instance.ip_address is not None
assert instance.update() == "running"
return instance
except (boto.exception.EC2ResponseError, AssertionError) as e:
logger.exception(e)
logger.error(e)
return None
def create_ec2_instance(max_retry=5):
retry = 0
while(retry < max_retry):
instance = try_to_create_ec2_instance()
if instance:
return instance
raise Exception("Can't create an instance")