blob: 59ee6940354e7ab42981444b653e47c140712529 [file] [log] [blame]
koder aka kdanilov4643fd62015-02-10 16:20:13 -08001import re
2import os
3import time
4
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08005from concurrent.futures import ThreadPoolExecutor
6
koder aka kdanilov4643fd62015-02-10 16:20:13 -08007from novaclient.client import Client as n_client
8from cinderclient.v1.client import Client as c_client
9
10
11def ostack_get_creds():
12 env = os.environ.get
13 name = env('OS_USERNAME')
14 passwd = env('OS_PASSWORD')
15 tenant = env('OS_TENANT_NAME')
16 auth_url = env('OS_AUTH_URL')
17 return name, passwd, tenant, auth_url
18
19
20def nova_connect():
21 return n_client('1.1', *ostack_get_creds())
22
23
24def create_keypair(nova, name, key_path):
25 with open(key_path) as key:
26 return nova.keypairs.create(name, key.read())
27
28
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080029def create_volume(size, name):
koder aka kdanilov4643fd62015-02-10 16:20:13 -080030 cinder = c_client(*ostack_get_creds())
koder aka kdanilov4643fd62015-02-10 16:20:13 -080031 vol = cinder.volumes.create(size=size, display_name=name)
32 err_count = 0
33 while vol.status != 'available':
34 if vol.status == 'error':
35 if err_count == 3:
36 print "Fail to create volume"
37 raise RuntimeError("Fail to create volume")
38 else:
39 err_count += 1
40 cinder.volumes.delete(vol)
41 time.sleep(1)
42 vol = cinder.volumes.create(size=size, display_name=name)
43 continue
44 time.sleep(1)
45 vol = cinder.volumes.get(vol.id)
46 return vol
47
48
49def wait_for_server_active(nova, server, timeout=240):
50 t = time.time()
51 while True:
koder aka kdanilov3f356262015-02-13 08:06:14 -080052 time.sleep(1)
koder aka kdanilov4643fd62015-02-10 16:20:13 -080053 sstate = getattr(server, 'OS-EXT-STS:vm_state').lower()
54
55 if sstate == 'active':
56 return True
57
koder aka kdanilov4643fd62015-02-10 16:20:13 -080058 if sstate == 'error':
59 return False
60
61 if time.time() - t > timeout:
62 return False
63
64 server = nova.servers.get(server)
65
66
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080067class Allocate(object):
68 pass
69
70
71def get_floating_ips(nova, pool, amount):
koder aka kdanilov4643fd62015-02-10 16:20:13 -080072 ip_list = nova.floating_ips.list()
73
74 if pool is not None:
75 ip_list = [ip for ip in ip_list if ip.pool == pool]
76
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080077 return [ip for ip in ip_list if ip.instance_id is None][:amount]
koder aka kdanilov4643fd62015-02-10 16:20:13 -080078
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080079
80def create_vms_mt(nova, amount, keypair_name, img_name,
81 flavor_name, vol_sz=None, network_zone_name=None,
82 flt_ip_pool=None, name_templ='ceph-test-{}',
83 scheduler_hints=None):
84
85 if network_zone_name is not None:
86 network = nova.networks.find(label=network_zone_name)
87 nics = [{'net-id': network.id}]
koder aka kdanilov4643fd62015-02-10 16:20:13 -080088 else:
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080089 nics = None
koder aka kdanilov4643fd62015-02-10 16:20:13 -080090
koder aka kdanilov4643fd62015-02-10 16:20:13 -080091 fl = nova.flavors.find(name=flavor_name)
92 img = nova.images.find(name=img_name)
koder aka kdanilov4643fd62015-02-10 16:20:13 -080093
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080094 if flt_ip_pool is not None:
95 ips = get_floating_ips(nova, flt_ip_pool, amount)
96 ips += [Allocate] * (amount - len(ips))
97 else:
98 ips = [None] * amount
99
100 print "Try to start {0} servers".format(amount)
101 names = map(name_templ.format, range(amount))
102
103 with ThreadPoolExecutor(max_workers=16) as executor:
104 futures = []
105 for name, flt_ip in zip(names, ips):
106 params = (nova, name, keypair_name, img, fl,
107 nics, vol_sz, flt_ip, scheduler_hints,
108 flt_ip_pool)
109
110 futures.append(executor.submit(create_vm, *params))
111 return [future.result() for future in futures]
112
113
114def create_vm(nova, name, keypair_name, img,
115 fl, nics, vol_sz=None,
116 flt_ip=False,
117 scheduler_hints=None,
118 pool=None):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800119 for i in range(3):
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800120 srv = nova.servers.create(name,
121 flavor=fl, image=img, nics=nics,
122 key_name=keypair_name,
123 scheduler_hints=scheduler_hints)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800124
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800125 if not wait_for_server_active(nova, srv):
126 msg = "Server {0} fails to start. Kill it and try again"
127 print msg.format(srv.name)
128 nova.servers.delete(srv)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800129
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800130 while True:
koder aka kdanilov3f356262015-02-13 08:06:14 -0800131 # print "wait till server deleted"
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800132 all_id = set(alive_srv.id for alive_srv in nova.servers.list())
133 if srv.id not in all_id:
134 break
135 time.sleep(1)
136 else:
137 break
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800138
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800139 if vol_sz is not None:
koder aka kdanilov3f356262015-02-13 08:06:14 -0800140 # print "creating volume"
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800141 vol = create_volume(vol_sz, name)
koder aka kdanilov3f356262015-02-13 08:06:14 -0800142 # print "attach volume to server"
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800143 nova.volumes.create_server_volume(srv.id, vol.id, None)
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800144
145 if flt_ip is Allocate:
146 flt_ip = nova.floating_ips.create(pool)
147
148 if flt_ip is not None:
koder aka kdanilov3f356262015-02-13 08:06:14 -0800149 # print "attaching ip to server"
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800150 srv.add_floating_ip(flt_ip)
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800151 return (flt_ip.ip, srv)
152 else:
153 return (None, srv)
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800154
155
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800156def clear_all(nova, name_templ="ceph-test-{}"):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800157 deleted_srvs = set()
158 for srv in nova.servers.list():
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800159 if re.match(name_templ.format("\\d+"), srv.name):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800160 print "Deleting server", srv.name
161 nova.servers.delete(srv)
162 deleted_srvs.add(srv.id)
163
164 while deleted_srvs != set():
165 print "Waiting till all servers are actually deleted"
166 all_id = set(srv.id for srv in nova.servers.list())
167 if all_id.intersection(deleted_srvs) == set():
168 print "Done, deleting volumes"
169 break
170 time.sleep(1)
171
172 # wait till vm actually deleted
173
174 cinder = c_client(*ostack_get_creds())
175 for vol in cinder.volumes.list():
176 if isinstance(vol.display_name, basestring):
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800177 if re.match(name_templ.format("\\d+"), vol.display_name):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800178 if vol.status in ('available', 'error'):
179 print "Deleting volume", vol.display_name
180 cinder.volumes.delete(vol)
181
182 print "Clearing done (yet some volumes may still deleting)"
183
184
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800185# def prepare_host(key_file, ip, fio_path, dst_fio_path, user='cirros'):
186# print "Wait till ssh ready...."
187# wait_ssh_ready(ip, user, key_file)
188
189# print "Preparing host >"
190# print " Coping fio"
191# copy_fio(key_file, ip, fio_path, user, dst_fio_path)
192
193# key_opts = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
194# args = (key_file, user, ip, key_opts)
195# cmd_format = "ssh {3} -i {0} {1}@{2} '{{0}}'".format(*args).format
196
197# def exec_on_host(cmd):
198# print " " + cmd
199# subprocess.check_call(cmd_format(cmd), shell=True)
200
201# exec_on_host("sudo /usr/sbin/mkfs.ext4 /dev/vdb")
202# exec_on_host("sudo /bin/mkdir /media/ceph")
203# exec_on_host("sudo /bin/mount /dev/vdb /media/ceph")
204# exec_on_host("sudo /bin/chmod a+rwx /media/ceph")
205
206
207def main():
208 image_name = 'TestVM'
209 flavor_name = 'ceph'
210 vol_sz = 50
211 network_zone_name = 'net04'
212 amount = 10
213 keypair_name = 'ceph-test'
214
215 nova = nova_connect()
216 clear_all(nova)
217
218 try:
219 ips = []
220 params = dict(vol_sz=vol_sz)
221 params['image_name'] = image_name
222 params['flavor_name'] = flavor_name
223 params['network_zone_name'] = network_zone_name
224 params['amount'] = amount
225 params['keypair_name'] = keypair_name
226
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -0800227 for ip, host in create_vms(nova, **params):
koder aka kdanilov4643fd62015-02-10 16:20:13 -0800228 ips.append(ip)
229
230 print "All setup done! Ips =", " ".join(ips)
231 print "Starting tests"
232 finally:
233 clear_all(nova)
234
235if __name__ == "__main__":
236 exit(main())