blob: e495afbd5aa171d3808570db4febf32a1d285403 [file] [log] [blame]
Matteo Scandolo48d3d2d2017-08-08 13:05:27 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
A R Karthick81acbff2016-06-17 14:45:16 -070017#
Chetan Gaonkercfcce782016-05-10 10:10:42 -070018# Copyright 2016-present Ciena Corporation
19#
20# Licensed under the Apache License, Version 2.0 (the "License");
21# you may not use this file except in compliance with the License.
22# You may obtain a copy of the License at
A R Karthick81acbff2016-06-17 14:45:16 -070023#
Chetan Gaonkercfcce782016-05-10 10:10:42 -070024# http://www.apache.org/licenses/LICENSE-2.0
A R Karthick81acbff2016-06-17 14:45:16 -070025#
Chetan Gaonkercfcce782016-05-10 10:10:42 -070026# Unless required by applicable law or agreed to in writing, software
27# distributed under the License is distributed on an "AS IS" BASIS,
28# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29# See the License for the specific language governing permissions and
30# limitations under the License.
31#
A.R Karthick1700e0e2016-10-06 18:16:57 -070032from CordContainer import Container, Onos, OnosStopWrapper, OnosCord, OnosCordStopWrapper, Quagga, QuaggaStopWrapper, Radius, reinitContainerClients
A R Karthick1555c7c2017-09-07 14:59:41 -070033from OltConfig import OltConfig
A R Karthickefcf1ab2017-09-08 18:24:16 -070034from EapolAAA import get_radius_macs, get_radius_networks
Chetan Gaonker3533faa2016-04-25 17:50:14 -070035from nose.tools import nottest
A R Karthick81acbff2016-06-17 14:45:16 -070036from SimpleXMLRPCServer import SimpleXMLRPCServer
A R Karthick1878c4f2016-11-29 09:19:50 -080037from resource import getrlimit, RLIMIT_NOFILE
A R Karthick81acbff2016-06-17 14:45:16 -070038import daemon
39import xmlrpclib
40import os
A R Karthicke99ab5c2016-09-30 13:59:57 -070041import signal
A R Karthick81acbff2016-06-17 14:45:16 -070042import json
43import time
44import threading
Chetan Gaonker3533faa2016-04-25 17:50:14 -070045
A R Karthick81acbff2016-06-17 14:45:16 -070046##Server to handle container restart/stop requests from test container.
Chetan Gaonker3533faa2016-04-25 17:50:14 -070047##Used now to restart ONOS from vrouter test container
48
49CORD_TEST_HOST = '172.17.0.1'
50CORD_TEST_PORT = 25000
51
A R Karthick81acbff2016-06-17 14:45:16 -070052class CordTestServer(object):
53
A R Karthickbd9b8a32016-07-21 09:56:45 -070054 onos_cord = None
55
A R Karthickde6b9dc2016-11-29 17:46:16 -080056 def __restart_onos(self, node = None, config = None, timeout = 10):
A R Karthickbd9b8a32016-07-21 09:56:45 -070057 if self.onos_cord:
A R Karthick928ad622017-01-30 12:18:32 -080058 onos_config = '{}/network-cfg.json'.format(self.onos_cord.onos_config_dir)
A R Karthickd44cea12016-07-20 12:16:41 -070059 else:
60 onos_config = '{}/network-cfg.json'.format(Onos.host_config_dir)
A R Karthick81acbff2016-06-17 14:45:16 -070061 if config is None:
62 try:
63 os.unlink(onos_config)
64 except:
65 pass
Chetan Gaonker6cf6e472016-04-26 14:41:51 -070066 print('Restarting ONOS')
A R Karthickbd9b8a32016-07-21 09:56:45 -070067 if self.onos_cord:
68 self.onos_cord.start(restart = True, network_cfg = config)
A R Karthickd44cea12016-07-20 12:16:41 -070069 else:
A R Karthickde6b9dc2016-11-29 17:46:16 -080070 Onos.restart_node(node = node, network_cfg = config, timeout = timeout)
A R Karthick81acbff2016-06-17 14:45:16 -070071 return 'DONE'
Chetan Gaonker6cf6e472016-04-26 14:41:51 -070072
A R Karthick81acbff2016-06-17 14:45:16 -070073 def restart_onos(self, kwargs):
74 return self.__restart_onos(**kwargs)
75
A.R Karthick1700e0e2016-10-06 18:16:57 -070076 def __shutdown_onos(self, node = None):
77 if node is None:
78 node = Onos.NAME
79 OnosStopWrapper(node)
80 return 'DONE'
81
82 def shutdown_onos(self, kwargs):
83 return self.__shutdown_onos(**kwargs)
84
A.R Karthick2560f042016-11-30 14:38:52 -080085 def __restart_cluster(self, config = None, timeout = 10, setup = False):
86 Onos.restart_cluster(network_cfg = config, timeout = timeout, setup = setup)
87 return 'DONE'
88
89 def restart_cluster(self, kwargs):
90 return self.__restart_cluster(**kwargs)
91
A R Karthicke2c24bd2016-10-07 14:51:38 -070092 def __add_cluster_onos(self, count = 1, config = None):
93 Onos.add_cluster(count = count, network_cfg = config)
94 return 'DONE'
95
96 def add_cluster_onos(self, kwargs):
A R Karthickdb59cf72016-10-10 10:43:22 -070097 return self.__add_cluster_onos(**kwargs)
A R Karthicke2c24bd2016-10-07 14:51:38 -070098
A R Karthick81acbff2016-06-17 14:45:16 -070099 def __restart_quagga(self, config = None, boot_delay = 30 ):
Chetan Gaonkerfd3d6502016-05-03 13:23:07 -0700100 config_file = Quagga.quagga_config_file
A R Karthick81acbff2016-06-17 14:45:16 -0700101 if config is not None:
102 quagga_config = '{}/testrib_gen.conf'.format(Quagga.host_quagga_config)
103 config_file = '{}/testrib_gen.conf'.format(Quagga.guest_quagga_config)
104 with open(quagga_config, 'w+') as fd:
105 fd.write(str(config))
106 print('Restarting QUAGGA with config file %s, delay %d' %(config_file, boot_delay))
A R Karthick07608ef2016-08-23 16:51:19 -0700107 Quagga(prefix = Container.IMAGE_PREFIX, restart = True, config_file = config_file, boot_delay = boot_delay)
A R Karthick81acbff2016-06-17 14:45:16 -0700108 return 'DONE'
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700109
A R Karthick81acbff2016-06-17 14:45:16 -0700110 def restart_quagga(self, kwargs):
111 return self.__restart_quagga(**kwargs)
Chetan Gaonker7f4bf742016-05-04 15:56:08 -0700112
A R Karthick81acbff2016-06-17 14:45:16 -0700113 def stop_quagga(self):
114 quaggaStop = QuaggaStopWrapper()
A R Karthick4a2362c2016-06-22 17:32:44 -0700115 time.sleep(5)
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700116 try:
A R Karthick81acbff2016-06-17 14:45:16 -0700117 quagga_config_gen = '{}/testrib_gen.conf'.format(Quagga.host_quagga_config)
118 os.unlink(quagga_config_gen)
119 except: pass
120 return 'DONE'
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700121
A R Karthickc3d80e22016-06-22 17:51:24 -0700122 def __run_shell_quagga(self, cmd = None):
123 ret = 0
124 if cmd is not None:
125 exec_cmd = 'docker exec {} {}'.format(Quagga.NAME, cmd)
126 ret = os.system(exec_cmd)
127 return ret
128
A R Karthicka013a272016-08-16 16:40:19 -0700129 def __run_shell(self, cmd = None):
130 ret = 0
131 if cmd is not None:
132 ret = os.system(cmd)
133 return ret
134
A R Karthickc3d80e22016-06-22 17:51:24 -0700135 def run_shell_quagga(self, kwargs):
136 return self.__run_shell_quagga(**kwargs)
137
A R Karthicka013a272016-08-16 16:40:19 -0700138 def run_shell(self, kwargs):
139 return self.__run_shell(**kwargs)
140
A R Karthick1555c7c2017-09-07 14:59:41 -0700141 def __restart_radius(self, olt_conf_file = ''):
142 olt_conf = os.path.join(Onos.setup_dir, os.path.basename(olt_conf_file))
143 olt = OltConfig(olt_conf_file = olt_conf)
144 port_map, _ = olt.olt_port_map()
A R Karthick07608ef2016-08-23 16:51:19 -0700145 Radius(prefix = Container.IMAGE_PREFIX, restart = True)
A R Karthick1555c7c2017-09-07 14:59:41 -0700146 radius_macs = get_radius_macs(len(port_map['radius_ports']))
A R Karthickefcf1ab2017-09-08 18:24:16 -0700147 radius_networks = get_radius_networks(len(port_map['switch_radius_port_list']))
A R Karthick1555c7c2017-09-07 14:59:41 -0700148 radius_intf_index = 0
A R Karthickefcf1ab2017-09-08 18:24:16 -0700149 index = 0
A R Karthick1555c7c2017-09-07 14:59:41 -0700150 for host_intf, ports in port_map['switch_radius_port_list']:
A R Karthickefcf1ab2017-09-08 18:24:16 -0700151 prefix, subnet, _ = radius_networks[index]
152 mask = subnet.split('/')[-1]
153 index += 1
A R Karthick1555c7c2017-09-07 14:59:41 -0700154 for port in ports:
155 guest_if = 'eth{}'.format(radius_intf_index + 2)
156 port_index = port_map[port]
157 local_if = 'r{}'.format(port_index)
A R Karthickefcf1ab2017-09-08 18:24:16 -0700158 guest_ip = '{}.{}/{}'.format(prefix, port_index, mask)
A R Karthick1555c7c2017-09-07 14:59:41 -0700159 mac = radius_macs[radius_intf_index]
160 radius_intf_index += 1
161 pipework_cmd = 'pipework {0} -i {1} -l {2} {3} {4} {5}'.format(host_intf, guest_if,
162 local_if, Radius.NAME,
163 guest_ip, mac)
164 print('Configuring Radius port %s on OVS bridge %s' %(guest_if, host_intf))
165 print('Running pipework command: %s' %(pipework_cmd))
166 res = os.system(pipework_cmd)
167
168 def restart_radius(self, kwargs):
169 print('Restarting RADIUS Server')
170 self.__restart_radius(**kwargs)
A R Karthick81acbff2016-06-17 14:45:16 -0700171 return 'DONE'
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700172
A R Karthicke99ab5c2016-09-30 13:59:57 -0700173 def shutdown(self):
174 print('Shutting down cord test server')
175 os.kill(0, signal.SIGKILL)
176 return 'DONE'
177
A R Karthick1878c4f2016-11-29 09:19:50 -0800178def find_files_by_path(*paths):
179 wanted = []
180 for p in paths:
181 try:
182 fd = os.open(p, os.O_RDONLY)
183 wanted.append(os.fstat(fd)[1:3])
184 finally:
185 os.close(fd)
186
187 def fd_wanted(fd):
188 try:
189 return os.fstat(fd)[1:3] in wanted
190 except OSError:
191 return False
192
193 max_fd = getrlimit(RLIMIT_NOFILE)[1]
194 return [ fd for fd in xrange(max_fd) if fd_wanted(fd) ]
195
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700196@nottest
A R Karthickbd82f362016-11-10 15:08:52 -0800197def cord_test_server_start(daemonize = True,
198 cord_test_host = CORD_TEST_HOST,
199 cord_test_port = CORD_TEST_PORT,
200 onos_cord = None,
201 foreground=False):
A R Karthick81acbff2016-06-17 14:45:16 -0700202 server = SimpleXMLRPCServer( (cord_test_host, cord_test_port) )
203 server.register_instance(CordTestServer())
A R Karthickbd9b8a32016-07-21 09:56:45 -0700204 CordTestServer.onos_cord = onos_cord
A R Karthick81acbff2016-06-17 14:45:16 -0700205 if daemonize is True:
A R Karthick1878c4f2016-11-29 09:19:50 -0800206 ##before daemonizing, preserve urandom needed by paramiko
207 preserve_list = find_files_by_path('/dev/urandom')
208 preserve_list.append(server)
209 d = daemon.DaemonContext(files_preserve = preserve_list,
A R Karthick81acbff2016-06-17 14:45:16 -0700210 detach_process = True)
211 with d:
212 reinitContainerClients()
213 server.serve_forever()
214 else:
A R Karthickbd82f362016-11-10 15:08:52 -0800215 if foreground:
216 try:
217 server.serve_forever()
218 except KeyboardInterrupt:
219 return server
220 else:
221 task = threading.Thread(target = server.serve_forever)
222 ##terminate when main thread exits
223 task.daemon = True
224 task.start()
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700225 return server
226
227@nottest
228def cord_test_server_stop(server):
229 server.shutdown()
230 server.server_close()
231
232@nottest
A R Karthick81acbff2016-06-17 14:45:16 -0700233def get_cord_test_loc():
234 host = os.getenv('CORD_TEST_HOST', CORD_TEST_HOST)
235 port = int(os.getenv('CORD_TEST_PORT', CORD_TEST_PORT))
236 return host, port
237
238def rpc_server_instance():
239 '''Stateless'''
240 host, port = get_cord_test_loc()
241 rpc_server = 'http://{}:{}'.format(host, port)
242 return xmlrpclib.Server(rpc_server, allow_none = True)
243
244@nottest
245def __cord_test_onos_restart(**kwargs):
246 return rpc_server_instance().restart_onos(kwargs)
247
248@nottest
A R Karthickde6b9dc2016-11-29 17:46:16 -0800249def cord_test_onos_restart(node = None, config = None, timeout = 10):
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700250 '''Send ONOS restart to server'''
A R Karthick6cc8b812016-12-09 10:24:40 -0800251 for i in range(3):
252 try:
253 data = __cord_test_onos_restart(node = node, config = config, timeout = timeout)
254 if data == 'DONE':
255 return True
256 except:
257 time.sleep(2)
258
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700259 return False
260
261@nottest
A.R Karthick1700e0e2016-10-06 18:16:57 -0700262def __cord_test_onos_shutdown(**kwargs):
263 return rpc_server_instance().shutdown_onos(kwargs)
264
265@nottest
266def cord_test_onos_shutdown(node = None):
267 data = __cord_test_onos_shutdown(node = node)
268 if data == 'DONE':
269 return True
270 return False
271
272@nottest
A.R Karthick2560f042016-11-30 14:38:52 -0800273def __cord_test_restart_cluster(**kwargs):
274 return rpc_server_instance().restart_cluster(kwargs)
275
276@nottest
277def cord_test_restart_cluster(config = None, timeout = 10, setup = False):
A R Karthick6cc8b812016-12-09 10:24:40 -0800278 for i in range(3):
279 try:
280 data = __cord_test_restart_cluster(config = config, timeout = timeout, setup = setup)
281 if data == 'DONE':
282 return True
283 except:
284 time.sleep(2)
285
A.R Karthick2560f042016-11-30 14:38:52 -0800286 return False
287
288@nottest
A R Karthicke2c24bd2016-10-07 14:51:38 -0700289def __cord_test_onos_add_cluster(**kwargs):
290 return rpc_server_instance().add_cluster_onos(kwargs)
291
292@nottest
293def cord_test_onos_add_cluster(count = 1, config = None):
294 data = __cord_test_onos_add_cluster(count = count, config = config)
295 if data == 'DONE':
296 return True
297 return False
298
299@nottest
A R Karthick81acbff2016-06-17 14:45:16 -0700300def __cord_test_quagga_restart(**kwargs):
301 return rpc_server_instance().restart_quagga(kwargs)
302
303@nottest
A R Karthick1555c7c2017-09-07 14:59:41 -0700304def __cord_test_radius_restart(**kwargs):
305 return rpc_server_instance().restart_radius(kwargs)
306
307@nottest
A R Karthick81acbff2016-06-17 14:45:16 -0700308def cord_test_quagga_restart(config = None, boot_delay = 30):
Chetan Gaonker6cf6e472016-04-26 14:41:51 -0700309 '''Send QUAGGA restart to server'''
A R Karthick81acbff2016-06-17 14:45:16 -0700310 data = __cord_test_quagga_restart(config = config, boot_delay = boot_delay)
311 if data == 'DONE':
312 return True
313 return False
314
315@nottest
A R Karthickc3d80e22016-06-22 17:51:24 -0700316def __cord_test_quagga_shell(**kwargs):
317 return rpc_server_instance().run_shell_quagga(kwargs)
318
319@nottest
320def cord_test_quagga_shell(cmd = None):
321 '''Send QUAGGA shell cmd to server'''
322 return __cord_test_quagga_shell(cmd = cmd)
323
324@nottest
A R Karthicka013a272016-08-16 16:40:19 -0700325def __cord_test_shell(**kwargs):
326 return rpc_server_instance().run_shell(kwargs)
327
328@nottest
329def cord_test_shell(cmd = None):
330 '''Send shell cmd to run remotely'''
331 return __cord_test_shell(cmd = cmd)
332
333@nottest
A R Karthick81acbff2016-06-17 14:45:16 -0700334def cord_test_quagga_stop():
335 data = rpc_server_instance().stop_quagga()
Chetan Gaonker3533faa2016-04-25 17:50:14 -0700336 if data == 'DONE':
337 return True
338 return False
Chetan Gaonker7f4bf742016-05-04 15:56:08 -0700339
340@nottest
A R Karthick1555c7c2017-09-07 14:59:41 -0700341def cord_test_radius_restart(olt_conf_file = ''):
Chetan Gaonker7f4bf742016-05-04 15:56:08 -0700342 '''Send Radius server restart to server'''
A R Karthick1555c7c2017-09-07 14:59:41 -0700343 if not olt_conf_file:
344 olt_conf_file = os.getenv('OLT_CONFIG')
345 olt_conf_file = os.path.basename(olt_conf_file)
346 data = __cord_test_radius_restart(olt_conf_file = olt_conf_file)
Chetan Gaonker7f4bf742016-05-04 15:56:08 -0700347 if data == 'DONE':
348 return True
349 return False
A R Karthicke99ab5c2016-09-30 13:59:57 -0700350
351@nottest
352def cord_test_server_shutdown(host, port):
353 '''Shutdown the cord test server'''
354 rpc_server = 'http://{}:{}'.format(host, port)
355 try:
356 xmlrpclib.Server(rpc_server, allow_none = True).shutdown()
357 except: pass
358
359 return True