# See the License for the specific language governing permissions and
# limitations under the License.
+from __future__ import print_function
+
"""VPP util library"""
import logging
import re
import subprocess
-import platform
+import requests
from collections import Counter
-# VPP_VERSION = '1707'
-VPP_VERSION = '1710'
+import distro
+
+ubuntu_pkgs = {'release': ['vpp', 'vpp-plugin-core', 'vpp-plugin-dpdk', 'vpp-api-python', 'python3-vpp-api',
+ 'vpp-dbg', 'vpp-dev', 'vpp-ext-deps'],
+ 'master': ['vpp', 'vpp-plugin-core', 'vpp-plugin-dpdk', 'vpp-api-python', 'python3-vpp-api',
+ 'vpp-dbg', 'vpp-dev', 'vpp-ext-deps']}
+
+centos_pkgs = {'release': ['vpp', 'vpp-selinux-policy', 'vpp-plugins', 'vpp-api-lua',
+ 'vpp-api-python', 'vpp-debuginfo', 'vpp-devel', 'libvpp0', 'vpp-ext-deps'],
+ 'master': ['vpp', 'vpp-selinux-policy', 'vpp-plugins', 'vpp-api-lua',
+ 'vpp-api-python', 'vpp-debuginfo', 'vpp-devel', 'libvpp0', 'vpp-ext-deps']}
class VPPUtil(object):
stderr=subprocess.PIPE)
with prc.stdout:
- for line in iter(prc.stdout.readline, b''):
+ lines = prc.stdout.readlines()
+ for line in lines:
+ if type(line) != str:
+ line = line.decode()
logging.info(" {}".format(line.strip('\n')))
out += line
with prc.stderr:
- for line in iter(prc.stderr.readline, b''):
- logging.warn(" {}".format(line.strip('\n')))
+ lines = prc.stderr.readlines()
+ for line in lines:
+ if type(line) != str:
+ line = line.decode()
+ logging.warning(" {}".format(line.strip('\n')))
err += line
ret = prc.wait()
if ret != 0:
logging.debug(stderr)
- def _install_vpp_pkg_ubuntu(self, node, pkg):
- """
- Install the VPP packages
-
- :param node: Node dictionary
- :param pkg: The vpp packages
- :type node: dict
- :type pkg: string
- """
-
- cmd = 'apt-get -y install {}'.format(pkg)
- (ret, stdout, stderr) = self.exec_command(cmd)
- if ret != 0:
- raise RuntimeError('{} failed on node {} {} {}'.format(
- cmd, node['host'], stdout, stderr))
-
- def _install_vpp_pkg_centos(self, node, pkg):
- """
- Install the VPP packages
-
- :param node: Node dictionary
- :param pkg: The vpp packages
- :type node: dict
- :type pkg: string
- """
-
- cmd = 'yum -y install {}'.format(pkg)
- (ret, stdout, stderr) = self.exec_command(cmd)
- if ret != 0:
- 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
"""
# 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/'
- # When using a stable branch
- # reps += 'repositories/fd.io.stable.{}.ubuntu.{}.main/ ./\n' \
- # .format(fdio_release, ubuntu_version)
- reps += 'repositories/fd.io.ubuntu.{}.main/ ./\n' \
- .format(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.decode(key.encoding))
(ret, stdout, stderr) = self.exec_command(cmd)
if ret != 0:
raise RuntimeError('{} failed on node {} {}'.format(
node['host'],
stderr))
- 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')
+ # Get the package list
+ pkgstr = ''
+ for ps in ubuntu_pkgs[branch]:
+ pkgstr += ps + ' '
- def _install_vpp_centos(self, node, fdio_release=VPP_VERSION,
- centos_version='centos7'):
+ cmd = 'apt-get -y install {}'.format(pkgstr)
+ (ret, stdout, stderr) = self.exec_command(cmd)
+ if ret != 0:
+ raise RuntimeError('{} failed on node {} {} {}'.format(
+ cmd, node['host'], stdout, stderr))
+
+ 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'
node['host'],
stderr))
- reps = '[fdio-stable-{}]\n'.format(fdio_release)
- reps += 'name=fd.io stable/{} branch latest merge\n'.format(fdio_release)
- # When using stable
- # reps += 'baseurl=https://nexus.fd.io/content/repositories/fd.io.stable.{}.{}/\n'.\
- # format(fdio_release, centos_version)
- reps += 'baseurl=https://nexus.fd.io/content/repositories/fd.io.{}/\n'.\
- format(centos_version)
- reps += 'enabled=1\n'
- reps += 'gpgcheck=0'
-
- cmd = 'echo "{0}" | sudo tee {1}'.format(reps, sfile)
+ # Get the file contents
+
+ reps = '\n'.join([
+ '[fdio_{}]'.format(branch),
+ 'name=fdio_{}'.format(branch),
+ 'baseurl=https://packagecloud.io/fdio/{}/el/7/$basearch'.format(
+ branch),
+ 'repo_gpgcheck=1',
+ 'gpgcheck=0',
+ 'enabled=1',
+ 'gpgkey=https://packagecloud.io/fdio/{}/gpgkey'.format(branch),
+ 'sslverify=1',
+ 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt',
+ 'metadata_expire=300\n',
+ '[fdio_{}-source]'.format(branch),
+ 'name=fdio_release-{}'.format(branch),
+ 'baseurl=https://packagecloud.io/fdio/{}/el/7/SRPMS'.format(
+ branch),
+ 'repo_gpgcheck=1',
+ 'gpgcheck=0',
+ 'enabled=1',
+ 'gpgkey=https://packagecloud.io/fdio/{}/gpgkey'.format(branch),
+ 'sslverify =1',
+ 'sslcacert=/etc/pki/tls/certs/ca-bundle.crt',
+ 'metadata_expire=300\n'
+ ])
+ 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))
- # Install the packages
-
- 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')
+ 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))
+
+ # Get the package list
+ pkgstr = ''
+ for ps in centos_pkgs[branch]:
+ pkgstr += ps + ' '
- def install_vpp(self, node):
+ cmd = 'yum -y install {}'.format(pkgstr)
+ (ret, stdout, stderr) = self.exec_command(cmd)
+ if ret != 0:
+ raise RuntimeError('{} failed on node {} {} {}'.format(
+ cmd, node['host'], stdout, stderr))
+
+ 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):
+ def _uninstall_vpp_ubuntu(self, node):
"""
Uninstall the VPP packages
- :param node: Node dictionary
- :param pkg: The vpp packages
+ :param node: Node dictionary with cpuinfo.
:type node: dict
- :type pkg: string
"""
- cmd = 'dpkg --purge {}'.format(pkg)
- (ret, stdout, stderr) = self.exec_command(cmd)
- if ret != 0:
- raise RuntimeError('{} failed on node {} {} {}'.format(
- cmd, node['host'], stdout, stderr))
- def _uninstall_vpp_pkg_centos(self, node, pkg):
- """
- Uninstall the VPP packages
+ # get the package list
+ pkgstr = ''
+ pkgs = self.get_installed_vpp_pkgs()
+ for pkg in pkgs:
+ pkgname = pkg['name']
+ pkgstr += pkgname + ' '
- :param node: Node dictionary
- :param pkg: The vpp packages
- :type node: dict
- :type pkg: string
- """
- cmd = 'yum -y remove {}'.format(pkg)
+ cmd = 'dpkg --purge {}'.format(pkgstr)
(ret, stdout, stderr) = self.exec_command(cmd)
if ret != 0:
raise RuntimeError('{} failed on node {} {} {}'.format(
cmd, node['host'], stdout, stderr))
- def _uninstall_vpp_ubuntu(self, node):
- """
- Uninstall the VPP packages
-
- :param node: Node dictionary with cpuinfo.
- :type node: dict
- """
- pkgs = self.get_installed_vpp_pkgs()
-
- if len(pkgs) > 0:
- if 'version' in pkgs[0]:
- logging.info("Uninstall Ubuntu Packages")
- 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:
- logging.info("Uninstall locally installed Ubuntu Packages")
- for pkg in pkgs:
- self._uninstall_vpp_pkg_ubuntu(node, pkg['name'])
- else:
- logging.error("There are no Ubuntu packages installed")
-
def _uninstall_vpp_centos(self, node):
"""
Uninstall the VPP packages
:param node: Node dictionary with cpuinfo.
:type node: dict
- """
+ """
+ pkgstr = ''
pkgs = self.get_installed_vpp_pkgs()
+ for pkg in pkgs:
+ pkgname = pkg['name']
+ pkgstr += pkgname + ' '
- if len(pkgs) > 0:
- if 'version' in pkgs[0]:
- logging.info("Uninstall CentOS Packages")
- 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')
- else:
- logging.info("Uninstall locally installed CentOS Packages")
- for pkg in pkgs:
- self._uninstall_vpp_pkg_centos(node, pkg['name'])
- else:
- logging.error("There are no CentOS packages installed")
+ logging.info("Uninstalling {}".format(pkgstr))
+ cmd = 'yum -y remove {}'.format(pkgstr)
+ (ret, stdout, stderr) = self.exec_command(cmd)
+ if ret != 0:
+ raise RuntimeError('{} failed on node {} {} {}'.format(
+ cmd, node['host'], stdout, stderr))
def uninstall_vpp(self, node):
"""
# 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):
:param node: VPP node.
:type node: dict
- :returns: Dictionary containing a list of VMs and the interfaces that are connected to VPP
+ :returns: Dictionary containing a list of VMs and the interfaces
+ that are connected to VPP
:rtype: dictionary
"""
vmdict = {}
- print "Need to implement get vms"
-
+ print("Need to implement get vms")
+
return vmdict
@staticmethod
return interfaces
lines = stdout.split('\n')
- if len(lines[0]) is not 0:
+ if len(lines[0]) != 0:
if lines[0].split(' ')[0] == 'FileNotFoundError':
return interfaces
name = ''
for line in lines:
- if len(line) is 0:
+ if len(line) == 0:
continue
# If the first character is not whitespace
# create a new interface
- if len(re.findall(r'\s', line[0])) is 0:
+ if len(re.findall(r'\s', line[0])) == 0:
spl = line.split()
name = spl[0]
if name == 'local0':
return interfaces
lines = stdout.split('\n')
- if len(lines[0]) is not 0:
+ if len(lines[0]) != 0:
if lines[0].split(' ')[0] == 'FileNotFoundError':
return interfaces
for line in lines:
- if len(line) is 0:
+ if len(line) == 0:
continue
# If the first character is not whitespace
# create a new interface
- if len(re.findall(r'\s', line[0])) is 0:
+ if len(re.findall(r'\s', line[0])) == 0:
spl = line.split()
name = spl[0]
interfaces[name] = {}
interfaces[name]['carrier'] = spl[1]
# Socket
- rfall = re.findall(r'cpu socket', line)
+ spl = ''
+ 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:
- 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]['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:
+ 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
elif distro[0] == 'CentOS Linux':
pkgs = self._get_installed_vpp_pkgs_centos()
else:
+ pkgs = self._get_installed_vpp_pkgs_centos()
return []
return pkgs
def get_interfaces_numa_node(node, *iface_keys):
"""Get numa node on which are located most of the interfaces.
- Return numa node with highest count of interfaces provided as arguments.
- Return 0 if the interface does not have numa_node information available.
+ Return numa node with highest count of interfaces provided as
+ arguments.
+ Return 0 if the interface does not have numa_node information
+ available.
If all interfaces have unknown location (-1), then return 0.
If most of interfaces have unknown location (-1), but there are
some interfaces with known location, then return the second most
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):
"""
:rtype: list
"""
- distro = platform.linux_distribution()
- if distro[0] == 'Ubuntu' or \
- distro[0] == 'CentOS Linux' or \
- distro[:26] == 'Linux Distribution Red Hat':
- return distro
+ dist = distro.linux_distribution()
+ if dist[0] == 'Ubuntu' or \
+ dist[0] == 'CentOS Linux' or \
+ dist[:7] == 'Red Hat':
+ return dist
else:
- raise RuntimeError('Linux Distribution {} is not supported'.format(distro[0]))
+ raise RuntimeError(
+ 'Linux Distribution {} is not supported'.format(dist[0]))
@staticmethod
def version():
return version
lines = stdout.split('\n')
- if len(lines[0]) is not 0:
+ if len(lines[0]) != 0:
if lines[0].split(' ')[0] == 'FileNotFoundError':
return version
for line in lines:
- if len(line) is 0:
+ if len(line) == 0:
continue
dct = line.split(':')
version[dct[0]] = dct[1].lstrip(' ')
: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:
bridges = []
for line in lines:
if line == 'no bridge-domains in use':
- print line
- return
+ print(line)
+ return ifaces
if len(line) == 0:
continue
raise RuntimeError('{} failed on node {} {} {}'.
format(cmd, node['host'],
stdout, stderr))
- print stdout
+
+ 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