-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAzureSimulation.py
More file actions
269 lines (228 loc) · 9.56 KB
/
AzureSimulation.py
File metadata and controls
269 lines (228 loc) · 9.56 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
from settings_local import STORAGE_ACCOUNT_NAME, STORAGE_ACCOUNT_KEY, SUBSCRIPTION_ID, VM_PASSWORD, VM_USERNAME
__author__ = 'Natalie'
import hashlib
import os
import pickle
from re import search
from time import time, sleep
from sys import stderr
from azure import *
from azure.servicemanagement import *
from azure.storage import BlobService
import AzureTools
from AzureTools import comp_user
# Create service management object
subscription_id = SUBSCRIPTION_ID
certificate_path = 'CURRENT_USER\\my\\AzureCertificate'
sms = ServiceManagementService(subscription_id, certificate_path)
# Create blob service object
blob_service = BlobService(
account_name=STORAGE_ACCOUNT_NAME,
account_key=STORAGE_ACCOUNT_KEY)
class AzureSimulation:
def __init__(self):
self.name = ""
self.vm_id = ""
self.input = ""
self.cores = 1
self.tstamp = ""
def upload_input(self, user_info):
"""
Calls to zip the provided input files then uploads them to the user's storage container.
:param user_info:
:return:
"""
# Convert to Windows format
norm_inputs = (os.path.normpath(self.input))
# Create pickle file for user_info
f = 'C:/Users/' + comp_user + '/Simulations/' + user_info["username"] + '/AzureUserInfo.pickle'
pickle.dump(user_info,file(f, 'w'))
# Zip input files
inputs_zip = AzureTools.zip_files(user_info["username"], norm_inputs)
# Try uploading the specified input
try:
blob_service.put_block_blob_from_path(user_info["username"].lower(), self.vm_id, inputs_zip)
except:
stderr.write('An error occurred uploading your input.')
exit(1)
def generate_vm_id(self, username):
"""
Generates a name for the VM that will run the simulation. The name is created by add random hex to the client's
username to create a 15 character string
:param username:
:return:
"""
hash_obj = hashlib.sha1()
hash_obj.update(str(time()))
length = 14 - len(username) # specifies length of rand such that VM name will be 15 characters long
rand = hash_obj.hexdigest()[:length] # creates n random digits of hex
self.vm_id = username + '-' + rand # appends random hex number to the username to create a unique VM name
def check_name(self, name):
"""
Checks that the project name is valid
:return:
"""
valid = True
# Check that the project name is valid
val = search('[ <>:"/\\\|?*]', name)
if val:
valid = False
return valid
def simulation(self, username, sim_type="EMOD", ARG=False, DEL=True):
"""
Uploads a client's input files for a new simulation to the client's storage container and then creates a VM
under the client's cloud service on which the simulation will be run.
:param username:
:param sim_type:
:param ARG:
:param DEL:
:return:
"""
######### Create OS Hard Disk #########
if DEL:
if sim_type == "EMOD":
image_name = 'emod-email-v3-os-2015-02-05' #EMOD-OS-os-2014-07-09'
elif sim_type == "OM":
image_name = 'mock-model2-os-2014-07-10' #TODO Make OM image
elif sim_type == "mock":
image_name = 'mock-email-os-2015-02-03' #'mock-model2-os-2014-07-10'
else:
stderr.write('Error')
exit(1)
else:
if sim_type == "EMOD":
image_name = 'emod-email-noDel-v3-os-2015-02-04' #'no-delete-EMOD2-os-2014-09-19'
elif sim_type == "OM":
image_name = 'om-email-noDel-v5-os-2015-02-17' #'no-delete-Mock-os-2014-09-17'
elif sim_type == "mock":
image_name = 'mock-email-noDel-v4-os-2015-02-03' #'no-delete-Mock-os-2014-09-17'
else:
stderr.write('Error')
exit(1)
storage_account = STORAGE_ACCOUNT_NAME
blob = self.vm_id + '-blob.vhd'
media_link = "https://" + storage_account + ".blob.core.windows.net/vhds/" + blob
os_hd = OSVirtualHardDisk(image_name, media_link)
###### Windows VM configuration #####
windows_config = WindowsConfigurationSet(
computer_name=self.vm_id,
admin_password=VM_PASSWORD,
admin_username=VM_USERNAME)
windows_config.domain_join = None
windows_config.win_rm = None
### Endpoints for Remote Connection ###
endpoint_config = ConfigurationSet()
endpoint_config.configuration_set_type = 'NetworkConfiguration'
endpoint1 = ConfigurationSetInputEndpoint(
name='rdp',
protocol='tcp',
port='33890',
local_port='3389',
load_balanced_endpoint_set_name=None,
enable_direct_server_return=False)
endpoint_config.input_endpoints.input_endpoints.append(endpoint1)
############# Create VM #############
if int(self.cores) == 1:
core_size = 'Small'
elif int(self.cores) == 2:
core_size = 'Medium'
elif int(self.cores) == 4:
core_size = 'Large'
elif int(self.cores) == 8:
core_size = 'Extra Large'
elif int(self.cores) == 16:
core_size = 'A9'
else:
stderr.write('Core size not available. Options: 1, 2, 4, 8, 16\n')
print self.cores
exit(1)
# Check that there are cores available
timed_out = True
message_given = False
start_time = time()
while (time() - start_time) < 180:
subscription = sms.get_subscription()
cores_available = subscription.max_core_count - (subscription.current_core_count + int(self.cores))
if cores_available < 0:
if not message_given:
print 'No cores are available for usage at this time. Please, wait until a ' + str(self.cores) + '-core VM can be generated...\n'
message_given = True
else:
print "\nCreating VM..."
timed_out = False
break
if timed_out:
stderr.write("Request timed out: Windows Azure is a bit backlogged at the moment. Try again later.")
sleep(0.5)
if ARG:
exit(1)
else:
return 1
# Wait until a role can be added to the deployment
first = True
timed_out = True
start_time = time()
deployment_result = 0
while (time() - start_time) < 180: # will try to create role for 3 minutes before timing out
service = sms.get_hosted_service_properties(username, True)
# If there's a VM running on the client's service, add a VM to the pre-existing deployment
if service.deployments:
try:
deployment_result = sms.add_role(
service_name=username,
deployment_name=username,
role_name=self.vm_id,
system_config=windows_config,
os_virtual_hard_disk=os_hd,
role_size=core_size)
timed_out = False
break
except WindowsAzureConflictError:
if first:
print '\nWindows Azure is currently performing an operation on this deployment that requires ' \
'exclusive access. \nPlease, wait...'
first = False
except:
stderr.write("There was an error creating a virtual machine to run your simulation.")
sleep(0.5)
if ARG:
exit(1)
else:
return 1
# If no VMs are deployed, a VM is deployed on the client's service
elif not service.deployments:
try:
deployment_result = sms.create_virtual_machine_deployment(
service_name=username,
deployment_name=username,
deployment_slot='production',
label=self.vm_id,
role_name=self.vm_id,
network_config=endpoint_config,
system_config=windows_config,
os_virtual_hard_disk=os_hd,
role_size=core_size)
timed_out = False
break
except:
stderr.write("There was an error creating a virtual machine to run your simulation.")
sleep(0.5)
if ARG:
exit(1)
else:
return 1
if timed_out:
stderr.write("Request timed out: Windows Azure is a bit backlogged at the moment. Try again later.")
sleep(0.5)
if ARG:
exit(1)
else:
return 1
# Check that the VM was created properly
status = sms.get_operation_status(deployment_result.request_id)
try:
stderr.write(vars(status.error))
exit(1)
except:
print "\nSimulation Running! Check back later to retrieve results."
return 0