2017-09-27 16:35:23 -04:00
|
|
|
# Copyright (c) 2016 Cisco and/or its affiliates.
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at:
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
|
2018-12-19 02:05:25 -08:00
|
|
|
from __future__ import print_function
|
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
"""VPP util library"""
|
|
|
|
import logging
|
|
|
|
import re
|
|
|
|
import subprocess
|
2018-11-13 12:40:12 -05:00
|
|
|
import requests
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
from collections import Counter
|
|
|
|
|
2019-04-30 21:15:18 -07:00
|
|
|
import distro
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
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",
|
|
|
|
],
|
|
|
|
}
|
2019-02-19 16:25:05 -05:00
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
class VPPUtil(object):
|
|
|
|
"""General class for any VPP related methods/functions."""
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def exec_command(cmd, timeout=None):
|
|
|
|
"""Execute a command on the local node.
|
|
|
|
|
|
|
|
:param cmd: Command to run locally.
|
|
|
|
:param timeout: Timeout value
|
|
|
|
:type cmd: str
|
|
|
|
:type timeout: int
|
|
|
|
:return return_code, stdout, stderr
|
|
|
|
:rtype: tuple(int, str, str)
|
|
|
|
"""
|
|
|
|
|
|
|
|
logging.info(" Local Command: {}".format(cmd))
|
2022-04-26 19:02:15 +02:00
|
|
|
out = ""
|
|
|
|
err = ""
|
|
|
|
prc = subprocess.Popen(
|
|
|
|
cmd,
|
|
|
|
shell=True,
|
|
|
|
bufsize=1,
|
|
|
|
stdin=subprocess.PIPE,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
with prc.stdout:
|
2018-12-19 02:05:25 -08:00
|
|
|
lines = prc.stdout.readlines()
|
|
|
|
for line in lines:
|
|
|
|
if type(line) != str:
|
|
|
|
line = line.decode()
|
2022-04-26 19:02:15 +02:00
|
|
|
logging.info(" {}".format(line.strip("\n")))
|
2017-09-27 16:35:23 -04:00
|
|
|
out += line
|
|
|
|
|
|
|
|
with prc.stderr:
|
2018-12-19 02:05:25 -08:00
|
|
|
lines = prc.stderr.readlines()
|
|
|
|
for line in lines:
|
|
|
|
if type(line) != str:
|
|
|
|
line = line.decode()
|
2022-04-26 19:02:15 +02:00
|
|
|
logging.warning(" {}".format(line.strip("\n")))
|
2017-09-27 16:35:23 -04:00
|
|
|
err += line
|
|
|
|
|
|
|
|
ret = prc.wait()
|
|
|
|
|
|
|
|
return ret, out, err
|
|
|
|
|
|
|
|
def _autoconfig_backup_file(self, filename):
|
|
|
|
"""
|
|
|
|
Create a backup file.
|
|
|
|
|
|
|
|
:param filename: The file to backup
|
|
|
|
:type filename: str
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Does a copy of the file exist, if not create one
|
2022-04-26 19:02:15 +02:00
|
|
|
ofile = filename + ".orig"
|
|
|
|
(ret, stdout, stderr) = self.exec_command("ls {}".format(ofile))
|
2017-09-27 16:35:23 -04:00
|
|
|
if ret != 0:
|
|
|
|
logging.debug(stderr)
|
2022-04-26 19:02:15 +02:00
|
|
|
if stdout.strip("\n") != ofile:
|
|
|
|
cmd = "sudo cp {} {}".format(filename, ofile)
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
|
|
|
logging.debug(stderr)
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
def _install_vpp_ubuntu(self, node, branch, ubuntu_version="xenial"):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Install the VPP packages
|
|
|
|
|
|
|
|
:param node: Node dictionary with cpuinfo.
|
2018-12-18 15:29:45 -05:00
|
|
|
:param branch: VPP branch
|
2017-09-27 16:35:23 -04:00
|
|
|
:param ubuntu_version: Ubuntu Version
|
|
|
|
:type node: dict
|
2018-12-18 15:29:45 -05:00
|
|
|
:type branch: string
|
2017-09-27 16:35:23 -04:00
|
|
|
:type ubuntu_version: string
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Modify the sources list
|
2022-04-26 19:02:15 +02:00
|
|
|
sfile = "/etc/apt/sources.list.d/99fd.io.list"
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Backup the sources list
|
|
|
|
self._autoconfig_backup_file(sfile)
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
reps = "deb [trusted=yes] https://packagecloud.io/fdio/"
|
|
|
|
reps += "{}/ubuntu {} main\n".format(branch, ubuntu_version)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
with open(sfile, "w") as sfd:
|
2018-11-13 12:40:12 -05:00
|
|
|
sfd.write(reps)
|
|
|
|
sfd.close()
|
|
|
|
|
|
|
|
# Add the key
|
2018-12-19 02:05:25 -08:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
key = requests.get("https://packagecloud.io/fdio/{}/gpgkey".format(branch))
|
2018-12-19 02:05:25 -08:00
|
|
|
cmd = 'echo "{}" | apt-key add -'.format(key.content.decode(key.encoding))
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {}".format(cmd, node["host"], stderr)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Install the package
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "apt-get -y update"
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} apt-get update failed on node {} {}".format(
|
|
|
|
cmd, node["host"], stderr
|
|
|
|
)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2019-02-19 16:25:05 -05:00
|
|
|
# Get the package list
|
2022-04-26 19:02:15 +02:00
|
|
|
pkgstr = ""
|
2019-02-19 16:25:05 -05:00
|
|
|
for ps in ubuntu_pkgs[branch]:
|
2022-04-26 19:02:15 +02:00
|
|
|
pkgstr += ps + " "
|
2019-02-19 16:25:05 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "apt-get -y install {}".format(pkgstr)
|
2019-02-19 16:25:05 -05:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2018-12-18 15:29:45 -05:00
|
|
|
def _install_vpp_centos(self, node, branch):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Install the VPP packages
|
|
|
|
|
|
|
|
:param node: Node dictionary with cpuinfo.
|
2018-12-18 15:29:45 -05:00
|
|
|
:param branch: The branch name release or master
|
2017-09-27 16:35:23 -04:00
|
|
|
:type node: dict
|
2018-12-18 15:29:45 -05:00
|
|
|
:type branch: string
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
|
2018-11-13 12:40:12 -05:00
|
|
|
# Be sure the correct system packages are installed
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "yum -y update"
|
2018-11-13 12:40:12 -05:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr))
|
2018-11-13 12:40:12 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "yum -y install pygpgme yum-utils"
|
2018-11-13 12:40:12 -05:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr))
|
2018-11-13 12:40:12 -05:00
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
# Modify the sources list
|
2022-04-26 19:02:15 +02:00
|
|
|
sfile = "/etc/yum.repos.d/fdio-release.repo"
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Backup the sources list
|
|
|
|
self._autoconfig_backup_file(sfile)
|
|
|
|
|
|
|
|
# Remove the current file
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "rm {}".format(sfile)
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr))
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2018-11-13 12:40:12 -05:00
|
|
|
# Get the file contents
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
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:
|
2018-11-13 12:40:12 -05:00
|
|
|
sfd.write(reps)
|
|
|
|
sfd.close()
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2018-11-13 12:40:12 -05:00
|
|
|
# Update the fdio repo
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "yum clean all"
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr))
|
2018-11-13 12:40:12 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "yum -q makecache -y --disablerepo='*' " "--enablerepo='fdio_{}'".format(
|
|
|
|
branch
|
|
|
|
)
|
2018-11-13 12:40:12 -05:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
logging.debug("{} failed on node {} {}".format(cmd, node["host"], stderr))
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2019-02-19 16:25:05 -05:00
|
|
|
# Get the package list
|
2022-04-26 19:02:15 +02:00
|
|
|
pkgstr = ""
|
2019-02-19 16:25:05 -05:00
|
|
|
for ps in centos_pkgs[branch]:
|
2022-04-26 19:02:15 +02:00
|
|
|
pkgstr += ps + " "
|
2019-02-19 16:25:05 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "yum -y install {}".format(pkgstr)
|
2019-02-19 16:25:05 -05:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2018-12-18 15:29:45 -05:00
|
|
|
def install_vpp(self, node, branch):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Install the VPP packages
|
|
|
|
|
|
|
|
:param node: Node dictionary with cpuinfo.
|
2018-12-18 15:29:45 -05:00
|
|
|
:param branch: The branch name
|
2017-09-27 16:35:23 -04:00
|
|
|
:type node: dict
|
2018-12-18 15:29:45 -05:00
|
|
|
:type branch: string
|
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
distro = self.get_linux_distro()
|
2018-03-30 10:50:19 -04:00
|
|
|
logging.info(" {}".format(distro[0]))
|
2022-04-26 19:02:15 +02:00
|
|
|
if distro[0] == "Ubuntu":
|
2018-03-30 10:50:19 -04:00
|
|
|
logging.info("Install Ubuntu")
|
2018-12-18 15:29:45 -05:00
|
|
|
self._install_vpp_ubuntu(node, branch, ubuntu_version=distro[2])
|
2022-04-26 19:02:15 +02:00
|
|
|
elif distro[0] == "CentOS Linux":
|
2017-09-27 16:35:23 -04:00
|
|
|
logging.info("Install CentOS")
|
2018-12-18 15:29:45 -05:00
|
|
|
self._install_vpp_centos(node, branch)
|
2017-09-27 16:35:23 -04:00
|
|
|
else:
|
2018-03-30 10:50:19 -04:00
|
|
|
logging.info("Install CentOS (default)")
|
2018-12-18 15:29:45 -05:00
|
|
|
self._install_vpp_centos(node, branch)
|
2018-03-30 10:50:19 -04:00
|
|
|
return
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2019-02-19 16:25:05 -05:00
|
|
|
def _uninstall_vpp_ubuntu(self, node):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Uninstall the VPP packages
|
|
|
|
|
2019-02-19 16:25:05 -05:00
|
|
|
:param node: Node dictionary with cpuinfo.
|
2017-09-27 16:35:23 -04:00
|
|
|
:type node: dict
|
|
|
|
"""
|
|
|
|
|
2019-02-19 16:25:05 -05:00
|
|
|
# get the package list
|
2022-04-26 19:02:15 +02:00
|
|
|
pkgstr = ""
|
2019-02-19 16:25:05 -05:00
|
|
|
pkgs = self.get_installed_vpp_pkgs()
|
|
|
|
for pkg in pkgs:
|
2022-04-26 19:02:15 +02:00
|
|
|
pkgname = pkg["name"]
|
|
|
|
pkgstr += pkgname + " "
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "dpkg --purge {}".format(pkgstr)
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
def _uninstall_vpp_centos(self, node):
|
|
|
|
"""
|
|
|
|
Uninstall the VPP packages
|
|
|
|
|
|
|
|
:param node: Node dictionary with cpuinfo.
|
|
|
|
:type node: dict
|
2019-02-19 16:25:05 -05:00
|
|
|
"""
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
pkgstr = ""
|
2017-09-27 16:35:23 -04:00
|
|
|
pkgs = self.get_installed_vpp_pkgs()
|
2019-02-19 16:25:05 -05:00
|
|
|
for pkg in pkgs:
|
2022-04-26 19:02:15 +02:00
|
|
|
pkgname = pkg["name"]
|
|
|
|
pkgstr += pkgname + " "
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2019-02-19 16:25:05 -05:00
|
|
|
logging.info("Uninstalling {}".format(pkgstr))
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "yum -y remove {}".format(pkgstr)
|
2019-02-19 16:25:05 -05:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
def uninstall_vpp(self, node):
|
|
|
|
"""
|
|
|
|
Uninstall the VPP packages
|
|
|
|
|
|
|
|
:param node: Node dictionary with cpuinfo.
|
|
|
|
:type node: dict
|
|
|
|
"""
|
2017-11-01 12:37:47 -04:00
|
|
|
|
|
|
|
# First stop VPP
|
|
|
|
self.stop(node)
|
2017-09-27 16:35:23 -04:00
|
|
|
distro = self.get_linux_distro()
|
2022-04-26 19:02:15 +02:00
|
|
|
if distro[0] == "Ubuntu":
|
2018-03-30 10:50:19 -04:00
|
|
|
logging.info("Uninstall Ubuntu")
|
2017-09-27 16:35:23 -04:00
|
|
|
self._uninstall_vpp_ubuntu(node)
|
2022-04-26 19:02:15 +02:00
|
|
|
elif distro[0] == "CentOS Linux":
|
2017-09-27 16:35:23 -04:00
|
|
|
logging.info("Uninstall CentOS")
|
|
|
|
self._uninstall_vpp_centos(node)
|
|
|
|
else:
|
2018-03-30 10:50:19 -04:00
|
|
|
logging.info("Uninstall CentOS (Default)")
|
|
|
|
self._uninstall_vpp_centos(node)
|
2017-09-27 16:35:23 -04:00
|
|
|
return
|
|
|
|
|
|
|
|
def show_vpp_settings(self, *additional_cmds):
|
|
|
|
"""
|
|
|
|
Print default VPP settings. In case others are needed, can be
|
|
|
|
accepted as next parameters (each setting one parameter), preferably
|
|
|
|
in form of a string.
|
|
|
|
|
|
|
|
:param additional_cmds: Additional commands that the vpp should print
|
|
|
|
settings for.
|
|
|
|
:type additional_cmds: tuple
|
|
|
|
"""
|
|
|
|
def_setting_tb_displayed = {
|
2022-04-26 19:02:15 +02:00
|
|
|
"IPv6 FIB": "ip6 fib",
|
|
|
|
"IPv4 FIB": "ip fib",
|
|
|
|
"Interface IP": "int addr",
|
|
|
|
"Interfaces": "int",
|
|
|
|
"ARP": "ip arp",
|
|
|
|
"Errors": "err",
|
2017-09-27 16:35:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if additional_cmds:
|
|
|
|
for cmd in additional_cmds:
|
2022-04-26 19:02:15 +02:00
|
|
|
def_setting_tb_displayed["Custom Setting: {}".format(cmd)] = cmd
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
for _, value in def_setting_tb_displayed.items():
|
2022-04-26 19:02:15 +02:00
|
|
|
self.exec_command("vppctl sh {}".format(value))
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2017-11-01 12:37:47 -04:00
|
|
|
@staticmethod
|
|
|
|
def get_vms(node):
|
|
|
|
"""
|
|
|
|
Get a list of VMs that are connected to VPP interfaces
|
|
|
|
|
|
|
|
:param node: VPP node.
|
|
|
|
:type node: dict
|
2018-12-19 02:05:25 -08:00
|
|
|
:returns: Dictionary containing a list of VMs and the interfaces
|
|
|
|
that are connected to VPP
|
2017-11-01 12:37:47 -04:00
|
|
|
:rtype: dictionary
|
|
|
|
"""
|
|
|
|
|
|
|
|
vmdict = {}
|
|
|
|
|
2019-02-19 16:25:05 -05:00
|
|
|
print("Need to implement get vms")
|
2018-12-19 02:05:25 -08:00
|
|
|
|
2017-11-01 12:37:47 -04:00
|
|
|
return vmdict
|
|
|
|
|
2017-10-17 11:07:22 -04:00
|
|
|
@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 = {}
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "vppctl show int addr"
|
2017-10-17 11:07:22 -04:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
if ret != 0:
|
|
|
|
return interfaces
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
lines = stdout.split("\n")
|
2019-04-30 20:57:04 -07:00
|
|
|
if len(lines[0]) != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
if lines[0].split(" ")[0] == "FileNotFoundError":
|
2017-10-17 11:07:22 -04:00
|
|
|
return interfaces
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
name = ""
|
2017-10-17 11:07:22 -04:00
|
|
|
for line in lines:
|
2019-04-30 20:57:04 -07:00
|
|
|
if len(line) == 0:
|
2017-10-17 11:07:22 -04:00
|
|
|
continue
|
|
|
|
|
|
|
|
# If the first character is not whitespace
|
|
|
|
# create a new interface
|
2022-04-26 19:02:15 +02:00
|
|
|
if len(re.findall(r"\s", line[0])) == 0:
|
2017-10-17 11:07:22 -04:00
|
|
|
spl = line.split()
|
|
|
|
name = spl[0]
|
2022-04-26 19:02:15 +02:00
|
|
|
if name == "local0":
|
2017-10-17 11:07:22 -04:00
|
|
|
continue
|
|
|
|
interfaces[name] = {}
|
2022-04-26 19:02:15 +02:00
|
|
|
interfaces[name]["state"] = spl[1].lstrip("(").rstrip("):\r")
|
2017-10-17 11:07:22 -04:00
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
interfaces[name]["address"] = line.lstrip(" ").rstrip("\r")
|
2017-10-17 11:07:22 -04:00
|
|
|
|
|
|
|
return interfaces
|
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
@staticmethod
|
|
|
|
def get_hardware(node):
|
|
|
|
"""
|
|
|
|
Get the VPP hardware information and return it in a
|
|
|
|
dictionary
|
|
|
|
|
|
|
|
:param node: VPP node.
|
|
|
|
:type node: dict
|
2017-10-17 11:07:22 -04:00
|
|
|
:returns: Dictionary containing VPP hardware information
|
2017-09-27 16:35:23 -04:00
|
|
|
:rtype: dictionary
|
|
|
|
"""
|
|
|
|
|
|
|
|
interfaces = {}
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "vppctl show hard"
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
if ret != 0:
|
|
|
|
return interfaces
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
lines = stdout.split("\n")
|
2019-04-30 20:57:04 -07:00
|
|
|
if len(lines[0]) != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
if lines[0].split(" ")[0] == "FileNotFoundError":
|
2017-09-27 16:35:23 -04:00
|
|
|
return interfaces
|
|
|
|
|
|
|
|
for line in lines:
|
2019-04-30 20:57:04 -07:00
|
|
|
if len(line) == 0:
|
2017-09-27 16:35:23 -04:00
|
|
|
continue
|
|
|
|
|
|
|
|
# If the first character is not whitespace
|
|
|
|
# create a new interface
|
2022-04-26 19:02:15 +02:00
|
|
|
if len(re.findall(r"\s", line[0])) == 0:
|
2017-09-27 16:35:23 -04:00
|
|
|
spl = line.split()
|
|
|
|
name = spl[0]
|
|
|
|
interfaces[name] = {}
|
2022-04-26 19:02:15 +02:00
|
|
|
interfaces[name]["index"] = spl[1]
|
|
|
|
interfaces[name]["state"] = spl[2]
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Ethernet address
|
2022-04-26 19:02:15 +02:00
|
|
|
rfall = re.findall(r"Ethernet address", line)
|
2017-09-27 16:35:23 -04:00
|
|
|
if rfall:
|
|
|
|
spl = line.split()
|
2022-04-26 19:02:15 +02:00
|
|
|
interfaces[name]["mac"] = spl[2]
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Carrier
|
2022-04-26 19:02:15 +02:00
|
|
|
rfall = re.findall(r"carrier", line)
|
2017-09-27 16:35:23 -04:00
|
|
|
if rfall:
|
2022-04-26 19:02:15 +02:00
|
|
|
spl = line.split("carrier ")
|
|
|
|
interfaces[name]["carrier"] = spl[1]
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Socket
|
2022-04-26 19:02:15 +02:00
|
|
|
spl = ""
|
|
|
|
rfall = re.findall(r"numa \d+", line)
|
2017-09-27 16:35:23 -04:00
|
|
|
if rfall:
|
2018-11-20 11:25:17 -05:00
|
|
|
spl = rfall[0].split()
|
2022-04-26 19:02:15 +02:00
|
|
|
interfaces[name]["numa"] = rfall[0].split()[1]
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Queues and Descriptors
|
2022-04-26 19:02:15 +02:00
|
|
|
rfall = re.findall(r"rx\: queues \d+", line)
|
2017-09-27 16:35:23 -04:00
|
|
|
if rfall:
|
2022-04-26 19:02:15 +02:00
|
|
|
interfaces[name]["rx queues"] = rfall[0].split()[2]
|
|
|
|
rdesc = re.findall(r"desc \d+", line)
|
2018-11-20 11:25:17 -05:00
|
|
|
if rdesc:
|
2022-04-26 19:02:15 +02:00
|
|
|
interfaces[name]["rx descs"] = rdesc[0].split()[1]
|
2018-11-20 11:25:17 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
rfall = re.findall(r"tx\: queues \d+", line)
|
2018-11-20 11:25:17 -05:00
|
|
|
if rfall:
|
2022-04-26 19:02:15 +02:00
|
|
|
interfaces[name]["tx queues"] = rfall[0].split()[2]
|
|
|
|
rdesc = re.findall(r"desc \d+", line)
|
2018-11-20 11:25:17 -05:00
|
|
|
if rdesc:
|
2022-04-26 19:02:15 +02:00
|
|
|
interfaces[name]["tx descs"] = rdesc[0].split()[1]
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
return interfaces
|
|
|
|
|
2019-02-19 16:25:05 -05:00
|
|
|
def _get_installed_vpp_pkgs_ubuntu(self):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Get the VPP hardware information and return it in a
|
|
|
|
dictionary
|
|
|
|
|
|
|
|
:returns: List of the packages installed
|
|
|
|
:rtype: list
|
|
|
|
"""
|
|
|
|
|
|
|
|
pkgs = []
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "dpkg -l | grep vpp"
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
|
|
|
return pkgs
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
lines = stdout.split("\n")
|
2017-09-27 16:35:23 -04:00
|
|
|
for line in lines:
|
|
|
|
items = line.split()
|
|
|
|
if len(items) < 2:
|
|
|
|
continue
|
2022-04-26 19:02:15 +02:00
|
|
|
pkg = {"name": items[1], "version": items[2]}
|
2017-09-27 16:35:23 -04:00
|
|
|
pkgs.append(pkg)
|
|
|
|
|
|
|
|
return pkgs
|
|
|
|
|
|
|
|
def _get_installed_vpp_pkgs_centos(self):
|
|
|
|
"""
|
|
|
|
Get the VPP hardware information and return it in a
|
|
|
|
dictionary
|
|
|
|
|
|
|
|
:returns: List of the packages installed
|
|
|
|
:rtype: list
|
|
|
|
"""
|
|
|
|
|
|
|
|
pkgs = []
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "rpm -qa | grep vpp"
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = self.exec_command(cmd)
|
|
|
|
if ret != 0:
|
|
|
|
return pkgs
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
lines = stdout.split("\n")
|
2017-09-27 16:35:23 -04:00
|
|
|
for line in lines:
|
|
|
|
if len(line) == 0:
|
|
|
|
continue
|
|
|
|
|
|
|
|
items = line.split()
|
|
|
|
if len(items) < 2:
|
2022-04-26 19:02:15 +02:00
|
|
|
pkg = {"name": items[0]}
|
2017-09-27 16:35:23 -04:00
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
pkg = {"name": items[1], "version": items[2]}
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
pkgs.append(pkg)
|
|
|
|
|
|
|
|
return pkgs
|
|
|
|
|
|
|
|
def get_installed_vpp_pkgs(self):
|
|
|
|
"""
|
|
|
|
Get the VPP hardware information and return it in a
|
|
|
|
dictionary
|
|
|
|
|
|
|
|
:returns: List of the packages installed
|
|
|
|
:rtype: list
|
|
|
|
"""
|
|
|
|
|
|
|
|
distro = self.get_linux_distro()
|
2022-04-26 19:02:15 +02:00
|
|
|
if distro[0] == "Ubuntu":
|
2019-02-19 16:25:05 -05:00
|
|
|
pkgs = self._get_installed_vpp_pkgs_ubuntu()
|
2022-04-26 19:02:15 +02:00
|
|
|
elif distro[0] == "CentOS Linux":
|
2017-09-27 16:35:23 -04:00
|
|
|
pkgs = self._get_installed_vpp_pkgs_centos()
|
|
|
|
else:
|
2018-03-30 10:50:19 -04:00
|
|
|
pkgs = self._get_installed_vpp_pkgs_centos()
|
2017-09-27 16:35:23 -04:00
|
|
|
return []
|
|
|
|
|
|
|
|
return pkgs
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_interfaces_numa_node(node, *iface_keys):
|
|
|
|
"""Get numa node on which are located most of the interfaces.
|
|
|
|
|
2018-12-19 02:05:25 -08:00
|
|
|
Return numa node with highest count of interfaces provided as
|
|
|
|
arguments.
|
|
|
|
Return 0 if the interface does not have numa_node information
|
|
|
|
available.
|
2017-09-27 16:35:23 -04:00
|
|
|
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
|
|
|
|
location of the provided interfaces.
|
|
|
|
|
|
|
|
:param node: Node from DICT__nodes.
|
|
|
|
:param iface_keys: Interface keys for lookup.
|
|
|
|
:type node: dict
|
|
|
|
:type iface_keys: strings
|
|
|
|
"""
|
|
|
|
numa_list = []
|
|
|
|
for if_key in iface_keys:
|
|
|
|
try:
|
2022-04-26 19:02:15 +02:00
|
|
|
numa_list.append(node["interfaces"][if_key].get("numa_node"))
|
2017-09-27 16:35:23 -04:00
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
numa_cnt_mc = Counter(numa_list).most_common()
|
|
|
|
numa_cnt_mc_len = len(numa_cnt_mc)
|
|
|
|
if numa_cnt_mc_len > 0 and numa_cnt_mc[0][0] != -1:
|
|
|
|
return numa_cnt_mc[0][0]
|
|
|
|
elif numa_cnt_mc_len > 1 and numa_cnt_mc[0][0] == -1:
|
|
|
|
return numa_cnt_mc[1][0]
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
2017-11-01 12:37:47 -04:00
|
|
|
@staticmethod
|
|
|
|
def restart(node):
|
|
|
|
"""
|
|
|
|
|
|
|
|
Starts vpp for a given node
|
|
|
|
|
|
|
|
:param node: VPP node.
|
|
|
|
:type node: dict
|
|
|
|
"""
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "service vpp restart"
|
2017-11-01 12:37:47 -04:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
|
|
|
|
)
|
2017-11-01 12:37:47 -04:00
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
@staticmethod
|
|
|
|
def start(node):
|
|
|
|
"""
|
|
|
|
|
|
|
|
Starts vpp for a given node
|
|
|
|
|
|
|
|
:param node: VPP node.
|
|
|
|
:type node: dict
|
|
|
|
"""
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "service vpp start"
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def stop(node):
|
|
|
|
"""
|
|
|
|
|
|
|
|
Stops vpp for a given node
|
|
|
|
|
|
|
|
:param node: VPP node.
|
|
|
|
:type node: dict
|
|
|
|
"""
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "service vpp stop"
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
logging.debug(
|
|
|
|
"{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2018-01-26 14:55:33 -05:00
|
|
|
# noinspection RegExpRedundantEscape
|
2017-09-27 16:35:23 -04:00
|
|
|
@staticmethod
|
|
|
|
def status(node):
|
|
|
|
"""
|
|
|
|
|
|
|
|
Gets VPP status
|
|
|
|
|
|
|
|
:param: node
|
|
|
|
:type node: dict
|
|
|
|
:returns: status, errors
|
|
|
|
:rtype: tuple(str, list)
|
|
|
|
"""
|
|
|
|
errors = []
|
|
|
|
vutil = VPPUtil()
|
|
|
|
pkgs = vutil.get_installed_vpp_pkgs()
|
|
|
|
if len(pkgs) == 0:
|
|
|
|
return "Not Installed", errors
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "service vpp status"
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
|
|
|
|
# Get the active status
|
2022-04-26 19:02:15 +02:00
|
|
|
state = re.findall(r"Active:[\w (\)]+", stdout)[0].split(" ")
|
2017-09-27 16:35:23 -04:00
|
|
|
if len(state) > 2:
|
|
|
|
statestr = "{} {}".format(state[1], state[2])
|
|
|
|
else:
|
|
|
|
statestr = "Invalid"
|
|
|
|
|
|
|
|
# For now we won't look for DPDK errors
|
|
|
|
# lines = stdout.split('\n')
|
|
|
|
# for line in lines:
|
|
|
|
# if 'EAL' in line or \
|
|
|
|
# 'FAILURE' in line or \
|
|
|
|
# 'failed' in line or \
|
|
|
|
# 'Failed' in line:
|
|
|
|
# errors.append(line.lstrip(' '))
|
|
|
|
|
|
|
|
return statestr, errors
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_linux_distro():
|
|
|
|
"""
|
|
|
|
Get the linux distribution and check if it is supported
|
|
|
|
|
|
|
|
:returns: linux distro, None if the distro is not supported
|
|
|
|
:rtype: list
|
|
|
|
"""
|
|
|
|
|
2019-04-30 21:15:18 -07:00
|
|
|
dist = distro.linux_distribution()
|
2022-04-26 19:02:15 +02:00
|
|
|
if dist[0] == "Ubuntu" or dist[0] == "CentOS Linux" or dist[:7] == "Red Hat":
|
2019-04-30 21:15:18 -07:00
|
|
|
return dist
|
2017-09-27 16:35:23 -04:00
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError("Linux Distribution {} is not supported".format(dist[0]))
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def version():
|
|
|
|
"""
|
|
|
|
|
|
|
|
Gets VPP Version information
|
|
|
|
|
|
|
|
:returns: version
|
|
|
|
:rtype: dict
|
|
|
|
"""
|
|
|
|
|
|
|
|
version = {}
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "vppctl show version verbose"
|
2017-09-27 16:35:23 -04:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
if ret != 0:
|
|
|
|
return version
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
lines = stdout.split("\n")
|
2019-04-30 20:57:04 -07:00
|
|
|
if len(lines[0]) != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
if lines[0].split(" ")[0] == "FileNotFoundError":
|
2017-09-27 16:35:23 -04:00
|
|
|
return version
|
|
|
|
|
|
|
|
for line in lines:
|
2019-04-30 20:57:04 -07:00
|
|
|
if len(line) == 0:
|
2017-09-27 16:35:23 -04:00
|
|
|
continue
|
2022-04-26 19:02:15 +02:00
|
|
|
dct = line.split(":")
|
|
|
|
version[dct[0]] = dct[1].lstrip(" ")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
return version
|
2017-11-01 12:37:47 -04:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def show_bridge(node):
|
|
|
|
"""
|
|
|
|
Shows the current bridge configuration
|
|
|
|
|
|
|
|
:param node: VPP node.
|
|
|
|
:type node: dict
|
2018-02-06 15:23:05 -05:00
|
|
|
:returns: A list of interfaces
|
2017-11-01 12:37:47 -04:00
|
|
|
"""
|
|
|
|
|
2018-02-06 15:23:05 -05:00
|
|
|
ifaces = []
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "vppctl show bridge"
|
2017-11-01 12:37:47 -04:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
|
|
|
|
)
|
|
|
|
lines = stdout.split("\r\n")
|
2017-11-01 12:37:47 -04:00
|
|
|
bridges = []
|
|
|
|
for line in lines:
|
2022-04-26 19:02:15 +02:00
|
|
|
if line == "no bridge-domains in use":
|
2019-02-19 16:25:05 -05:00
|
|
|
print(line)
|
2018-02-06 15:23:05 -05:00
|
|
|
return ifaces
|
2017-11-01 12:37:47 -04:00
|
|
|
if len(line) == 0:
|
|
|
|
continue
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
lspl = line.lstrip(" ").split()
|
|
|
|
if lspl[0] != "BD-ID":
|
2017-11-01 12:37:47 -04:00
|
|
|
bridges.append(lspl[0])
|
|
|
|
|
|
|
|
for bridge in bridges:
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "vppctl show bridge {} detail".format(bridge)
|
2017-11-01 12:37:47 -04:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {} {}".format(
|
|
|
|
cmd, node["host"], stdout, stderr
|
|
|
|
)
|
|
|
|
)
|
2018-02-06 15:23:05 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
lines = stdout.split("\r\n")
|
2018-02-06 15:23:05 -05:00
|
|
|
for line in lines:
|
2022-04-26 19:02:15 +02:00
|
|
|
iface = re.findall(r"[a-zA-z]+\d+/\d+/\d+", line)
|
2018-02-06 15:23:05 -05:00
|
|
|
if len(iface):
|
2022-04-26 19:02:15 +02:00
|
|
|
ifcidx = {"name": iface[0], "index": line.split()[1]}
|
2018-02-06 15:23:05 -05:00
|
|
|
ifaces.append(ifcidx)
|
|
|
|
|
2019-02-19 16:25:05 -05:00
|
|
|
print(stdout)
|
2018-03-30 10:50:19 -04:00
|
|
|
return ifaces
|