-
Notifications
You must be signed in to change notification settings - Fork 0
/
create_instance.py
103 lines (93 loc) · 3.63 KB
/
create_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
#!/usr/bin/env python
__author__ = "Lutz Künneke"
__copyright__ = ""
__credits__ = []
__license__ = ""
__version__ = "0.1"
__maintainer__ = "Lutz Künneke"
__email__ = "[email protected]"
__status__ = "Prototype"
"""
Simple wrapper for the boto3 API which makes it easier if
you need just one worker instance which has to carry out
a specific task and then should be terminated after retrieving
the result files
Author: Lutz Kuenneke, 12.07.2018
"""
import os
import time
from configparser import ConfigParser
import boto3
class Controller(object):
def __init__(self, config_name):
conf = ConfigParser()
conf.read(config_name)
self.image_id = conf.get('AWS', 'image_id')
self.type = conf.get('AWS', 'type')
self.ec2 = boto3.resource('ec2')
self.instance = None
self.maxprice = conf.get('AWS', 'max_price')
self.keyname = conf.get('AWS', 'keyname')
self.pemfile = conf.get('AWS', 'pemfile')
self.security_group = conf.get('AWS', 'security_group')
def createInstance(self):
marketOptions = {'MarketType': 'spot', 'SpotOptions': {'MaxPrice': self.maxprice}}
if self.instance:
return self.instance
else:
instArr = self.ec2.create_instances(
ImageId=self.image_id,
MinCount=1,
MaxCount=1,
InstanceType=self.type,
KeyName=self.keyname,
InstanceMarketOptions=marketOptions,
SecurityGroups=[self.security_group])
self.instance = instArr[0]
print(self.instance.id)
# self.waitUntilRunning()
return self.instance
def terminateInstance(self):
if not self.instance:
prent('No running instance')
else:
response = self.instance.terminate()
print(response)
def waitUntilRunning(self):
time.sleep(10)
client = boto3.client('ec2')
while True:
response = client.describe_instances(InstanceIds=[self.instance.instance_id])
state = response['Reservations'][0]['Instances'][0]['State']['Code']
if state == 16:
return
else:
print('Instance ' + str(instance.id) + ', state: ' + str(state))
time.sleep(10)
def transferFilesToWorker(self, filesList):
if not self.instance:
print('Instantiate a worker first')
return
client = boto3.client('ec2')
response = client.describe_instances(InstanceIds=[self.instance.instance_id])
self.public_dns = response['Reservations'][0]['Instances'][0]['NetworkInterfaces'][0]['Association'][
'PublicDnsName'] # this is weird, but this is how it is
for _file in filesList:
scpstr = 'scp -o StrictHostKeyChecking=no -i ' + self.pemfile + ' ' + _file + ' ubuntu@' + self.public_dns + ':~/'
print(scpstr)
os.system(scpstr)
def execOnRemote(self, scriptName):
if not self.public_dns:
print('unable to execute: NO remote public dns')
sshString = 'ssh -o StrictHostKeyChecking=no -i ' + self.pemfile + ' ubuntu@' + str(
self.public_dns) + " 'bash -s' < " + scriptName
print(sshString)
os.system(sshString)
def retrieveResults(self, resultsNames):
if not self.instance:
print('Instantiate a worker first')
return
for _file in resultsNames:
scpstr = 'scp -i ' + self.pemfile + ' ubuntu@' + self.public_dns + ':' + _file + ' .'
print(scpstr)
os.system(scpstr)