blob: 4551cf45a5e0104e8e252fe8df5409e9ba860a93 [file] [log] [blame]
John DeNisco68b0ee32017-09-27 16:35:23 -04001# Copyright (c) 2016 Cisco and/or its affiliates.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at:
5#
6# http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14"""VPP util library"""
15import logging
16import re
17import subprocess
18import platform
19
20from collections import Counter
21
22# VPP_VERSION = '1707'
23VPP_VERSION = '1710'
24
25
26class VPPUtil(object):
27 """General class for any VPP related methods/functions."""
28
29 @staticmethod
30 def exec_command(cmd, timeout=None):
31 """Execute a command on the local node.
32
33 :param cmd: Command to run locally.
34 :param timeout: Timeout value
35 :type cmd: str
36 :type timeout: int
37 :return return_code, stdout, stderr
38 :rtype: tuple(int, str, str)
39 """
40
41 logging.info(" Local Command: {}".format(cmd))
42 out = ''
43 err = ''
44 prc = subprocess.Popen(cmd, shell=True, bufsize=1,
45 stdin=subprocess.PIPE,
46 stdout=subprocess.PIPE,
47 stderr=subprocess.PIPE)
48
49 with prc.stdout:
50 for line in iter(prc.stdout.readline, b''):
51 logging.info(" {}".format(line.strip('\n')))
52 out += line
53
54 with prc.stderr:
55 for line in iter(prc.stderr.readline, b''):
56 logging.warn(" {}".format(line.strip('\n')))
57 err += line
58
59 ret = prc.wait()
60
61 return ret, out, err
62
63 def _autoconfig_backup_file(self, filename):
64 """
65 Create a backup file.
66
67 :param filename: The file to backup
68 :type filename: str
69 """
70
71 # Does a copy of the file exist, if not create one
72 ofile = filename + '.orig'
73 (ret, stdout, stderr) = self.exec_command('ls {}'.format(ofile))
74 if ret != 0:
75 logging.debug(stderr)
76 if stdout.strip('\n') != ofile:
77 cmd = 'sudo cp {} {}'.format(filename, ofile)
78 (ret, stdout, stderr) = self.exec_command(cmd)
79 if ret != 0:
80 logging.debug(stderr)
81
82 def _install_vpp_pkg_ubuntu(self, node, pkg):
83 """
84 Install the VPP packages
85
86 :param node: Node dictionary
87 :param pkg: The vpp packages
88 :type node: dict
89 :type pkg: string
90 """
91
92 cmd = 'apt-get -y install {}'.format(pkg)
93 (ret, stdout, stderr) = self.exec_command(cmd)
94 if ret != 0:
95 raise RuntimeError('{} failed on node {} {} {}'.format(
96 cmd, node['host'], stdout, stderr))
97
98 def _install_vpp_pkg_centos(self, node, pkg):
99 """
100 Install the VPP packages
101
102 :param node: Node dictionary
103 :param pkg: The vpp packages
104 :type node: dict
105 :type pkg: string
106 """
107
108 cmd = 'yum -y install {}'.format(pkg)
109 (ret, stdout, stderr) = self.exec_command(cmd)
110 if ret != 0:
111 raise RuntimeError('{} failed on node {} {} {}'.format(
112 cmd, node['host'], stdout, stderr))
113
114 def _install_vpp_ubuntu(self, node, fdio_release=VPP_VERSION,
115 ubuntu_version='xenial'):
116 """
117 Install the VPP packages
118
119 :param node: Node dictionary with cpuinfo.
120 :param fdio_release: VPP release number
121 :param ubuntu_version: Ubuntu Version
122 :type node: dict
123 :type fdio_release: string
124 :type ubuntu_version: string
125 """
126
127 # Modify the sources list
128 sfile = '/etc/apt/sources.list.d/99fd.io.list'
129
130 # Backup the sources list
131 self._autoconfig_backup_file(sfile)
132
133 # Remove the current file
134 cmd = 'rm {}'.format(sfile)
135 (ret, stdout, stderr) = self.exec_command(cmd)
136 if ret != 0:
137 logging.debug('{} failed on node {} {}'.format(
138 cmd,
139 node['host'],
140 stderr))
141
142 reps = 'deb [trusted=yes] https://nexus.fd.io/content/'
John DeNiscoc6b2a202017-11-01 12:37:47 -0400143 # When using a stable branch
144 # reps += 'repositories/fd.io.stable.{}.ubuntu.{}.main/ ./\n' \
145 # .format(fdio_release, ubuntu_version)
146 reps += 'repositories/fd.io.ubuntu.{}.main/ ./\n' \
147 .format(ubuntu_version)
John DeNisco68b0ee32017-09-27 16:35:23 -0400148
149 cmd = 'echo "{0}" | sudo tee {1}'.format(reps, sfile)
150 (ret, stdout, stderr) = self.exec_command(cmd)
151 if ret != 0:
152 raise RuntimeError('{} failed on node {} {}'.format(
153 cmd,
154 node['host'],
155 stderr))
156
157 # Install the package
158 cmd = 'apt-get -y update'
159 (ret, stdout, stderr) = self.exec_command(cmd)
160 if ret != 0:
161 raise RuntimeError('{} apt-get update failed on node {} {}'.format(
162 cmd,
163 node['host'],
164 stderr))
165
166 self._install_vpp_pkg_ubuntu(node, 'vpp-lib')
167 self._install_vpp_pkg_ubuntu(node, 'vpp')
168 self._install_vpp_pkg_ubuntu(node, 'vpp-plugins')
169 self._install_vpp_pkg_ubuntu(node, 'vpp-dpdk-dkms')
170 self._install_vpp_pkg_ubuntu(node, 'vpp-dpdk-dev')
171 self._install_vpp_pkg_ubuntu(node, 'vpp-api-python')
172 self._install_vpp_pkg_ubuntu(node, 'vpp-api-java')
173 self._install_vpp_pkg_ubuntu(node, 'vpp-api-lua')
174 self._install_vpp_pkg_ubuntu(node, 'vpp-dev')
175 self._install_vpp_pkg_ubuntu(node, 'vpp-dbg')
176
177 def _install_vpp_centos(self, node, fdio_release=VPP_VERSION,
178 centos_version='centos7'):
179 """
180 Install the VPP packages
181
182 :param node: Node dictionary with cpuinfo.
183 :param fdio_release: VPP release number
184 :param centos_version: Ubuntu Version
185 :type node: dict
186 :type fdio_release: string
187 :type centos_version: string
188 """
189
190 # Modify the sources list
191 sfile = '/etc/yum.repos.d/fdio-release.repo'
192
193 # Backup the sources list
194 self._autoconfig_backup_file(sfile)
195
196 # Remove the current file
197 cmd = 'rm {}'.format(sfile)
198 (ret, stdout, stderr) = self.exec_command(cmd)
199 if ret != 0:
200 logging.debug('{} failed on node {} {}'.format(
201 cmd,
202 node['host'],
203 stderr))
204
205 reps = '[fdio-stable-{}]\n'.format(fdio_release)
206 reps += 'name=fd.io stable/{} branch latest merge\n'.format(fdio_release)
John DeNiscoc6b2a202017-11-01 12:37:47 -0400207 # When using stable
208 # reps += 'baseurl=https://nexus.fd.io/content/repositories/fd.io.stable.{}.{}/\n'.\
209 # format(fdio_release, centos_version)
210 reps += 'baseurl=https://nexus.fd.io/content/repositories/fd.io.{}/\n'.\
211 format(centos_version)
John DeNisco68b0ee32017-09-27 16:35:23 -0400212 reps += 'enabled=1\n'
213 reps += 'gpgcheck=0'
214
215 cmd = 'echo "{0}" | sudo tee {1}'.format(reps, sfile)
216 (ret, stdout, stderr) = self.exec_command(cmd)
217 if ret != 0:
218 raise RuntimeError('{} failed on node {} {}'.format(
219 cmd,
220 node['host'],
221 stderr))
222
223 # Install the packages
224
225 self._install_vpp_pkg_centos(node, 'vpp-lib')
226 self._install_vpp_pkg_centos(node, 'vpp')
227 self._install_vpp_pkg_centos(node, 'vpp-plugins')
228 # jadfix Check with Ole
229 # self._install_vpp_pkg_centos(node, 'vpp-dpdk-devel')
230 self._install_vpp_pkg_centos(node, 'vpp-api-python')
231 self._install_vpp_pkg_centos(node, 'vpp-api-java')
232 self._install_vpp_pkg_centos(node, 'vpp-api-lua')
233 self._install_vpp_pkg_centos(node, 'vpp-devel')
234
235 def install_vpp(self, node):
236 """
237 Install the VPP packages
238
239 :param node: Node dictionary with cpuinfo.
240 :type node: dict
241 """
242 distro = self.get_linux_distro()
243 if distro[0] == 'Ubuntu':
244 self._install_vpp_ubuntu(node)
245 elif distro[0] == 'CentOS Linux':
246 logging.info("Install CentOS")
247 self._install_vpp_centos(node)
248 else:
249 return
250
251 def _uninstall_vpp_pkg_ubuntu(self, node, pkg):
252 """
253 Uninstall the VPP packages
254
255 :param node: Node dictionary
256 :param pkg: The vpp packages
257 :type node: dict
258 :type pkg: string
259 """
260 cmd = 'dpkg --purge {}'.format(pkg)
261 (ret, stdout, stderr) = self.exec_command(cmd)
262 if ret != 0:
263 raise RuntimeError('{} failed on node {} {} {}'.format(
264 cmd, node['host'], stdout, stderr))
265
266 def _uninstall_vpp_pkg_centos(self, node, pkg):
267 """
268 Uninstall the VPP packages
269
270 :param node: Node dictionary
271 :param pkg: The vpp packages
272 :type node: dict
273 :type pkg: string
274 """
275 cmd = 'yum -y remove {}'.format(pkg)
276 (ret, stdout, stderr) = self.exec_command(cmd)
277 if ret != 0:
278 raise RuntimeError('{} failed on node {} {} {}'.format(
279 cmd, node['host'], stdout, stderr))
280
281 def _uninstall_vpp_ubuntu(self, node):
282 """
283 Uninstall the VPP packages
284
285 :param node: Node dictionary with cpuinfo.
286 :type node: dict
287 """
288 pkgs = self.get_installed_vpp_pkgs()
289
290 if len(pkgs) > 0:
291 if 'version' in pkgs[0]:
292 logging.info("Uninstall Ubuntu Packages")
293 self._uninstall_vpp_pkg_ubuntu(node, 'vpp-api-python')
294 self._uninstall_vpp_pkg_ubuntu(node, 'vpp-api-java')
295 self._uninstall_vpp_pkg_ubuntu(node, 'vpp-api-lua')
296 self._uninstall_vpp_pkg_ubuntu(node, 'vpp-plugins')
297 self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dpdk-dev')
298 self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dpdk-dkms')
299 self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dev')
300 self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dbg')
301 self._uninstall_vpp_pkg_ubuntu(node, 'vpp')
302 self._uninstall_vpp_pkg_ubuntu(node, 'vpp-lib')
303 else:
304 logging.info("Uninstall locally installed Ubuntu Packages")
305 for pkg in pkgs:
306 self._uninstall_vpp_pkg_ubuntu(node, pkg['name'])
307 else:
308 logging.error("There are no Ubuntu packages installed")
309
310 def _uninstall_vpp_centos(self, node):
311 """
312 Uninstall the VPP packages
313
314 :param node: Node dictionary with cpuinfo.
315 :type node: dict
316 """
317
318 pkgs = self.get_installed_vpp_pkgs()
319
320 if len(pkgs) > 0:
321 if 'version' in pkgs[0]:
322 logging.info("Uninstall CentOS Packages")
323 self._uninstall_vpp_pkg_centos(node, 'vpp-api-python')
324 self._uninstall_vpp_pkg_centos(node, 'vpp-api-java')
325 self._uninstall_vpp_pkg_centos(node, 'vpp-api-lua')
326 self._uninstall_vpp_pkg_centos(node, 'vpp-plugins')
327 self._uninstall_vpp_pkg_centos(node, 'vpp-dpdk-devel')
328 self._uninstall_vpp_pkg_centos(node, 'vpp-devel')
329 self._uninstall_vpp_pkg_centos(node, 'vpp')
330 self._uninstall_vpp_pkg_centos(node, 'vpp-lib')
331 else:
332 logging.info("Uninstall locally installed CentOS Packages")
333 for pkg in pkgs:
334 self._uninstall_vpp_pkg_centos(node, pkg['name'])
335 else:
336 logging.error("There are no CentOS packages installed")
337
338 def uninstall_vpp(self, node):
339 """
340 Uninstall the VPP packages
341
342 :param node: Node dictionary with cpuinfo.
343 :type node: dict
344 """
John DeNiscoc6b2a202017-11-01 12:37:47 -0400345
346 # First stop VPP
347 self.stop(node)
348
John DeNisco68b0ee32017-09-27 16:35:23 -0400349 distro = self.get_linux_distro()
350 if distro[0] == 'Ubuntu':
351 self._uninstall_vpp_ubuntu(node)
352 elif distro[0] == 'CentOS Linux':
353 logging.info("Uninstall CentOS")
354 self._uninstall_vpp_centos(node)
355 else:
356 return
357
358 def show_vpp_settings(self, *additional_cmds):
359 """
360 Print default VPP settings. In case others are needed, can be
361 accepted as next parameters (each setting one parameter), preferably
362 in form of a string.
363
364 :param additional_cmds: Additional commands that the vpp should print
365 settings for.
366 :type additional_cmds: tuple
367 """
368 def_setting_tb_displayed = {
369 'IPv6 FIB': 'ip6 fib',
370 'IPv4 FIB': 'ip fib',
371 'Interface IP': 'int addr',
372 'Interfaces': 'int',
373 'ARP': 'ip arp',
374 'Errors': 'err'
375 }
376
377 if additional_cmds:
378 for cmd in additional_cmds:
379 def_setting_tb_displayed['Custom Setting: {}'.format(cmd)] \
380 = cmd
381
382 for _, value in def_setting_tb_displayed.items():
383 self.exec_command('vppctl sh {}'.format(value))
384
385 @staticmethod
John DeNiscoc6b2a202017-11-01 12:37:47 -0400386 def get_vms(node):
387 """
388 Get a list of VMs that are connected to VPP interfaces
389
390 :param node: VPP node.
391 :type node: dict
392 :returns: Dictionary containing a list of VMs and the interfaces that are connected to VPP
393 :rtype: dictionary
394 """
395
396 vmdict = {}
397
398 print "Need to implement get vms"
399
400 return vmdict
401
402 @staticmethod
John DeNiscoa3db0782017-10-17 11:07:22 -0400403 def get_int_ip(node):
404 """
405 Get the VPP interfaces and IP addresses
406
407 :param node: VPP node.
408 :type node: dict
409 :returns: Dictionary containing VPP interfaces and IP addresses
410 :rtype: dictionary
411 """
412 interfaces = {}
413 cmd = 'vppctl show int addr'
414 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
415 if ret != 0:
416 return interfaces
417
418 lines = stdout.split('\n')
419 if len(lines[0]) is not 0:
420 if lines[0].split(' ')[0] == 'FileNotFoundError':
421 return interfaces
422
John DeNiscoc6b2a202017-11-01 12:37:47 -0400423 name = ''
John DeNiscoa3db0782017-10-17 11:07:22 -0400424 for line in lines:
425 if len(line) is 0:
426 continue
427
428 # If the first character is not whitespace
429 # create a new interface
430 if len(re.findall(r'\s', line[0])) is 0:
431 spl = line.split()
432 name = spl[0]
433 if name == 'local0':
434 continue
435 interfaces[name] = {}
436 interfaces[name]['state'] = spl[1].lstrip('(').rstrip('):\r')
437 else:
438 interfaces[name]['address'] = line.lstrip(' ').rstrip('\r')
439
440 return interfaces
441
442 @staticmethod
John DeNisco68b0ee32017-09-27 16:35:23 -0400443 def get_hardware(node):
444 """
445 Get the VPP hardware information and return it in a
446 dictionary
447
448 :param node: VPP node.
449 :type node: dict
John DeNiscoa3db0782017-10-17 11:07:22 -0400450 :returns: Dictionary containing VPP hardware information
John DeNisco68b0ee32017-09-27 16:35:23 -0400451 :rtype: dictionary
452 """
453
454 interfaces = {}
455 cmd = 'vppctl show hard'
456 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
457 if ret != 0:
458 return interfaces
459
460 lines = stdout.split('\n')
461 if len(lines[0]) is not 0:
462 if lines[0].split(' ')[0] == 'FileNotFoundError':
463 return interfaces
464
465 for line in lines:
466 if len(line) is 0:
467 continue
468
469 # If the first character is not whitespace
470 # create a new interface
471 if len(re.findall(r'\s', line[0])) is 0:
472 spl = line.split()
473 name = spl[0]
474 interfaces[name] = {}
475 interfaces[name]['index'] = spl[1]
476 interfaces[name]['state'] = spl[2]
477
478 # Ethernet address
479 rfall = re.findall(r'Ethernet address', line)
480 if rfall:
481 spl = line.split()
482 interfaces[name]['mac'] = spl[2]
483
484 # Carrier
485 rfall = re.findall(r'carrier', line)
486 if rfall:
487 spl = line.split('carrier ')
488 interfaces[name]['carrier'] = spl[1]
489
490 # Socket
491 rfall = re.findall(r'cpu socket', line)
492 if rfall:
493 spl = line.split('cpu socket ')
494 interfaces[name]['cpu socket'] = spl[1]
495
496 # Queues and Descriptors
497 rfall = re.findall(r'rx queues', line)
498 if rfall:
499 spl = line.split(',')
500 interfaces[name]['rx queues'] = spl[0].lstrip(' ').split(' ')[2]
501 interfaces[name]['rx descs'] = spl[1].split(' ')[3]
502 interfaces[name]['tx queues'] = spl[2].split(' ')[3]
503 interfaces[name]['tx descs'] = spl[3].split(' ')[3]
504
505 return interfaces
506
507 def _get_installed_vpp_pkgs_ubuntu(self):
508 """
509 Get the VPP hardware information and return it in a
510 dictionary
511
512 :returns: List of the packages installed
513 :rtype: list
514 """
515
516 pkgs = []
517 cmd = 'dpkg -l | grep vpp'
518 (ret, stdout, stderr) = self.exec_command(cmd)
519 if ret != 0:
520 return pkgs
521
522 lines = stdout.split('\n')
523 for line in lines:
524 items = line.split()
525 if len(items) < 2:
526 continue
527 pkg = {'name': items[1], 'version': items[2]}
528 pkgs.append(pkg)
529
530 return pkgs
531
532 def _get_installed_vpp_pkgs_centos(self):
533 """
534 Get the VPP hardware information and return it in a
535 dictionary
536
537 :returns: List of the packages installed
538 :rtype: list
539 """
540
541 pkgs = []
542 cmd = 'rpm -qa | grep vpp'
543 (ret, stdout, stderr) = self.exec_command(cmd)
544 if ret != 0:
545 return pkgs
546
547 lines = stdout.split('\n')
548 for line in lines:
549 if len(line) == 0:
550 continue
551
552 items = line.split()
553 if len(items) < 2:
554 pkg = {'name': items[0]}
555 else:
556 pkg = {'name': items[1], 'version': items[2]}
557
558 pkgs.append(pkg)
559
560 return pkgs
561
562 def get_installed_vpp_pkgs(self):
563 """
564 Get the VPP hardware information and return it in a
565 dictionary
566
567 :returns: List of the packages installed
568 :rtype: list
569 """
570
571 distro = self.get_linux_distro()
572 if distro[0] == 'Ubuntu':
573 pkgs = self._get_installed_vpp_pkgs_ubuntu()
574 elif distro[0] == 'CentOS Linux':
575 pkgs = self._get_installed_vpp_pkgs_centos()
576 else:
577 return []
578
579 return pkgs
580
581 @staticmethod
582 def get_interfaces_numa_node(node, *iface_keys):
583 """Get numa node on which are located most of the interfaces.
584
585 Return numa node with highest count of interfaces provided as arguments.
586 Return 0 if the interface does not have numa_node information available.
587 If all interfaces have unknown location (-1), then return 0.
588 If most of interfaces have unknown location (-1), but there are
589 some interfaces with known location, then return the second most
590 location of the provided interfaces.
591
592 :param node: Node from DICT__nodes.
593 :param iface_keys: Interface keys for lookup.
594 :type node: dict
595 :type iface_keys: strings
596 """
597 numa_list = []
598 for if_key in iface_keys:
599 try:
600 numa_list.append(node['interfaces'][if_key].get('numa_node'))
601 except KeyError:
602 pass
603
604 numa_cnt_mc = Counter(numa_list).most_common()
605 numa_cnt_mc_len = len(numa_cnt_mc)
606 if numa_cnt_mc_len > 0 and numa_cnt_mc[0][0] != -1:
607 return numa_cnt_mc[0][0]
608 elif numa_cnt_mc_len > 1 and numa_cnt_mc[0][0] == -1:
609 return numa_cnt_mc[1][0]
610
611 return 0
612
613 @staticmethod
John DeNiscoc6b2a202017-11-01 12:37:47 -0400614 def restart(node):
615 """
616
617 Starts vpp for a given node
618
619 :param node: VPP node.
620 :type node: dict
621 """
622
623 cmd = 'service vpp restart'
624 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
625 if ret != 0:
626 raise RuntimeError('{} failed on node {} {} {}'.
627 format(cmd, node['host'],
628 stdout, stderr))
629
630 @staticmethod
John DeNisco68b0ee32017-09-27 16:35:23 -0400631 def start(node):
632 """
633
634 Starts vpp for a given node
635
636 :param node: VPP node.
637 :type node: dict
638 """
639
640 cmd = 'service vpp start'
641 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
642 if ret != 0:
643 raise RuntimeError('{} failed on node {} {} {}'.
644 format(cmd, node['host'],
645 stdout, stderr))
646
647 @staticmethod
648 def stop(node):
649 """
650
651 Stops vpp for a given node
652
653 :param node: VPP node.
654 :type node: dict
655 """
656
657 cmd = 'service vpp stop'
658 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
659 if ret != 0:
660 raise RuntimeError('{} failed on node {} {} {}'.
661 format(cmd, node['host'],
662 stdout, stderr))
663
664 @staticmethod
665 def status(node):
666 """
667
668 Gets VPP status
669
670 :param: node
671 :type node: dict
672 :returns: status, errors
673 :rtype: tuple(str, list)
674 """
675 errors = []
676 vutil = VPPUtil()
677 pkgs = vutil.get_installed_vpp_pkgs()
678 if len(pkgs) == 0:
679 return "Not Installed", errors
680
681 cmd = 'service vpp status'
682 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
683
684 # Get the active status
685 state = re.findall(r'Active:[\w (\)]+', stdout)[0].split(' ')
686 if len(state) > 2:
687 statestr = "{} {}".format(state[1], state[2])
688 else:
689 statestr = "Invalid"
690
691 # For now we won't look for DPDK errors
692 # lines = stdout.split('\n')
693 # for line in lines:
694 # if 'EAL' in line or \
695 # 'FAILURE' in line or \
696 # 'failed' in line or \
697 # 'Failed' in line:
698 # errors.append(line.lstrip(' '))
699
700 return statestr, errors
701
702 @staticmethod
703 def get_linux_distro():
704 """
705 Get the linux distribution and check if it is supported
706
707 :returns: linux distro, None if the distro is not supported
708 :rtype: list
709 """
710
711 distro = platform.linux_distribution()
712 if distro[0] == 'Ubuntu' or \
713 distro[0] == 'CentOS Linux' or \
714 distro[:26] == 'Linux Distribution Red Hat':
715 return distro
716 else:
717 raise RuntimeError('Linux Distribution {} is not supported'.format(distro[0]))
718
719 @staticmethod
720 def version():
721 """
722
723 Gets VPP Version information
724
725 :returns: version
726 :rtype: dict
727 """
728
729 version = {}
730 cmd = 'vppctl show version verbose'
731 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
732 if ret != 0:
733 return version
734
735 lines = stdout.split('\n')
736 if len(lines[0]) is not 0:
737 if lines[0].split(' ')[0] == 'FileNotFoundError':
738 return version
739
740 for line in lines:
741 if len(line) is 0:
742 continue
743 dct = line.split(':')
744 version[dct[0]] = dct[1].lstrip(' ')
745
746 return version
John DeNiscoc6b2a202017-11-01 12:37:47 -0400747
748 @staticmethod
749 def show_bridge(node):
750 """
751 Shows the current bridge configuration
752
753 :param node: VPP node.
754 :type node: dict
755 """
756
757 cmd = 'vppctl show bridge'
758 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
759 if ret != 0:
760 raise RuntimeError('{} failed on node {} {} {}'.
761 format(cmd, node['host'],
762 stdout, stderr))
763 lines = stdout.split('\r\n')
764 bridges = []
765 for line in lines:
766 if line == 'no bridge-domains in use':
767 print line
768 return
769 if len(line) == 0:
770 continue
771
772 lspl = line.lstrip(' ').split()
773 if lspl[0] != 'BD-ID':
774 bridges.append(lspl[0])
775
776 for bridge in bridges:
777 cmd = 'vppctl show bridge {} detail'.format(bridge)
778 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
779 if ret != 0:
780 raise RuntimeError('{} failed on node {} {} {}'.
781 format(cmd, node['host'],
782 stdout, stderr))
783 print stdout