X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=extras%2Fvpp_config%2Fvpplib%2FVPPUtil.py;h=a1c64a3e15dee590bcb9117150ba27958a734959;hb=b0b9dadc5c57b96ed43427ca78430e52fed9196e;hp=350b7759a0389729c5dedee041bf54fc028a96e7;hpb=68b0ee3a38e3a86f0389d8cc695915df190c3dfb;p=vpp.git diff --git a/extras/vpp_config/vpplib/VPPUtil.py b/extras/vpp_config/vpplib/VPPUtil.py index 350b7759a03..a1c64a3e15d 100644 --- a/extras/vpp_config/vpplib/VPPUtil.py +++ b/extras/vpp_config/vpplib/VPPUtil.py @@ -16,12 +16,10 @@ import logging import re import subprocess import platform +import requests from collections import Counter -# VPP_VERSION = '1707' -VPP_VERSION = '1710' - class VPPUtil(object): """General class for any VPP related methods/functions.""" @@ -111,16 +109,15 @@ class VPPUtil(object): raise RuntimeError('{} failed on node {} {} {}'.format( cmd, node['host'], stdout, stderr)) - def _install_vpp_ubuntu(self, node, fdio_release=VPP_VERSION, - ubuntu_version='xenial'): + def _install_vpp_ubuntu(self, node, branch, ubuntu_version='xenial'): """ Install the VPP packages :param node: Node dictionary with cpuinfo. - :param fdio_release: VPP release number + :param branch: VPP branch :param ubuntu_version: Ubuntu Version :type node: dict - :type fdio_release: string + :type branch: string :type ubuntu_version: string """ @@ -130,20 +127,16 @@ class VPPUtil(object): # Backup the sources list self._autoconfig_backup_file(sfile) - # Remove the current file - cmd = 'rm {}'.format(sfile) - (ret, stdout, stderr) = self.exec_command(cmd) - if ret != 0: - logging.debug('{} failed on node {} {}'.format( - cmd, - node['host'], - stderr)) + reps = 'deb [trusted=yes] https://packagecloud.io/fdio/' + reps += '{}/ubuntu {} main ./\n'.format(branch, ubuntu_version) - reps = 'deb [trusted=yes] https://nexus.fd.io/content/' - reps += 'repositories/fd.io.stable.{}.ubuntu.{}.main/ ./\n' \ - .format(fdio_release, ubuntu_version) + with open(sfile, 'w') as sfd: + sfd.write(reps) + sfd.close() - cmd = 'echo "{0}" | sudo tee {1}'.format(reps, sfile) + # Add the key + key = requests.get('https://packagecloud.io/fdio/{}/gpgkey'.format(branch)) + cmd = 'echo "{}" | apt-key add -'.format(key.content) (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: raise RuntimeError('{} failed on node {} {}'.format( @@ -163,27 +156,39 @@ class VPPUtil(object): self._install_vpp_pkg_ubuntu(node, 'vpp-lib') self._install_vpp_pkg_ubuntu(node, 'vpp') self._install_vpp_pkg_ubuntu(node, 'vpp-plugins') - self._install_vpp_pkg_ubuntu(node, 'vpp-dpdk-dkms') - self._install_vpp_pkg_ubuntu(node, 'vpp-dpdk-dev') self._install_vpp_pkg_ubuntu(node, 'vpp-api-python') self._install_vpp_pkg_ubuntu(node, 'vpp-api-java') self._install_vpp_pkg_ubuntu(node, 'vpp-api-lua') self._install_vpp_pkg_ubuntu(node, 'vpp-dev') self._install_vpp_pkg_ubuntu(node, 'vpp-dbg') - def _install_vpp_centos(self, node, fdio_release=VPP_VERSION, - centos_version='centos7'): + def _install_vpp_centos(self, node, branch): """ Install the VPP packages :param node: Node dictionary with cpuinfo. - :param fdio_release: VPP release number - :param centos_version: Ubuntu Version + :param branch: The branch name release or master :type node: dict - :type fdio_release: string - :type centos_version: string + :type branch: string """ + # Be sure the correct system packages are installed + cmd = 'yum -y update' + (ret, stdout, stderr) = self.exec_command(cmd) + if ret != 0: + logging.debug('{} failed on node {} {}'.format( + cmd, + node['host'], + stderr)) + + cmd = 'yum -y install pygpgme yum-utils' + (ret, stdout, stderr) = self.exec_command(cmd) + if ret != 0: + logging.debug('{} failed on node {} {}'.format( + cmd, + node['host'], + stderr)) + # Modify the sources list sfile = '/etc/yum.repos.d/fdio-release.repo' @@ -199,48 +204,83 @@ class VPPUtil(object): node['host'], stderr)) - reps = '[fdio-stable-{}]\n'.format(fdio_release) - reps += 'name=fd.io stable/{} branch latest merge\n'.format(fdio_release) - reps += 'baseurl=https://nexus.fd.io/content/repositories/fd.io.stable.{}.{}/\n'.\ - format(fdio_release, centos_version) + # Get the file contents + reps = '[fdio_{}]\n'.format(branch) + reps += 'name=fdio_{}\n'.format(branch) + reps += 'baseurl=https://packagecloud.io/fdio/{}/el/7/$basearch\n'.format(branch) + reps += 'repo_gpgcheck=1\n' + reps += 'gpgcheck=0\n' + reps += 'enabled=1\n' + reps += 'gpgkey=https://packagecloud.io/fdio/{}/gpgkey\n'.format(branch) + reps += 'sslverify=1\n' + reps += 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt\n' + reps += 'metadata_expire=300\n' + reps += '\n' + reps += '[fdio_{}-source]\n'.format(branch) + reps += 'name=fdio_{}-source\n'.format(branch) + reps += 'baseurl=https://packagecloud.io/fdio/{}/el/7/SRPMS\n'.format(branch) + reps += 'repo_gpgcheck=1\n' + reps += 'gpgcheck=0\n' reps += 'enabled=1\n' - reps += 'gpgcheck=0' + reps += 'gpgkey=https://packagecloud.io/fdio/{}/gpgkey\n'.format(branch) + reps += 'sslverify =1\n' + reps += 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt\n' + reps += 'metadata_expire=300\n' - cmd = 'echo "{0}" | sudo tee {1}'.format(reps, sfile) + with open(sfile, 'w') as sfd: + sfd.write(reps) + sfd.close() + + # Update the fdio repo + cmd = 'yum clean all' (ret, stdout, stderr) = self.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {}'.format( + logging.debug('{} failed on node {} {}'.format( + cmd, + node['host'], + stderr)) + + cmd = "yum -q makecache -y --disablerepo='*' --enablerepo='fdio_{}'".format(branch) + (ret, stdout, stderr) = self.exec_command(cmd) + if ret != 0: + logging.debug('{} failed on node {} {}'.format( cmd, node['host'], stderr)) # Install the packages - + self._install_vpp_pkg_centos(node, 'vpp-selinux-policy') self._install_vpp_pkg_centos(node, 'vpp-lib') self._install_vpp_pkg_centos(node, 'vpp') self._install_vpp_pkg_centos(node, 'vpp-plugins') - # jadfix Check with Ole - # self._install_vpp_pkg_centos(node, 'vpp-dpdk-devel') self._install_vpp_pkg_centos(node, 'vpp-api-python') self._install_vpp_pkg_centos(node, 'vpp-api-java') self._install_vpp_pkg_centos(node, 'vpp-api-lua') self._install_vpp_pkg_centos(node, 'vpp-devel') + self._install_vpp_pkg_centos(node, 'vpp-debuginfo') - def install_vpp(self, node): + def install_vpp(self, node, branch): """ Install the VPP packages :param node: Node dictionary with cpuinfo. + :param branch: The branch name :type node: dict + :type branch: string + """ distro = self.get_linux_distro() + logging.info(" {}".format(distro[0])) if distro[0] == 'Ubuntu': - self._install_vpp_ubuntu(node) + logging.info("Install Ubuntu") + self._install_vpp_ubuntu(node, branch, ubuntu_version=distro[2]) elif distro[0] == 'CentOS Linux': logging.info("Install CentOS") - self._install_vpp_centos(node) + self._install_vpp_centos(node, branch) else: - return + logging.info("Install CentOS (default)") + self._install_vpp_centos(node, branch) + return def _uninstall_vpp_pkg_ubuntu(self, node, pkg): """ @@ -284,14 +324,12 @@ class VPPUtil(object): if len(pkgs) > 0: if 'version' in pkgs[0]: logging.info("Uninstall Ubuntu Packages") + self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dbg') + self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dev') self._uninstall_vpp_pkg_ubuntu(node, 'vpp-api-python') self._uninstall_vpp_pkg_ubuntu(node, 'vpp-api-java') self._uninstall_vpp_pkg_ubuntu(node, 'vpp-api-lua') self._uninstall_vpp_pkg_ubuntu(node, 'vpp-plugins') - self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dpdk-dev') - self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dpdk-dkms') - self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dev') - self._uninstall_vpp_pkg_ubuntu(node, 'vpp-dbg') self._uninstall_vpp_pkg_ubuntu(node, 'vpp') self._uninstall_vpp_pkg_ubuntu(node, 'vpp-lib') else: @@ -314,14 +352,15 @@ class VPPUtil(object): if len(pkgs) > 0: if 'version' in pkgs[0]: logging.info("Uninstall CentOS Packages") + self._install_vpp_pkg_centos(node, 'vpp-debuginfo') + self._uninstall_vpp_pkg_centos(node, 'vpp-devel') self._uninstall_vpp_pkg_centos(node, 'vpp-api-python') self._uninstall_vpp_pkg_centos(node, 'vpp-api-java') self._uninstall_vpp_pkg_centos(node, 'vpp-api-lua') self._uninstall_vpp_pkg_centos(node, 'vpp-plugins') - self._uninstall_vpp_pkg_centos(node, 'vpp-dpdk-devel') - self._uninstall_vpp_pkg_centos(node, 'vpp-devel') self._uninstall_vpp_pkg_centos(node, 'vpp') self._uninstall_vpp_pkg_centos(node, 'vpp-lib') + self._uninstall_vpp_pkg_centos(node, 'vpp-selinux-policy') else: logging.info("Uninstall locally installed CentOS Packages") for pkg in pkgs: @@ -336,13 +375,20 @@ class VPPUtil(object): :param node: Node dictionary with cpuinfo. :type node: dict """ + + # First stop VPP + self.stop(node) + distro = self.get_linux_distro() if distro[0] == 'Ubuntu': + logging.info("Uninstall Ubuntu") self._uninstall_vpp_ubuntu(node) elif distro[0] == 'CentOS Linux': logging.info("Uninstall CentOS") self._uninstall_vpp_centos(node) else: + logging.info("Uninstall CentOS (Default)") + self._uninstall_vpp_centos(node) return def show_vpp_settings(self, *additional_cmds): @@ -372,6 +418,63 @@ class VPPUtil(object): for _, value in def_setting_tb_displayed.items(): self.exec_command('vppctl sh {}'.format(value)) + @staticmethod + def get_vms(node): + """ + Get a list of VMs that are connected to VPP interfaces + + :param node: VPP node. + :type node: dict + :returns: Dictionary containing a list of VMs and the interfaces that are connected to VPP + :rtype: dictionary + """ + + vmdict = {} + + print "Need to implement get vms" + + return vmdict + + @staticmethod + def get_int_ip(node): + """ + Get the VPP interfaces and IP addresses + + :param node: VPP node. + :type node: dict + :returns: Dictionary containing VPP interfaces and IP addresses + :rtype: dictionary + """ + interfaces = {} + cmd = 'vppctl show int addr' + (ret, stdout, stderr) = VPPUtil.exec_command(cmd) + if ret != 0: + return interfaces + + lines = stdout.split('\n') + if len(lines[0]) is not 0: + if lines[0].split(' ')[0] == 'FileNotFoundError': + return interfaces + + name = '' + for line in lines: + if len(line) is 0: + continue + + # If the first character is not whitespace + # create a new interface + if len(re.findall(r'\s', line[0])) is 0: + spl = line.split() + name = spl[0] + if name == 'local0': + continue + interfaces[name] = {} + interfaces[name]['state'] = spl[1].lstrip('(').rstrip('):\r') + else: + interfaces[name]['address'] = line.lstrip(' ').rstrip('\r') + + return interfaces + @staticmethod def get_hardware(node): """ @@ -380,7 +483,7 @@ class VPPUtil(object): :param node: VPP node. :type node: dict - :returns: Dictionary containing improtant VPP information + :returns: Dictionary containing VPP hardware information :rtype: dictionary """ @@ -421,27 +524,35 @@ class VPPUtil(object): interfaces[name]['carrier'] = spl[1] # Socket - rfall = re.findall(r'cpu socket', line) + rfall = re.findall(r'numa \d+', line) if rfall: - spl = line.split('cpu socket ') - interfaces[name]['cpu socket'] = spl[1] + spl = rfall[0].split() + interfaces[name]['numa'] = rfall[0].split()[1] # Queues and Descriptors - rfall = re.findall(r'rx queues', line) + rfall = re.findall(r'rx\: queues \d+', line) + if rfall: + interfaces[name]['rx queues'] = rfall[0].split()[2] + rdesc = re.findall(r'desc \d+', line) + if rdesc: + interfaces[name]['rx descs'] = rdesc[0].split()[1] + + rfall = re.findall(r'tx\: queues \d+', line) if rfall: - spl = line.split(',') - interfaces[name]['rx queues'] = spl[0].lstrip(' ').split(' ')[2] - interfaces[name]['rx descs'] = spl[1].split(' ')[3] - interfaces[name]['tx queues'] = spl[2].split(' ')[3] - interfaces[name]['tx descs'] = spl[3].split(' ')[3] + interfaces[name]['tx queues'] = rfall[0].split()[2] + rdesc = re.findall(r'desc \d+', line) + if rdesc: + interfaces[name]['tx descs'] = rdesc[0].split()[1] return interfaces - def _get_installed_vpp_pkgs_ubuntu(self): + def _get_installed_vpp_pkgs_ubuntu(self, distro): """ Get the VPP hardware information and return it in a dictionary + :param distro: The linux distro + :type distro: dict :returns: List of the packages installed :rtype: list """ @@ -503,10 +614,11 @@ class VPPUtil(object): distro = self.get_linux_distro() if distro[0] == 'Ubuntu': - pkgs = self._get_installed_vpp_pkgs_ubuntu() + pkgs = self._get_installed_vpp_pkgs_ubuntu(distro) elif distro[0] == 'CentOS Linux': pkgs = self._get_installed_vpp_pkgs_centos() else: + pkgs = self._get_installed_vpp_pkgs_centos() return [] return pkgs @@ -543,6 +655,23 @@ class VPPUtil(object): return 0 + @staticmethod + def restart(node): + """ + + Starts vpp for a given node + + :param node: VPP node. + :type node: dict + """ + + cmd = 'service vpp restart' + (ret, stdout, stderr) = VPPUtil.exec_command(cmd) + if ret != 0: + raise RuntimeError('{} failed on node {} {} {}'. + format(cmd, node['host'], + stdout, stderr)) + @staticmethod def start(node): """ @@ -573,10 +702,9 @@ class VPPUtil(object): cmd = 'service vpp stop' (ret, stdout, stderr) = VPPUtil.exec_command(cmd) if ret != 0: - raise RuntimeError('{} failed on node {} {} {}'. - format(cmd, node['host'], - stdout, stderr)) + logging.debug('{} failed on node {} {} {}'.format(cmd, node['host'], stdout, stderr)) + # noinspection RegExpRedundantEscape @staticmethod def status(node): """ @@ -627,7 +755,7 @@ class VPPUtil(object): distro = platform.linux_distribution() if distro[0] == 'Ubuntu' or \ distro[0] == 'CentOS Linux' or \ - distro[:26] == 'Linux Distribution Red Hat': + distro[:7] == 'Red Hat': return distro else: raise RuntimeError('Linux Distribution {} is not supported'.format(distro[0])) @@ -660,3 +788,51 @@ class VPPUtil(object): version[dct[0]] = dct[1].lstrip(' ') return version + + @staticmethod + def show_bridge(node): + """ + Shows the current bridge configuration + + :param node: VPP node. + :type node: dict + :returns: A list of interfaces + """ + + ifaces = [] + cmd = 'vppctl show bridge' + (ret, stdout, stderr) = VPPUtil.exec_command(cmd) + if ret != 0: + raise RuntimeError('{} failed on node {} {} {}'. + format(cmd, node['host'], + stdout, stderr)) + lines = stdout.split('\r\n') + bridges = [] + for line in lines: + if line == 'no bridge-domains in use': + print line + return ifaces + if len(line) == 0: + continue + + lspl = line.lstrip(' ').split() + if lspl[0] != 'BD-ID': + bridges.append(lspl[0]) + + for bridge in bridges: + cmd = 'vppctl show bridge {} detail'.format(bridge) + (ret, stdout, stderr) = VPPUtil.exec_command(cmd) + if ret != 0: + raise RuntimeError('{} failed on node {} {} {}'. + format(cmd, node['host'], + stdout, stderr)) + + lines = stdout.split('\r\n') + for line in lines: + iface = re.findall(r'[a-zA-z]+\d+/\d+/\d+', line) + if len(iface): + ifcidx = {'name': iface[0], 'index': line.split()[1]} + ifaces.append(ifcidx) + + print stdout + return ifaces