blob: 471996a2539d2ced60ff56ff97977e4e9f360ada [file] [log] [blame]
koder aka kdanilov4643fd62015-02-10 16:20:13 -08001import re
2import os
3import time
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +03004import os.path
koder aka kdanilove21d7472015-02-14 19:02:04 -08005import logging
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +03006import subprocess
koder aka kdanilov4643fd62015-02-10 16:20:13 -08007
koder aka kdanilovfd2cfa52015-05-20 03:17:42 +03008from concurrent.futures import ThreadPoolExecutor
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08009
koder aka kdanilov4500a5f2015-04-17 16:55:17 +030010from novaclient.exceptions import NotFound
koder aka kdanilov4643fd62015-02-10 16:20:13 -080011from novaclient.client import Client as n_client
12from cinderclient.v1.client import Client as c_client
13
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030014import wally
15from wally.discover import Node
koder aka kdanilov1c2b5112015-04-10 16:53:51 +030016
koder aka kdanilov4643fd62015-02-10 16:20:13 -080017
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030018logger = logging.getLogger("wally.vms")
koder aka kdanilove21d7472015-02-14 19:02:04 -080019
20
koder aka kdanilove87ae652015-04-20 02:14:35 +030021STORED_OPENSTACK_CREDS = None
koder aka kdanilov1c2b5112015-04-10 16:53:51 +030022NOVA_CONNECTION = None
koder aka kdanilove87ae652015-04-20 02:14:35 +030023CINDER_CONNECTION = None
24
25
koder aka kdanilov416b87a2015-05-12 00:26:04 +030026def is_connected():
27 return NOVA_CONNECTION is not None
28
29
koder aka kdanilove87ae652015-04-20 02:14:35 +030030def ostack_get_creds():
31 if STORED_OPENSTACK_CREDS is None:
32 env = os.environ.get
33 name = env('OS_USERNAME')
34 passwd = env('OS_PASSWORD')
35 tenant = env('OS_TENANT_NAME')
36 auth_url = env('OS_AUTH_URL')
37 return name, passwd, tenant, auth_url
38 else:
39 return STORED_OPENSTACK_CREDS
koder aka kdanilov1c2b5112015-04-10 16:53:51 +030040
41
42def nova_connect(name=None, passwd=None, tenant=None, auth_url=None):
43 global NOVA_CONNECTION
koder aka kdanilove87ae652015-04-20 02:14:35 +030044 global STORED_OPENSTACK_CREDS
45
koder aka kdanilov1c2b5112015-04-10 16:53:51 +030046 if NOVA_CONNECTION is None:
47 if name is None:
48 name, passwd, tenant, auth_url = ostack_get_creds()
koder aka kdanilove87ae652015-04-20 02:14:35 +030049 else:
50 STORED_OPENSTACK_CREDS = (name, passwd, tenant, auth_url)
51
koder aka kdanilov1c2b5112015-04-10 16:53:51 +030052 NOVA_CONNECTION = n_client('1.1', name, passwd, tenant, auth_url)
53 return NOVA_CONNECTION
54
55
koder aka kdanilove87ae652015-04-20 02:14:35 +030056def cinder_connect(name=None, passwd=None, tenant=None, auth_url=None):
57 global CINDER_CONNECTION
58 global STORED_OPENSTACK_CREDS
59
60 if CINDER_CONNECTION is None:
61 if name is None:
62 name, passwd, tenant, auth_url = ostack_get_creds()
63 else:
64 STORED_OPENSTACK_CREDS = (name, passwd, tenant, auth_url)
65 CINDER_CONNECTION = c_client(name, passwd, tenant, auth_url)
66 return CINDER_CONNECTION
67
68
koder aka kdanilovc368eb62015-04-28 18:22:01 +030069def prepare_os_subpr(params, name=None, passwd=None, tenant=None,
70 auth_url=None):
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +030071 if name is None:
72 name, passwd, tenant, auth_url = ostack_get_creds()
73
koder aka kdanilovc368eb62015-04-28 18:22:01 +030074 MAX_VM_PER_NODE = 8
75 serv_groups = " ".join(map(params['aa_group_name'].format,
76 range(MAX_VM_PER_NODE)))
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +030077
koder aka kdanilov6ab4d432015-06-22 00:26:28 +030078 image_name = params['image']['name']
koder aka kdanilovc368eb62015-04-28 18:22:01 +030079 env = os.environ.copy()
80 env.update(dict(
81 OS_USERNAME=name,
82 OS_PASSWORD=passwd,
83 OS_TENANT_NAME=tenant,
84 OS_AUTH_URL=auth_url,
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +030085
koder aka kdanilovc368eb62015-04-28 18:22:01 +030086 FLAVOR_NAME=params['flavor']['name'],
87 FLAVOR_RAM=str(params['flavor']['ram_size']),
88 FLAVOR_HDD=str(params['flavor']['hdd_size']),
89 FLAVOR_CPU_COUNT=str(params['flavor']['cpu_count']),
90
91 SERV_GROUPS=serv_groups,
92 KEYPAIR_NAME=params['keypair_name'],
93
94 SECGROUP=params['security_group'],
95
koder aka kdanilov6ab4d432015-06-22 00:26:28 +030096 IMAGE_NAME=image_name,
koder aka kdanilovc368eb62015-04-28 18:22:01 +030097 KEY_FILE_NAME=params['keypair_file_private'],
98 IMAGE_URL=params['image']['url'],
99 ))
100
101 spath = os.path.dirname(os.path.dirname(wally.__file__))
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300102 spath = os.path.join(spath, 'scripts/prepare.sh')
103
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300104 cmd = "bash {spath} >/dev/null".format(spath=spath)
105 subprocess.check_call(cmd, shell=True, env=env)
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +0300106
koder aka kdanilov7e0f7cf2015-05-01 17:24:35 +0300107 conn = nova_connect(name, passwd, tenant, auth_url)
108 while True:
koder aka kdanilov6ab4d432015-06-22 00:26:28 +0300109 status = conn.images.find(name=image_name).status
koder aka kdanilov7e0f7cf2015-05-01 17:24:35 +0300110 if status == 'ACTIVE':
111 break
112 msg = "Image {0} is still in {1} state. Waiting 10 more seconds"
koder aka kdanilov6ab4d432015-06-22 00:26:28 +0300113 logger.info(msg.format(image_name, status))
koder aka kdanilov7e0f7cf2015-05-01 17:24:35 +0300114 time.sleep(10)
115
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300116
koder aka kdanilovf86d7af2015-05-06 04:01:54 +0300117def find_vms(nova, name_prefix):
118 for srv in nova.servers.list():
119 if srv.name.startswith(name_prefix):
120 for ips in srv.addresses.values():
121 for ip in ips:
122 if ip.get("OS-EXT-IPS:type", None) == 'floating':
koder aka kdanilovd5ed4da2015-05-07 23:33:23 +0300123 yield ip['addr'], srv.id
koder aka kdanilovf86d7af2015-05-06 04:01:54 +0300124 break
125
126
koder aka kdanilov416b87a2015-05-12 00:26:04 +0300127def pause(ids):
128 def pause_vm(conn, vm_id):
129 vm = conn.servers.get(vm_id)
130 if vm.status == 'ACTIVE':
131 vm.pause()
132
133 conn = nova_connect()
134 with ThreadPoolExecutor(max_workers=16) as executor:
135 futures = [executor.submit(pause_vm, conn, vm_id)
136 for vm_id in ids]
137 for future in futures:
138 future.result()
139
140
141def unpause(ids, max_resume_time=10):
142 def unpause(conn, vm_id):
143 vm = conn.servers.get(vm_id)
144 if vm.status == 'PAUSED':
145 vm.unpause()
146
147 for i in range(max_resume_time * 10):
148 vm = conn.servers.get(vm_id)
149 if vm.status != 'PAUSED':
150 return
151 time.sleep(0.1)
152 raise RuntimeError("Can't unpause vm {0}".format(vm_id))
153
154 conn = nova_connect()
155 with ThreadPoolExecutor(max_workers=16) as executor:
156 futures = [executor.submit(unpause, conn, vm_id)
157 for vm_id in ids]
158
159 for future in futures:
160 future.result()
161
162
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300163def prepare_os(nova, params):
164 allow_ssh(nova, params['security_group'])
165
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300166 MAX_VM_PER_NODE = 8
167 serv_groups = " ".join(map(params['aa_group_name'].format,
168 range(MAX_VM_PER_NODE)))
169
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300170 shed_ids = []
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300171 for shed_group in serv_groups:
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300172 shed_ids.append(get_or_create_aa_group(nova, shed_group))
173
174 create_keypair(nova,
175 params['keypair_name'],
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300176 params['keypair_name'] + ".pub",
177 params['keypair_name'] + ".pem")
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300178
179 create_image(nova, params['image']['name'],
180 params['image']['url'])
181
182 create_flavor(nova, **params['flavor'])
koder aka kdanilov4e9f3ed2015-04-14 11:26:12 +0300183
184
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300185def get_or_create_aa_group(nova, name):
186 try:
187 group = nova.server_groups.find(name=name)
188 except NotFound:
189 group = nova.server_groups.create({'name': name,
190 'policies': ['anti-affinity']})
koder aka kdanilov652cd802015-04-13 12:21:07 +0300191
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300192 return group.id
koder aka kdanilov652cd802015-04-13 12:21:07 +0300193
194
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300195def allow_ssh(nova, group_name):
196 try:
197 secgroup = nova.security_groups.find(name=group_name)
198 except NotFound:
199 secgroup = nova.security_groups.create(group_name,
200 "allow ssh/ping to node")
201
koder aka kdanilov652cd802015-04-13 12:21:07 +0300202 nova.security_group_rules.create(secgroup.id,
203 ip_protocol="tcp",
204 from_port="22",
205 to_port="22",
206 cidr="0.0.0.0/0")
207
208 nova.security_group_rules.create(secgroup.id,
209 ip_protocol="icmp",
210 from_port=-1,
211 cidr="0.0.0.0/0",
212 to_port=-1)
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300213 return secgroup.id
koder aka kdanilov652cd802015-04-13 12:21:07 +0300214
215
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300216def create_image(nova, name, url):
217 pass
218
219
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300220def create_flavor(nova, name, ram_size, hdd_size, cpu_count):
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300221 pass
222
223
224def create_keypair(nova, name, pub_key_path, priv_key_path):
225 try:
226 nova.keypairs.find(name=name)
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300227 # if file not found- delete and recreate
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300228 except NotFound:
229 if os.path.exists(pub_key_path):
230 with open(pub_key_path) as pub_key_fd:
231 return nova.keypairs.create(name, pub_key_fd.read())
232 else:
233 key = nova.keypairs.create(name)
234
235 with open(priv_key_path, "w") as priv_key_fd:
236 priv_key_fd.write(key.private_key)
237
238 with open(pub_key_path, "w") as pub_key_fd:
239 pub_key_fd.write(key.public_key)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800240
241
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800242def create_volume(size, name):
koder aka kdanilove87ae652015-04-20 02:14:35 +0300243 cinder = cinder_connect()
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800244 vol = cinder.volumes.create(size=size, display_name=name)
245 err_count = 0
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300246
koder aka kdanilove87ae652015-04-20 02:14:35 +0300247 while vol.status != 'available':
248 if vol.status == 'error':
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800249 if err_count == 3:
koder aka kdanilove21d7472015-02-14 19:02:04 -0800250 logger.critical("Fail to create volume")
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800251 raise RuntimeError("Fail to create volume")
252 else:
253 err_count += 1
254 cinder.volumes.delete(vol)
255 time.sleep(1)
256 vol = cinder.volumes.create(size=size, display_name=name)
257 continue
258 time.sleep(1)
koder aka kdanilove87ae652015-04-20 02:14:35 +0300259 vol = cinder.volumes.get(vol.id)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800260 return vol
261
262
koder aka kdanilov4af1c1d2015-05-18 15:48:58 +0300263def wait_for_server_active(nova, server, timeout=300):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800264 t = time.time()
265 while True:
koder aka kdanilov3f356262015-02-13 08:06:14 -0800266 time.sleep(1)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800267 sstate = getattr(server, 'OS-EXT-STS:vm_state').lower()
268
269 if sstate == 'active':
270 return True
271
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800272 if sstate == 'error':
273 return False
274
275 if time.time() - t > timeout:
276 return False
277
278 server = nova.servers.get(server)
279
280
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800281class Allocate(object):
282 pass
283
284
285def get_floating_ips(nova, pool, amount):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800286 ip_list = nova.floating_ips.list()
287
288 if pool is not None:
289 ip_list = [ip for ip in ip_list if ip.pool == pool]
290
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800291 return [ip for ip in ip_list if ip.instance_id is None][:amount]
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800292
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800293
koder aka kdanilovd5ed4da2015-05-07 23:33:23 +0300294def launch_vms(params, already_has_count=0):
koder aka kdanilov4af1c1d2015-05-18 15:48:58 +0300295 logger.debug("Calculating new vm count")
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300296 count = params['count']
koder aka kdanilov416b87a2015-05-12 00:26:04 +0300297 nova = nova_connect()
298 lst = nova.services.list(binary='nova-compute')
koder aka kdanilovd5ed4da2015-05-07 23:33:23 +0300299 srv_count = len([srv for srv in lst if srv.status == 'enabled'])
koder aka kdanilovda45e882015-04-06 02:24:42 +0300300
301 if isinstance(count, basestring):
koder aka kdanilovd5ed4da2015-05-07 23:33:23 +0300302 if count.startswith("x"):
303 count = srv_count * int(count[1:])
304 else:
305 assert count.startswith('=')
306 count = int(count[1:]) - already_has_count
307
308 if count <= 0:
koder aka kdanilov4af1c1d2015-05-18 15:48:58 +0300309 logger.debug("Not need new vms")
koder aka kdanilovd5ed4da2015-05-07 23:33:23 +0300310 return
koder aka kdanilovda45e882015-04-06 02:24:42 +0300311
koder aka kdanilov4af1c1d2015-05-18 15:48:58 +0300312 logger.debug("Starting new nodes on openstack")
313
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300314 assert isinstance(count, (int, long))
315
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300316 srv_params = "img: {image[name]}, flavor: {flavor[name]}".format(**params)
koder aka kdanilov66839a92015-04-11 13:22:31 +0300317 msg_templ = "Will start {0} servers with next params: {1}"
koder aka kdanilovcee43342015-04-14 22:52:53 +0300318 logger.info(msg_templ.format(count, srv_params))
koder aka kdanilovda45e882015-04-06 02:24:42 +0300319
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300320 vm_params = dict(
321 img_name=params['image']['name'],
322 flavor_name=params['flavor']['name'],
323 group_name=params['group_name'],
324 keypair_name=params['keypair_name'],
325 vol_sz=params.get('vol_sz'),
326 network_zone_name=params.get("network_zone_name"),
327 flt_ip_pool=params.get('flt_ip_pool'),
328 name_templ=params.get('name_templ'),
329 scheduler_hints={"group": params['aa_group_name']},
330 security_group=params['security_group'],
331 sec_group_size=srv_count
332 )
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300333
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300334 # precache all errors before start creating vms
335 private_key_path = params['keypair_file_private']
336 creds = params['image']['creds']
337 creds.format(ip="1.1.1.1", private_key_path="/some_path/xx")
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300338
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300339 for ip, os_node in create_vms_mt(NOVA_CONNECTION, count, **vm_params):
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300340
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300341 conn_uri = creds.format(ip=ip, private_key_path=private_key_path)
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300342 yield Node(conn_uri, []), os_node.id
koder aka kdanilovda45e882015-04-06 02:24:42 +0300343
344
koder aka kdanilovd5ed4da2015-05-07 23:33:23 +0300345def get_free_server_grpoups(nova, template=None):
346 for g in nova.server_groups.list():
347 if g.members == []:
348 if re.match(template, g.name):
349 yield str(g.name)
350
351
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300352def create_vms_mt(nova, amount, group_name, keypair_name, img_name,
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800353 flavor_name, vol_sz=None, network_zone_name=None,
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300354 flt_ip_pool=None, name_templ='wally-{id}',
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300355 scheduler_hints=None, security_group=None,
356 sec_group_size=None):
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800357
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800358 with ThreadPoolExecutor(max_workers=16) as executor:
koder aka kdanilov97644f92015-02-13 11:11:08 -0800359 if network_zone_name is not None:
360 network_future = executor.submit(nova.networks.find,
361 label=network_zone_name)
362 else:
363 network_future = None
364
365 fl_future = executor.submit(nova.flavors.find, name=flavor_name)
366 img_future = executor.submit(nova.images.find, name=img_name)
367
368 if flt_ip_pool is not None:
369 ips_future = executor.submit(get_floating_ips,
370 nova, flt_ip_pool, amount)
koder aka kdanilove21d7472015-02-14 19:02:04 -0800371 logger.debug("Wait for floating ip")
koder aka kdanilov97644f92015-02-13 11:11:08 -0800372 ips = ips_future.result()
373 ips += [Allocate] * (amount - len(ips))
374 else:
375 ips = [None] * amount
376
koder aka kdanilov7dec9df2015-02-15 21:35:19 -0800377 logger.debug("Getting flavor object")
koder aka kdanilov97644f92015-02-13 11:11:08 -0800378 fl = fl_future.result()
koder aka kdanilov7dec9df2015-02-15 21:35:19 -0800379 logger.debug("Getting image object")
koder aka kdanilov97644f92015-02-13 11:11:08 -0800380 img = img_future.result()
381
382 if network_future is not None:
koder aka kdanilove21d7472015-02-14 19:02:04 -0800383 logger.debug("Waiting for network results")
koder aka kdanilov97644f92015-02-13 11:11:08 -0800384 nics = [{'net-id': network_future.result().id}]
385 else:
386 nics = None
387
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300388 names = []
389 for i in range(amount):
390 names.append(name_templ.format(group=group_name, id=i))
koder aka kdanilov97644f92015-02-13 11:11:08 -0800391
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800392 futures = []
koder aka kdanilov168f6092015-04-19 02:33:38 +0300393 logger.debug("Requesting new vm's")
koder aka kdanilov6e2ae792015-03-04 18:02:24 -0800394
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300395 orig_scheduler_hints = scheduler_hints.copy()
396
koder aka kdanilovd5ed4da2015-05-07 23:33:23 +0300397 MAX_SHED_GROUPS = 32
398 for start_idx in range(MAX_SHED_GROUPS):
399 pass
400
401 group_name_template = scheduler_hints['group'].format("\\d+")
402 groups = list(get_free_server_grpoups(nova, group_name_template + "$"))
403 groups.sort()
404
405 for idx, (name, flt_ip) in enumerate(zip(names, ips), 2):
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300406
407 scheduler_hints = None
408 if orig_scheduler_hints is not None and sec_group_size is not None:
409 if "group" in orig_scheduler_hints:
410 scheduler_hints = orig_scheduler_hints.copy()
koder aka kdanilovd5ed4da2015-05-07 23:33:23 +0300411 scheduler_hints['group'] = groups[idx // sec_group_size]
koder aka kdanilovc368eb62015-04-28 18:22:01 +0300412
413 if scheduler_hints is None:
414 scheduler_hints = orig_scheduler_hints.copy()
415
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800416 params = (nova, name, keypair_name, img, fl,
417 nics, vol_sz, flt_ip, scheduler_hints,
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300418 flt_ip_pool, [security_group])
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800419
420 futures.append(executor.submit(create_vm, *params))
koder aka kdanilove21d7472015-02-14 19:02:04 -0800421 res = [future.result() for future in futures]
422 logger.debug("Done spawning")
423 return res
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800424
425
426def create_vm(nova, name, keypair_name, img,
427 fl, nics, vol_sz=None,
428 flt_ip=False,
429 scheduler_hints=None,
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300430 pool=None,
431 security_groups=None):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800432 for i in range(3):
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800433 srv = nova.servers.create(name,
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300434 flavor=fl,
435 image=img,
436 nics=nics,
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800437 key_name=keypair_name,
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300438 scheduler_hints=scheduler_hints,
439 security_groups=security_groups)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800440
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800441 if not wait_for_server_active(nova, srv):
442 msg = "Server {0} fails to start. Kill it and try again"
koder aka kdanilove21d7472015-02-14 19:02:04 -0800443 logger.debug(msg.format(srv))
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800444 nova.servers.delete(srv)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800445
koder aka kdanilovf86d7af2015-05-06 04:01:54 +0300446 try:
447 for j in range(120):
448 srv = nova.servers.get(srv.id)
449 time.sleep(1)
450 else:
451 msg = "Server {0} delete timeout".format(srv.id)
452 raise RuntimeError(msg)
453 except NotFound:
454 pass
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800455 else:
456 break
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +0300457 else:
458 raise RuntimeError("Failed to start server".format(srv.id))
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800459
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800460 if vol_sz is not None:
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800461 vol = create_volume(vol_sz, name)
koder aka kdanilove87ae652015-04-20 02:14:35 +0300462 nova.volumes.create_server_volume(srv.id, vol.id, None)
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800463
464 if flt_ip is Allocate:
465 flt_ip = nova.floating_ips.create(pool)
koder aka kdanilovda45e882015-04-06 02:24:42 +0300466
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800467 if flt_ip is not None:
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800468 srv.add_floating_ip(flt_ip)
Yulia Portnova0e64ea22015-03-20 17:27:22 +0200469
koder aka kdanilovda45e882015-04-06 02:24:42 +0300470 return flt_ip.ip, nova.servers.get(srv.id)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800471
472
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300473def clear_nodes(nodes_ids):
474 clear_all(NOVA_CONNECTION, nodes_ids, None)
gstepanov023c1e42015-04-08 15:50:19 +0300475
476
koder aka kdanilove87ae652015-04-20 02:14:35 +0300477def clear_all(nova, ids=None, name_templ=None):
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300478
479 def need_delete(srv):
480 if name_templ is not None:
481 return re.match(name_templ.format("\\d+"), srv.name) is not None
482 else:
483 return srv.id in ids
484
koder aka kdanilove87ae652015-04-20 02:14:35 +0300485 volumes_to_delete = []
486 cinder = cinder_connect()
487 for vol in cinder.volumes.list():
488 for attachment in vol.attachments:
489 if attachment['server_id'] in ids:
490 volumes_to_delete.append(vol)
491 break
492
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800493 deleted_srvs = set()
494 for srv in nova.servers.list():
koder aka kdanilov1c2b5112015-04-10 16:53:51 +0300495 if need_delete(srv):
koder aka kdanilove21d7472015-02-14 19:02:04 -0800496 logger.debug("Deleting server {0}".format(srv.name))
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800497 nova.servers.delete(srv)
498 deleted_srvs.add(srv.id)
499
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300500 count = 0
501 while True:
502 if count % 60 == 0:
503 logger.debug("Waiting till all servers are actually deleted")
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800504 all_id = set(srv.id for srv in nova.servers.list())
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300505 if len(all_id.intersection(deleted_srvs)) == 0:
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800506 break
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300507 count += 1
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800508 time.sleep(1)
koder aka kdanilov4500a5f2015-04-17 16:55:17 +0300509 logger.debug("Done, deleting volumes")
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800510
511 # wait till vm actually deleted
512
koder aka kdanilov6b1341a2015-04-21 22:44:21 +0300513 # logger.warning("Volume deletion commented out")
514 for vol in volumes_to_delete:
515 logger.debug("Deleting volume " + vol.display_name)
516 cinder.volumes.delete(vol)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800517
koder aka kdanilove21d7472015-02-14 19:02:04 -0800518 logger.debug("Clearing done (yet some volumes may still deleting)")