2019-10-31 13:31:07 -05:00
|
|
|
#!/usr/bin/env python3
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Copyright (c) 2016 Cisco and/or its affiliates.
|
2018-12-19 02:05:25 -08:00
|
|
|
# Copyright (c) 2018 Vinci Consulting Corp. All rights reserved.
|
2017-09-27 16:35:23 -04:00
|
|
|
# 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.
|
|
|
|
|
|
|
|
"""VPP Configuration Main Entry"""
|
2018-12-19 02:05:25 -08:00
|
|
|
from __future__ import absolute_import, division, print_function
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
import re
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import logging
|
2017-11-15 08:50:57 -05:00
|
|
|
import argparse
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
from vpplib.AutoConfig import AutoConfig
|
|
|
|
from vpplib.VPPUtil import VPPUtil
|
|
|
|
|
2018-12-19 02:05:25 -08:00
|
|
|
# Python2/3 compatible
|
|
|
|
try:
|
|
|
|
input = raw_input # noqa
|
|
|
|
except NameError:
|
|
|
|
pass
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
VPP_DRYRUNDIR = "/vpp/vpp-config/dryrun"
|
|
|
|
VPP_AUTO_CONFIGURATION_FILE = "/vpp/vpp-config/configs/auto-config.yaml"
|
|
|
|
VPP_HUGE_PAGE_FILE = "/vpp/vpp-config/dryrun/sysctl.d/80-vpp.conf"
|
|
|
|
VPP_STARTUP_FILE = "/vpp/vpp-config/dryrun/vpp/startup.conf"
|
|
|
|
VPP_GRUB_FILE = "/vpp/vpp-config/dryrun/default/grub"
|
|
|
|
VPP_REAL_HUGE_PAGE_FILE = "/etc/sysctl.d/80-vpp.conf"
|
|
|
|
VPP_REAL_STARTUP_FILE = "/etc/vpp/startup.conf"
|
|
|
|
VPP_REAL_GRUB_FILE = "/etc/default/grub"
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
rootdir = ""
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
|
|
|
|
def autoconfig_yn(question, default):
|
|
|
|
"""
|
|
|
|
Ask the user a yes or no question.
|
|
|
|
|
|
|
|
:param question: The text of the question
|
|
|
|
:param default: Value to be returned if '\n' is entered
|
|
|
|
:type question: string
|
|
|
|
:type default: string
|
|
|
|
:returns: The Answer
|
|
|
|
:rtype: string
|
|
|
|
"""
|
|
|
|
input_valid = False
|
|
|
|
default = default.lower()
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = ""
|
2017-09-27 16:35:23 -04:00
|
|
|
while not input_valid:
|
2018-12-19 02:05:25 -08:00
|
|
|
answer = input(question)
|
2017-09-27 16:35:23 -04:00
|
|
|
if len(answer) == 0:
|
|
|
|
answer = default
|
2022-04-26 19:02:15 +02:00
|
|
|
if re.findall(r"[YyNn]", answer):
|
2017-09-27 16:35:23 -04:00
|
|
|
input_valid = True
|
|
|
|
answer = answer[0].lower()
|
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("Please answer Y, N or Return.")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
return answer
|
|
|
|
|
|
|
|
|
|
|
|
def autoconfig_cp(node, src, dst):
|
|
|
|
"""
|
|
|
|
Copies a file, saving the original if needed.
|
|
|
|
|
|
|
|
:param node: Node dictionary with cpuinfo.
|
|
|
|
:param src: Source File
|
|
|
|
:param dst: Destination file
|
|
|
|
:type node: dict
|
|
|
|
:type src: string
|
|
|
|
:type dst: string
|
|
|
|
:raises RuntimeError: If command fails
|
|
|
|
"""
|
|
|
|
|
|
|
|
# If the destination file exist, create a copy if one does not already
|
|
|
|
# exist
|
2022-04-26 19:02:15 +02:00
|
|
|
ofile = dst + ".orig"
|
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command("ls {}".format(dst))
|
2017-09-27 16:35:23 -04:00
|
|
|
if ret == 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "cp {} {}".format(dst, ofile)
|
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
|
|
|
|
|
|
|
# Copy the source file
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "cp {} {}".format(src, os.path.dirname(dst))
|
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"], stderr))
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
|
|
|
|
def autoconfig_diff(node, src, dst):
|
|
|
|
"""
|
|
|
|
Returns the diffs of 2 files.
|
|
|
|
|
|
|
|
:param node: Node dictionary with cpuinfo.
|
|
|
|
:param src: Source File
|
|
|
|
:param dst: Destination file
|
|
|
|
:type node: dict
|
|
|
|
:type src: string
|
|
|
|
:type dst: string
|
|
|
|
:returns: The Answer
|
|
|
|
:rtype: string
|
|
|
|
:raises RuntimeError: If command fails
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Diff the files and return the output
|
|
|
|
cmd = "diff {} {}".format(src, dst)
|
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
2022-04-26 19:02:15 +02:00
|
|
|
if stderr != "":
|
|
|
|
raise RuntimeError(
|
|
|
|
"{} failed on node {} {} {}".format(cmd, node["host"], ret, stderr)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
return stdout
|
|
|
|
|
|
|
|
|
|
|
|
def autoconfig_show_system():
|
|
|
|
"""
|
|
|
|
Shows the system information.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
|
|
|
|
|
|
|
|
acfg.discover()
|
|
|
|
|
|
|
|
acfg.sys_info()
|
|
|
|
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
def autoconfig_hugepage_apply(node, ask_questions=True):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Apply the huge page configuration.
|
|
|
|
:param node: The node structure
|
|
|
|
:type node: dict
|
2017-11-15 08:50:57 -05:00
|
|
|
:param ask_questions: When True ask the user questions
|
|
|
|
:type ask_questions: bool
|
2017-09-27 16:35:23 -04:00
|
|
|
:returns: -1 if the caller should return, 0 if not
|
|
|
|
:rtype: int
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
diffs = autoconfig_diff(node, VPP_REAL_HUGE_PAGE_FILE, rootdir + VPP_HUGE_PAGE_FILE)
|
2022-04-26 19:02:15 +02:00
|
|
|
if diffs != "":
|
|
|
|
print("These are the changes we will apply to")
|
|
|
|
print("the huge page file ({}).\n".format(VPP_REAL_HUGE_PAGE_FILE))
|
|
|
|
print(diffs)
|
2017-11-15 08:50:57 -05:00
|
|
|
if ask_questions:
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = autoconfig_yn(
|
|
|
|
"\nAre you sure you want to apply these changes [Y/n]? ", "y"
|
|
|
|
)
|
|
|
|
if answer == "n":
|
2017-11-15 08:50:57 -05:00
|
|
|
return -1
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Copy and sysctl
|
|
|
|
autoconfig_cp(node, rootdir + VPP_HUGE_PAGE_FILE, VPP_REAL_HUGE_PAGE_FILE)
|
|
|
|
cmd = "sysctl -p {}".format(VPP_REAL_HUGE_PAGE_FILE)
|
|
|
|
(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
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nThere are no changes to the huge page configuration.")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
def autoconfig_vpp_apply(node, ask_questions=True):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Apply the vpp configuration.
|
|
|
|
|
|
|
|
:param node: The node structure
|
|
|
|
:type node: dict
|
2017-11-15 08:50:57 -05:00
|
|
|
:param ask_questions: When True ask the user questions
|
|
|
|
:type ask_questions: bool
|
2017-09-27 16:35:23 -04:00
|
|
|
:returns: -1 if the caller should return, 0 if not
|
|
|
|
:rtype: int
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
diffs = autoconfig_diff(node, VPP_REAL_STARTUP_FILE, rootdir + VPP_STARTUP_FILE)
|
2022-04-26 19:02:15 +02:00
|
|
|
if diffs != "":
|
|
|
|
print("These are the changes we will apply to")
|
|
|
|
print("the VPP startup file ({}).\n".format(VPP_REAL_STARTUP_FILE))
|
|
|
|
print(diffs)
|
2017-11-15 08:50:57 -05:00
|
|
|
if ask_questions:
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = autoconfig_yn(
|
|
|
|
"\nAre you sure you want to apply these changes [Y/n]? ", "y"
|
|
|
|
)
|
|
|
|
if answer == "n":
|
2017-11-15 08:50:57 -05:00
|
|
|
return -1
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Copy the VPP startup
|
|
|
|
autoconfig_cp(node, rootdir + VPP_STARTUP_FILE, VPP_REAL_STARTUP_FILE)
|
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nThere are no changes to VPP startup.")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
def autoconfig_grub_apply(node, ask_questions=True):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Apply the grub configuration.
|
|
|
|
|
|
|
|
:param node: The node structure
|
|
|
|
:type node: dict
|
2017-11-15 08:50:57 -05:00
|
|
|
:param ask_questions: When True ask the user questions
|
|
|
|
:type ask_questions: bool
|
2017-09-27 16:35:23 -04:00
|
|
|
:returns: -1 if the caller should return, 0 if not
|
|
|
|
:rtype: int
|
|
|
|
|
|
|
|
"""
|
2017-11-15 08:50:57 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nThe configured grub cmdline looks like this:")
|
|
|
|
configured_cmdline = node["grub"]["default_cmdline"]
|
|
|
|
current_cmdline = node["grub"]["current_cmdline"]
|
|
|
|
print(configured_cmdline)
|
|
|
|
print("\nThe current boot cmdline looks like this:")
|
|
|
|
print(current_cmdline)
|
2017-11-15 08:50:57 -05:00
|
|
|
if ask_questions:
|
|
|
|
question = "\nDo you want to keep the current boot cmdline [Y/n]? "
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = autoconfig_yn(question, "y")
|
|
|
|
if answer == "y":
|
2017-11-15 08:50:57 -05:00
|
|
|
return
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
node["grub"]["keep_cmdline"] = False
|
2017-11-15 08:50:57 -05:00
|
|
|
|
|
|
|
# Diff the file
|
|
|
|
diffs = autoconfig_diff(node, VPP_REAL_GRUB_FILE, rootdir + VPP_GRUB_FILE)
|
2022-04-26 19:02:15 +02:00
|
|
|
if diffs != "":
|
|
|
|
print("These are the changes we will apply to")
|
|
|
|
print("the GRUB file ({}).\n".format(VPP_REAL_GRUB_FILE))
|
|
|
|
print(diffs)
|
2017-11-15 08:50:57 -05:00
|
|
|
if ask_questions:
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = autoconfig_yn(
|
|
|
|
"\nAre you sure you want to apply these changes [y/N]? ", "n"
|
|
|
|
)
|
|
|
|
if answer == "n":
|
2017-09-27 16:35:23 -04:00
|
|
|
return -1
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
# Copy and update grub
|
|
|
|
autoconfig_cp(node, rootdir + VPP_GRUB_FILE, VPP_REAL_GRUB_FILE)
|
|
|
|
distro = VPPUtil.get_linux_distro()
|
2022-04-26 19:02:15 +02:00
|
|
|
if distro[0] == "Ubuntu":
|
2017-11-15 08:50:57 -05:00
|
|
|
cmd = "update-grub"
|
2017-09-27 16:35:23 -04:00
|
|
|
else:
|
2017-11-15 08:50:57 -05:00
|
|
|
cmd = "grub2-mkconfig -o /boot/grub2/grub.cfg"
|
|
|
|
|
|
|
|
(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-15 08:50:57 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
print("There have been changes to the GRUB config a", end=" ")
|
|
|
|
print("reboot will be required.")
|
2017-11-15 08:50:57 -05:00
|
|
|
return -1
|
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nThere are no changes to the GRUB config.")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
def autoconfig_apply(ask_questions=True):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Apply the configuration.
|
|
|
|
|
|
|
|
Show the diff of the dryrun file and the actual configuration file
|
|
|
|
Copy the files from the dryrun directory to the actual file.
|
|
|
|
Peform the system function
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
:param ask_questions: When true ask the user questions
|
|
|
|
:type ask_questions: bool
|
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
|
|
|
|
vutil = VPPUtil()
|
|
|
|
pkgs = vutil.get_installed_vpp_pkgs()
|
|
|
|
if len(pkgs) == 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nVPP is not installed, Install VPP with option 4.")
|
2017-09-27 16:35:23 -04:00
|
|
|
return
|
|
|
|
|
|
|
|
acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
if ask_questions:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nWe are now going to configure your system(s).\n")
|
|
|
|
answer = autoconfig_yn("Are you sure you want to do this [Y/n]? ", "y")
|
|
|
|
if answer == "n":
|
2017-11-15 08:50:57 -05:00
|
|
|
return
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
nodes = acfg.get_nodes()
|
|
|
|
for i in nodes.items():
|
|
|
|
node = i[1]
|
|
|
|
|
|
|
|
# Check the system resources
|
|
|
|
if not acfg.min_system_resources(node):
|
|
|
|
return
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
# Stop VPP
|
|
|
|
VPPUtil.stop(node)
|
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
# Huge Pages
|
2017-11-15 08:50:57 -05:00
|
|
|
ret = autoconfig_hugepage_apply(node, ask_questions)
|
2017-09-27 16:35:23 -04:00
|
|
|
if ret != 0:
|
|
|
|
return
|
|
|
|
|
|
|
|
# VPP
|
2017-11-15 08:50:57 -05:00
|
|
|
ret = autoconfig_vpp_apply(node, ask_questions)
|
2017-09-27 16:35:23 -04:00
|
|
|
if ret != 0:
|
|
|
|
return
|
|
|
|
|
|
|
|
# Grub
|
2017-11-15 08:50:57 -05:00
|
|
|
ret = autoconfig_grub_apply(node, ask_questions)
|
2017-09-27 16:35:23 -04:00
|
|
|
if ret != 0:
|
2017-11-15 08:50:57 -05:00
|
|
|
# We can still start VPP, even if we haven't configured grub
|
|
|
|
VPPUtil.start(node)
|
2017-09-27 16:35:23 -04:00
|
|
|
return
|
|
|
|
|
|
|
|
# Everything is configured start vpp
|
2017-11-15 08:50:57 -05:00
|
|
|
VPPUtil.start(node)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2018-01-26 14:55:33 -05:00
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
def autoconfig_dryrun(ask_questions=True):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
Execute the dryrun function.
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
:param ask_questions: When true ask the user for paraameters
|
|
|
|
:type ask_questions: bool
|
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE, clean=True)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Stop VPP on each node
|
|
|
|
nodes = acfg.get_nodes()
|
|
|
|
for i in nodes.items():
|
|
|
|
node = i[1]
|
|
|
|
VPPUtil.stop(node)
|
|
|
|
|
|
|
|
# Discover
|
|
|
|
acfg.discover()
|
|
|
|
|
|
|
|
# Check the system resources
|
|
|
|
nodes = acfg.get_nodes()
|
|
|
|
for i in nodes.items():
|
|
|
|
node = i[1]
|
|
|
|
if not acfg.min_system_resources(node):
|
|
|
|
return
|
|
|
|
|
|
|
|
# Modify the devices
|
2017-11-15 08:50:57 -05:00
|
|
|
if ask_questions:
|
|
|
|
acfg.modify_devices()
|
|
|
|
else:
|
|
|
|
acfg.update_interfaces_config()
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2019-04-05 12:25:50 -04:00
|
|
|
# If there are no interfaces, just return
|
|
|
|
for i in nodes.items():
|
|
|
|
node = i[1]
|
|
|
|
if not acfg.has_interfaces(node):
|
2022-04-26 19:02:15 +02:00
|
|
|
print(
|
|
|
|
"\nThere are no VPP interfaces configured, please configure at least 1."
|
|
|
|
)
|
2019-04-05 12:25:50 -04:00
|
|
|
return
|
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
# Modify CPU
|
2017-11-15 08:50:57 -05:00
|
|
|
acfg.modify_cpu(ask_questions)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Calculate the cpu parameters
|
|
|
|
acfg.calculate_cpu_parameters()
|
|
|
|
|
|
|
|
# Acquire TCP stack parameters
|
2017-11-15 08:50:57 -05:00
|
|
|
if ask_questions:
|
|
|
|
acfg.acquire_tcp_params()
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Apply the startup
|
|
|
|
acfg.apply_vpp_startup()
|
|
|
|
|
|
|
|
# Apply the grub configuration
|
|
|
|
acfg.apply_grub_cmdline()
|
|
|
|
|
|
|
|
# Huge Pages
|
2017-11-15 08:50:57 -05:00
|
|
|
if ask_questions:
|
|
|
|
acfg.modify_huge_pages()
|
2017-09-27 16:35:23 -04:00
|
|
|
acfg.apply_huge_pages()
|
|
|
|
|
|
|
|
|
|
|
|
def autoconfig_install():
|
|
|
|
"""
|
|
|
|
Install or Uninstall VPP.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Since these commands will take a while, we
|
|
|
|
# want to see the progress
|
|
|
|
logger = logging.getLogger()
|
|
|
|
|
|
|
|
acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
|
|
|
|
vutil = VPPUtil()
|
|
|
|
|
|
|
|
nodes = acfg.get_nodes()
|
|
|
|
for i in nodes.items():
|
|
|
|
node = i[1]
|
|
|
|
|
|
|
|
pkgs = vutil.get_installed_vpp_pkgs()
|
|
|
|
|
|
|
|
if len(pkgs) > 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nThese packages are installed on node {}".format(node["host"]))
|
|
|
|
print("{:25} {}".format("Name", "Version"))
|
2017-09-27 16:35:23 -04:00
|
|
|
for pkg in pkgs:
|
2018-12-19 02:05:25 -08:00
|
|
|
try:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("{:25} {}".format(pkg["name"], pkg["version"]))
|
2018-12-19 02:05:25 -08:00
|
|
|
except KeyError:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("{}".format(pkg["name"]))
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
question = "\nDo you want to uninstall these "
|
|
|
|
question += "packages [y/N]? "
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = autoconfig_yn(question, "n")
|
|
|
|
if answer == "y":
|
2017-09-27 16:35:23 -04:00
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
vutil.uninstall_vpp(node)
|
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nThere are no VPP packages on node {}.".format(node["host"]))
|
2017-09-27 16:35:23 -04:00
|
|
|
question = "Do you want to install VPP [Y/n]? "
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = autoconfig_yn(question, "y")
|
|
|
|
if answer == "y":
|
2018-12-18 15:29:45 -05:00
|
|
|
question = "Do you want to install the release version [Y/n]? "
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = autoconfig_yn(question, "y")
|
|
|
|
if answer == "y":
|
|
|
|
branch = "release"
|
2018-12-18 15:29:45 -05:00
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
branch = "master"
|
2017-09-27 16:35:23 -04:00
|
|
|
logger.setLevel(logging.INFO)
|
2018-12-18 15:29:45 -05:00
|
|
|
vutil.install_vpp(node, branch)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Set the logging level back
|
|
|
|
logger.setLevel(logging.ERROR)
|
|
|
|
|
|
|
|
|
|
|
|
def autoconfig_patch_qemu():
|
|
|
|
"""
|
|
|
|
Patch the correct qemu version that is needed for openstack
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Since these commands will take a while, we
|
|
|
|
# want to see the progress
|
|
|
|
logger = logging.getLogger()
|
|
|
|
|
|
|
|
acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
|
|
|
|
|
|
|
|
nodes = acfg.get_nodes()
|
|
|
|
for i in nodes.items():
|
|
|
|
node = i[1]
|
|
|
|
|
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
acfg.patch_qemu(node)
|
|
|
|
|
|
|
|
|
2017-10-17 11:07:22 -04:00
|
|
|
def autoconfig_ipv4_setup():
|
|
|
|
"""
|
|
|
|
Setup IPv4 interfaces
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
|
|
|
|
acfg.ipv4_interface_setup()
|
|
|
|
|
|
|
|
|
2018-02-06 15:23:05 -05:00
|
|
|
def autoconfig_create_iperf_vm():
|
2017-11-01 12:37:47 -04:00
|
|
|
"""
|
|
|
|
Setup IPv4 interfaces
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
|
2022-04-26 19:02:15 +02:00
|
|
|
acfg.destroy_iperf_vm("iperf-server")
|
2018-02-06 15:23:05 -05:00
|
|
|
acfg.create_and_bridge_iperf_virtual_interface()
|
2022-04-26 19:02:15 +02:00
|
|
|
acfg.create_iperf_vm("iperf-server")
|
2017-11-01 12:37:47 -04:00
|
|
|
|
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
def autoconfig_not_implemented():
|
|
|
|
"""
|
|
|
|
This feature is not implemented
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nThis Feature is not implemented yet....")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
|
2017-10-17 11:07:22 -04:00
|
|
|
def autoconfig_basic_test_menu():
|
|
|
|
"""
|
|
|
|
The auto configuration basic test menu
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
basic_menu_text = "\nWhat would you like to do?\n\n\
|
2017-10-17 11:07:22 -04:00
|
|
|
1) List/Create Simple IPv4 Setup\n\
|
2018-02-06 15:23:05 -05:00
|
|
|
2) Create an iperf VM and Connect to VPP an interface\n\
|
2022-04-26 19:02:15 +02:00
|
|
|
9 or q) Back to main menu."
|
2017-11-15 08:50:57 -05:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
print("{}".format(basic_menu_text))
|
2017-10-17 11:07:22 -04:00
|
|
|
|
|
|
|
input_valid = False
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = ""
|
2017-10-17 11:07:22 -04:00
|
|
|
while not input_valid:
|
2018-12-19 02:05:25 -08:00
|
|
|
answer = input("\nCommand: ")
|
2017-10-17 11:07:22 -04:00
|
|
|
if len(answer) > 1:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("Please enter only 1 character.")
|
2017-10-17 11:07:22 -04:00
|
|
|
continue
|
2022-04-26 19:02:15 +02:00
|
|
|
if re.findall(r"[Qq1-29]", answer):
|
2017-10-17 11:07:22 -04:00
|
|
|
input_valid = True
|
|
|
|
answer = answer[0].lower()
|
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("Please enter a character between 1 and 2 or 9.")
|
2017-10-17 11:07:22 -04:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
if answer == "9":
|
|
|
|
answer = "q"
|
2017-10-17 11:07:22 -04:00
|
|
|
|
|
|
|
return answer
|
|
|
|
|
|
|
|
|
|
|
|
def autoconfig_basic_test():
|
|
|
|
"""
|
|
|
|
The auto configuration basic test menu
|
|
|
|
|
|
|
|
"""
|
|
|
|
vutil = VPPUtil()
|
|
|
|
pkgs = vutil.get_installed_vpp_pkgs()
|
|
|
|
if len(pkgs) == 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nVPP is not installed, install VPP with option 4.")
|
2017-10-17 11:07:22 -04:00
|
|
|
return
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = ""
|
|
|
|
while answer != "q":
|
2017-10-17 11:07:22 -04:00
|
|
|
answer = autoconfig_basic_test_menu()
|
2022-04-26 19:02:15 +02:00
|
|
|
if answer == "1":
|
2017-10-17 11:07:22 -04:00
|
|
|
autoconfig_ipv4_setup()
|
2022-04-26 19:02:15 +02:00
|
|
|
elif answer == "2":
|
2018-02-06 15:23:05 -05:00
|
|
|
autoconfig_create_iperf_vm()
|
2022-04-26 19:02:15 +02:00
|
|
|
elif answer == "9" or answer == "q":
|
2017-10-17 11:07:22 -04:00
|
|
|
return
|
|
|
|
else:
|
|
|
|
autoconfig_not_implemented()
|
|
|
|
|
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
def autoconfig_main_menu():
|
|
|
|
"""
|
|
|
|
The auto configuration main menu
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
main_menu_text = "\nWhat would you like to do?\n\n\
|
2017-09-27 16:35:23 -04:00
|
|
|
1) Show basic system information\n\
|
2018-11-20 11:25:17 -05:00
|
|
|
2) Dry Run (Saves the configuration files in {}/vpp/vpp-config/dryrun.\n\
|
2017-09-27 16:35:23 -04:00
|
|
|
3) Full configuration (WARNING: This will change the system configuration)\n\
|
|
|
|
4) List/Install/Uninstall VPP.\n\
|
2022-04-26 19:02:15 +02:00
|
|
|
q) Quit".format(
|
|
|
|
rootdir, rootdir
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# 5) Dry Run from {}/vpp/vpp-config/auto-config.yaml (will not ask questions).\n\
|
|
|
|
# 6) Install QEMU patch (Needed when running openstack).\n\
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
print("{}".format(main_menu_text))
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
input_valid = False
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = ""
|
2017-09-27 16:35:23 -04:00
|
|
|
while not input_valid:
|
2018-12-19 02:05:25 -08:00
|
|
|
answer = input("\nCommand: ")
|
2017-09-27 16:35:23 -04:00
|
|
|
if len(answer) > 1:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("Please enter only 1 character.")
|
2017-09-27 16:35:23 -04:00
|
|
|
continue
|
2022-04-26 19:02:15 +02:00
|
|
|
if re.findall(r"[Qq1-4]", answer):
|
2017-09-27 16:35:23 -04:00
|
|
|
input_valid = True
|
|
|
|
answer = answer[0].lower()
|
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("Please enter a character between 1 and 4 or q.")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
return answer
|
|
|
|
|
|
|
|
|
|
|
|
def autoconfig_main():
|
|
|
|
"""
|
|
|
|
The auto configuration main entry point
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
# Setup
|
|
|
|
autoconfig_setup()
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
answer = ""
|
|
|
|
while answer != "q":
|
2017-09-27 16:35:23 -04:00
|
|
|
answer = autoconfig_main_menu()
|
2022-04-26 19:02:15 +02:00
|
|
|
if answer == "1":
|
2017-09-27 16:35:23 -04:00
|
|
|
autoconfig_show_system()
|
2022-04-26 19:02:15 +02:00
|
|
|
elif answer == "2":
|
2017-09-27 16:35:23 -04:00
|
|
|
autoconfig_dryrun()
|
2022-04-26 19:02:15 +02:00
|
|
|
elif answer == "3":
|
2017-09-27 16:35:23 -04:00
|
|
|
autoconfig_apply()
|
2022-04-26 19:02:15 +02:00
|
|
|
elif answer == "4":
|
2017-09-27 16:35:23 -04:00
|
|
|
autoconfig_install()
|
2022-04-26 19:02:15 +02:00
|
|
|
elif answer == "q":
|
2017-09-27 16:35:23 -04:00
|
|
|
return
|
|
|
|
else:
|
|
|
|
autoconfig_not_implemented()
|
|
|
|
|
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
def autoconfig_setup(ask_questions=True):
|
2017-09-27 16:35:23 -04:00
|
|
|
"""
|
|
|
|
The auto configuration setup function.
|
|
|
|
|
|
|
|
We will copy the configuration files to the dryrun directory.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
global rootdir
|
|
|
|
|
|
|
|
distro = VPPUtil.get_linux_distro()
|
2022-04-26 19:02:15 +02:00
|
|
|
if distro[0] == "Ubuntu":
|
|
|
|
rootdir = "/usr/local"
|
2017-09-27 16:35:23 -04:00
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
rootdir = "/usr"
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# If there is a system configuration file use that, if not use the initial auto-config file
|
|
|
|
filename = rootdir + VPP_AUTO_CONFIGURATION_FILE
|
|
|
|
if os.path.isfile(filename) is True:
|
|
|
|
acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
|
|
|
|
else:
|
2022-04-26 19:02:15 +02:00
|
|
|
raise RuntimeError(
|
|
|
|
"The Auto configuration file does not exist {}".format(filename)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2017-11-15 08:50:57 -05:00
|
|
|
if ask_questions:
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nWelcome to the VPP system configuration utility")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
print("\nThese are the files we will modify:")
|
|
|
|
print(" /etc/vpp/startup.conf")
|
|
|
|
print(" /etc/sysctl.d/80-vpp.conf")
|
|
|
|
print(" /etc/default/grub")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
print(
|
2018-12-19 02:05:25 -08:00
|
|
|
"\nBefore we change them, we'll create working copies in "
|
2022-04-26 19:02:15 +02:00
|
|
|
"{}".format(rootdir + VPP_DRYRUNDIR)
|
|
|
|
)
|
|
|
|
print(
|
2018-12-19 02:05:25 -08:00
|
|
|
"Please inspect them carefully before applying the actual "
|
2022-04-26 19:02:15 +02:00
|
|
|
"configuration (option 3)!"
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
nodes = acfg.get_nodes()
|
|
|
|
for i in nodes.items():
|
|
|
|
node = i[1]
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
if (os.path.isfile(rootdir + VPP_STARTUP_FILE) is not True) and (
|
|
|
|
os.path.isfile(VPP_REAL_STARTUP_FILE) is True
|
|
|
|
):
|
|
|
|
autoconfig_cp(
|
|
|
|
node, VPP_REAL_STARTUP_FILE, "{}".format(rootdir + VPP_STARTUP_FILE)
|
|
|
|
)
|
|
|
|
if (os.path.isfile(rootdir + VPP_HUGE_PAGE_FILE) is not True) and (
|
|
|
|
os.path.isfile(VPP_REAL_HUGE_PAGE_FILE) is True
|
|
|
|
):
|
|
|
|
autoconfig_cp(
|
|
|
|
node, VPP_REAL_HUGE_PAGE_FILE, "{}".format(rootdir + VPP_HUGE_PAGE_FILE)
|
|
|
|
)
|
|
|
|
if (os.path.isfile(rootdir + VPP_GRUB_FILE) is not True) and (
|
|
|
|
os.path.isfile(VPP_REAL_GRUB_FILE) is True
|
|
|
|
):
|
|
|
|
autoconfig_cp(
|
|
|
|
node, VPP_REAL_GRUB_FILE, "{}".format(rootdir + VPP_GRUB_FILE)
|
|
|
|
)
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2018-01-26 14:55:33 -05:00
|
|
|
# Be sure the uio_pci_generic driver is installed
|
2022-04-26 19:02:15 +02:00
|
|
|
cmd = "modprobe uio_pci_generic"
|
2018-01-26 14:55:33 -05:00
|
|
|
(ret, stdout, stderr) = VPPUtil.exec_command(cmd)
|
|
|
|
if ret != 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
logging.warning("{} failed on node {} {}".format(cmd, node["host"], stderr))
|
2018-01-26 14:55:33 -05:00
|
|
|
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2018-02-06 15:23:05 -05:00
|
|
|
# noinspection PyUnresolvedReferences
|
2017-11-15 08:50:57 -05:00
|
|
|
def execute_with_args(args):
|
|
|
|
"""
|
|
|
|
Execute the configuration utility with agruments.
|
|
|
|
|
|
|
|
:param args: The Command line arguments
|
|
|
|
:type args: tuple
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Setup
|
|
|
|
autoconfig_setup(ask_questions=False)
|
|
|
|
|
|
|
|
# Execute the command
|
|
|
|
if args.show:
|
|
|
|
autoconfig_show_system()
|
|
|
|
elif args.dry_run:
|
|
|
|
autoconfig_dryrun(ask_questions=False)
|
|
|
|
elif args.apply:
|
|
|
|
autoconfig_apply(ask_questions=False)
|
|
|
|
else:
|
|
|
|
autoconfig_not_implemented()
|
|
|
|
|
|
|
|
|
|
|
|
def config_main():
|
|
|
|
"""
|
|
|
|
The vpp configuration utility main entry point.
|
|
|
|
|
|
|
|
"""
|
2017-09-27 16:35:23 -04:00
|
|
|
|
|
|
|
# Check for root
|
|
|
|
if not os.geteuid() == 0:
|
2022-04-26 19:02:15 +02:00
|
|
|
sys.exit("\nPlease run the VPP Configuration Utility as root.")
|
2017-09-27 16:35:23 -04:00
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
if len(sys.argv) > 1 and ((sys.argv[1] == "-d") or (sys.argv[1] == "--debug")):
|
2018-01-26 14:55:33 -05:00
|
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
|
|
else:
|
|
|
|
logging.basicConfig(level=logging.ERROR)
|
|
|
|
|
2018-12-19 02:05:25 -08:00
|
|
|
# If no arguments were entered, ask the user questions to
|
|
|
|
# get the main parameters
|
2017-11-15 08:50:57 -05:00
|
|
|
if len(sys.argv) == 1:
|
2018-01-26 14:55:33 -05:00
|
|
|
autoconfig_main()
|
|
|
|
return
|
2022-04-26 19:02:15 +02:00
|
|
|
elif len(sys.argv) == 2 and ((sys.argv[1] == "-d") or (sys.argv[1] == "--debug")):
|
2017-11-15 08:50:57 -05:00
|
|
|
autoconfig_main()
|
|
|
|
return
|
|
|
|
|
2018-12-19 02:05:25 -08:00
|
|
|
# There were arguments specified, so execute the utility using
|
|
|
|
# command line arguments
|
2022-04-26 19:02:15 +02:00
|
|
|
description = "The VPP configuration utility allows the user to "
|
|
|
|
"configure VPP in a simple and safe manner. The utility takes input "
|
|
|
|
"from the user or the specified .yaml file. The user should then "
|
|
|
|
"examine these files to be sure they are correct and then actually "
|
|
|
|
"apply the configuration. When run without arguments the utility run "
|
|
|
|
"in an interactive mode"
|
2018-12-19 02:05:25 -08:00
|
|
|
|
|
|
|
main_parser = argparse.ArgumentParser(
|
2022-04-26 19:02:15 +02:00
|
|
|
prog="arg-test",
|
2018-12-19 02:05:25 -08:00
|
|
|
description=description,
|
2022-04-26 19:02:15 +02:00
|
|
|
epilog='See "%(prog)s help COMMAND" for help on a specific command.',
|
|
|
|
)
|
|
|
|
main_parser.add_argument(
|
|
|
|
"--apply", "-a", action="store_true", help="Apply the cofiguration."
|
|
|
|
)
|
|
|
|
main_parser.add_argument(
|
|
|
|
"--dry-run",
|
|
|
|
"-dr",
|
|
|
|
action="store_true",
|
|
|
|
help="Create the dryrun configuration files.",
|
|
|
|
)
|
|
|
|
main_parser.add_argument(
|
|
|
|
"--show", "-s", action="store_true", help="Shows basic system information"
|
|
|
|
)
|
|
|
|
main_parser.add_argument(
|
|
|
|
"--debug", "-d", action="count", help="Print debug output (multiple levels)"
|
|
|
|
)
|
2017-11-15 08:50:57 -05:00
|
|
|
|
|
|
|
args = main_parser.parse_args()
|
|
|
|
|
|
|
|
return execute_with_args(args)
|
|
|
|
|
|
|
|
|
2022-04-26 19:02:15 +02:00
|
|
|
if __name__ == "__main__":
|
2017-11-15 08:50:57 -05:00
|
|
|
config_main()
|