devstack/lib/neutron_plugins/ovn_agent
Slawek Kaplonski b1a89eb80b Configure access to physical network also with ML2/OVN backend
Neutron L3 module in Devstack has way to conigure access to physical
network on the node. It can put physical interface to the physical
bridge or, in case when such physical device isn't set, it creates
NAT rule in iptables.

There was missing the same operation for ML2/OVN backend as L3 agent is
not used there at all.

This patch adds the same to be done in both L3 agent and ovn_agent
modules.

Closes-Bug: #1939627
Change-Id: I9e558d1d5d3edbce9e7a025ba3c11267f1579820
2021-08-31 12:41:47 +00:00

797 lines
30 KiB
Bash

#!/bin/bash
#
# 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.
#
# Global Sources
# --------------
# There are some ovs functions OVN depends on that must be sourced from
# the ovs neutron plugins.
source ${TOP_DIR}/lib/neutron_plugins/ovs_base
source ${TOP_DIR}/lib/neutron_plugins/openvswitch_agent
# Load devstack ovs compliation and loading functions
source ${TOP_DIR}/lib/neutron_plugins/ovs_source
# Defaults
# --------
Q_BUILD_OVS_FROM_GIT=$(trueorfalse True Q_BUILD_OVS_FROM_GIT)
# Set variables for building OVN from source
OVN_REPO=${OVN_REPO:-https://github.com/ovn-org/ovn.git}
OVN_REPO_NAME=$(basename ${OVN_REPO} | cut -f1 -d'.')
OVN_REPO_NAME=${OVN_REPO_NAME:-ovn}
OVN_BRANCH=${OVN_BRANCH:-v20.06.1}
# The commit removing OVN bits from the OVS tree, it is the commit that is not
# present in OVN tree and is used to distinguish if OVN is part of OVS or not.
# https://github.com/openvswitch/ovs/commit/05bf1dbb98b0635a51f75e268ef8aed27601401d
OVN_SPLIT_HASH=05bf1dbb98b0635a51f75e268ef8aed27601401d
if is_service_enabled tls-proxy; then
OVN_PROTO=ssl
else
OVN_PROTO=tcp
fi
# How to connect to ovsdb-server hosting the OVN SB database.
OVN_SB_REMOTE=${OVN_SB_REMOTE:-$OVN_PROTO:$SERVICE_HOST:6642}
# How to connect to ovsdb-server hosting the OVN NB database
OVN_NB_REMOTE=${OVN_NB_REMOTE:-$OVN_PROTO:$SERVICE_HOST:6641}
# ml2/config for neutron_sync_mode
OVN_NEUTRON_SYNC_MODE=${OVN_NEUTRON_SYNC_MODE:-log}
# Configured DNS servers to be used with internal_dns extension, only
# if the subnet DNS is not configured.
OVN_DNS_SERVERS=${OVN_DNS_SERVERS:-8.8.8.8}
# The type of OVN L3 Scheduler to use. The OVN L3 Scheduler determines the
# hypervisor/chassis where a routers gateway should be hosted in OVN. The
# default OVN L3 scheduler is leastloaded
OVN_L3_SCHEDULER=${OVN_L3_SCHEDULER:-leastloaded}
# A UUID to uniquely identify this system. If one is not specified, a random
# one will be generated. A randomly generated UUID will be saved in a file
# $OVS_SYSCONFDIR/system-id.conf (typically /etc/openvswitch/system-id.conf)
# so that the same one will be re-used if you re-run DevStack or restart
# Open vSwitch service.
OVN_UUID=${OVN_UUID:-}
# Whether or not to build the openvswitch kernel module from ovs. This is required
# unless the distro kernel includes ovs+conntrack support.
OVN_BUILD_MODULES=$(trueorfalse False OVN_BUILD_MODULES)
OVN_BUILD_FROM_SOURCE=$(trueorfalse False OVN_BUILD_FROM_SOURCE)
# Whether or not to install the ovs python module from ovs source. This can be
# used to test and validate new ovs python features. This should only be used
# for development purposes since the ovs python version is controlled by OpenStack
# requirements.
OVN_INSTALL_OVS_PYTHON_MODULE=$(trueorfalse False OVN_INSTALL_OVS_PYTHON_MODULE)
# GENEVE overlay protocol overhead. Defaults to 38 bytes plus the IP version
# overhead (20 bytes for IPv4 (default) or 40 bytes for IPv6) which is determined
# based on the ML2 overlay_ip_version option. The ML2 framework will use this to
# configure the MTU DHCP option.
OVN_GENEVE_OVERHEAD=${OVN_GENEVE_OVERHEAD:-38}
# The log level of the OVN databases (north and south).
# Supported log levels are: off, emer, err, warn, info or dbg.
# More information about log levels can be found at
# http://www.openvswitch.org/support/dist-docs/ovs-appctl.8.txt
OVN_DBS_LOG_LEVEL=${OVN_DBS_LOG_LEVEL:-info}
OVN_META_CONF=$NEUTRON_CONF_DIR/neutron_ovn_metadata_agent.ini
OVN_META_DATA_HOST=${OVN_META_DATA_HOST:-$(ipv6_unquote $SERVICE_HOST)}
# If True (default) the node will be considered a gateway node.
ENABLE_CHASSIS_AS_GW=$(trueorfalse True ENABLE_CHASSIS_AS_GW)
OVN_L3_CREATE_PUBLIC_NETWORK=$(trueorfalse True OVN_L3_CREATE_PUBLIC_NETWORK)
export OVSDB_SERVER_LOCAL_HOST=$SERVICE_LOCAL_HOST
if [[ "$SERVICE_IP_VERSION" == 6 ]]; then
OVSDB_SERVER_LOCAL_HOST=[$OVSDB_SERVER_LOCAL_HOST]
fi
OVN_IGMP_SNOOPING_ENABLE=$(trueorfalse False OVN_IGMP_SNOOPING_ENABLE)
OVS_PREFIX=
if [[ "$OVN_BUILD_FROM_SOURCE" == "True" ]]; then
OVS_PREFIX=/usr/local
fi
OVS_SBINDIR=$OVS_PREFIX/sbin
OVS_BINDIR=$OVS_PREFIX/bin
OVS_RUNDIR=$OVS_PREFIX/var/run/openvswitch
OVS_SHAREDIR=$OVS_PREFIX/share/openvswitch
OVS_SCRIPTDIR=$OVS_SHAREDIR/scripts
OVS_DATADIR=$DATA_DIR/ovs
OVS_SYSCONFDIR=${OVS_SYSCONFDIR:-$OVS_PREFIX/etc/openvswitch}
OVN_DATADIR=$DATA_DIR/ovn
OVN_SHAREDIR=$OVS_PREFIX/share/ovn
OVN_SCRIPTDIR=$OVN_SHAREDIR/scripts
OVN_RUNDIR=$OVS_PREFIX/var/run/ovn
NEUTRON_OVN_BIN_DIR=$(get_python_exec_prefix)
NEUTRON_OVN_METADATA_BINARY="neutron-ovn-metadata-agent"
STACK_GROUP="$( id --group --name "$STACK_USER" )"
OVN_NORTHD_SERVICE=ovn-northd.service
if is_ubuntu; then
# The ovn-central.service file on Ubuntu is responsible for starting
# ovn-northd and the OVN DBs (on CentOS this is done by ovn-northd.service)
OVN_NORTHD_SERVICE=ovn-central.service
fi
OVSDB_SERVER_SERVICE=ovsdb-server.service
OVS_VSWITCHD_SERVICE=ovs-vswitchd.service
OVN_CONTROLLER_SERVICE=ovn-controller.service
OVN_CONTROLLER_VTEP_SERVICE=ovn-controller-vtep.service
if [[ "$OVN_BUILD_FROM_SOURCE" == "True" ]]; then
OVSDB_SERVER_SERVICE=devstack@ovsdb-server.service
OVS_VSWITCHD_SERVICE=devstack@ovs-vswitchd.service
OVN_NORTHD_SERVICE=devstack@ovn-northd.service
OVN_CONTROLLER_SERVICE=devstack@ovn-controller.service
OVN_CONTROLLER_VTEP_SERVICE=devstack@ovn-controller-vtep.service
fi
# Defaults Overwrite
# ------------------
Q_ML2_PLUGIN_MECHANISM_DRIVERS=${Q_ML2_PLUGIN_MECHANISM_DRIVERS:-ovn,logger}
Q_ML2_PLUGIN_TYPE_DRIVERS=${Q_ML2_PLUGIN_TYPE_DRIVERS:-local,flat,vlan,geneve}
Q_ML2_TENANT_NETWORK_TYPE=${Q_ML2_TENANT_NETWORK_TYPE:-"geneve"}
Q_ML2_PLUGIN_GENEVE_TYPE_OPTIONS=${Q_ML2_PLUGIN_GENEVE_TYPE_OPTIONS:-"vni_ranges=1:65536"}
Q_ML2_PLUGIN_EXT_DRIVERS=${Q_ML2_PLUGIN_EXT_DRIVERS:-port_security,qos}
# this one allows empty:
ML2_L3_PLUGIN=${ML2_L3_PLUGIN-"ovn-router"}
Q_LOG_DRIVER_RATE_LIMIT=${Q_LOG_DRIVER_RATE_LIMIT:-100}
Q_LOG_DRIVER_BURST_LIMIT=${Q_LOG_DRIVER_BURST_LIMIT:-25}
Q_LOG_DRIVER_LOG_BASE=${Q_LOG_DRIVER_LOG_BASE:-acl_log_meter}
# Utility Functions
# -----------------
function wait_for_sock_file {
local count=0
while [ ! -S $1 ]; do
sleep 1
count=$((count+1))
if [ "$count" -gt 5 ]; then
die $LINENO "Socket $1 not found"
fi
done
}
function use_new_ovn_repository {
if [[ "$OVN_BUILD_FROM_SOURCE" == "False" ]]; then
return 0
fi
if [ -z "$is_new_ovn" ]; then
local ovs_repo_dir=$DEST/$OVS_REPO_NAME
if [ ! -d $ovs_repo_dir ]; then
git_timed clone $OVS_REPO $ovs_repo_dir
pushd $ovs_repo_dir
git checkout $OVS_BRANCH
popd
else
clone_repository $OVS_REPO $ovs_repo_dir $OVS_BRANCH
fi
# Check the split commit exists in the current branch
pushd $ovs_repo_dir
git log $OVS_BRANCH --pretty=format:"%H" | grep -q $OVN_SPLIT_HASH
is_new_ovn=$?
popd
fi
return $is_new_ovn
}
# NOTE(rtheis): Function copied from DevStack _neutron_ovs_base_setup_bridge
# and _neutron_ovs_base_add_bridge with the call to neutron-ovs-cleanup
# removed. The call is not relevant for OVN, as it is specific to the use
# of Neutron's OVS agent and hangs when running stack.sh because
# neutron-ovs-cleanup uses the OVSDB native interface.
function ovn_base_setup_bridge {
local bridge=$1
local addbr_cmd="sudo ovs-vsctl --no-wait -- --may-exist add-br $bridge -- set bridge $bridge protocols=OpenFlow13,OpenFlow15"
if [ "$OVS_DATAPATH_TYPE" != "system" ] ; then
addbr_cmd="$addbr_cmd -- set Bridge $bridge datapath_type=${OVS_DATAPATH_TYPE}"
fi
$addbr_cmd
sudo ovs-vsctl --no-wait br-set-external-id $bridge bridge-id $bridge
}
function _start_process {
$SYSTEMCTL daemon-reload
$SYSTEMCTL enable $1
$SYSTEMCTL restart $1
}
function _run_process {
local service=$1
local cmd="$2"
local stop_cmd="$3"
local group=$4
local user=${5:-$STACK_USER}
local systemd_service="devstack@$service.service"
local unit_file="$SYSTEMD_DIR/$systemd_service"
local environment="OVN_RUNDIR=$OVS_RUNDIR OVN_DBDIR=$OVN_DATADIR OVN_LOGDIR=$LOGDIR OVS_RUNDIR=$OVS_RUNDIR OVS_DBDIR=$OVS_DATADIR OVS_LOGDIR=$LOGDIR"
echo "Starting $service executed command": $cmd
write_user_unit_file $systemd_service "$cmd" "$group" "$user"
iniset -sudo $unit_file "Service" "Type" "forking"
iniset -sudo $unit_file "Service" "RemainAfterExit" "yes"
iniset -sudo $unit_file "Service" "KillMode" "mixed"
iniset -sudo $unit_file "Service" "LimitNOFILE" "65536"
iniset -sudo $unit_file "Service" "Environment" "$environment"
if [ -n "$stop_cmd" ]; then
iniset -sudo $unit_file "Service" "ExecStop" "$stop_cmd"
fi
_start_process $systemd_service
local testcmd="test -e $OVS_RUNDIR/$service.pid"
test_with_retry "$testcmd" "$service did not start" $SERVICE_TIMEOUT 1
sudo ovs-appctl -t $service vlog/set console:off syslog:info file:info
}
function clone_repository {
local repo=$1
local dir=$2
local branch=$3
# Set ERROR_ON_CLONE to false to avoid the need of having the
# repositories like OVN and OVS in the required_projects of the job
# definition.
ERROR_ON_CLONE=false git_clone $repo $dir $branch
}
function create_public_bridge {
# Create the public bridge that OVN will use
sudo ovs-vsctl --may-exist add-br $PUBLIC_BRIDGE -- set bridge $PUBLIC_BRIDGE protocols=OpenFlow13,OpenFlow15
sudo ovs-vsctl set open . external-ids:ovn-bridge-mappings=$PHYSICAL_NETWORK:$PUBLIC_BRIDGE
_configure_public_network_connectivity
}
function _disable_libvirt_apparmor {
if ! sudo aa-status --enabled ; then
return 0
fi
# NOTE(arosen): This is used as a work around to allow newer versions
# of libvirt to work with ovs configured ports. See LP#1466631.
# requires the apparmor-utils
install_package apparmor-utils
# disables apparmor for libvirtd
sudo aa-complain /etc/apparmor.d/usr.sbin.libvirtd
}
# OVN compilation functions
# -------------------------
# compile_ovn() - Compile OVN from source and load needed modules
# Accepts three parameters:
# - first optional is False by default and means that
# modules are built and installed.
# - second optional parameter defines prefix for
# ovn compilation
# - third optional parameter defines localstatedir for
# ovn single machine runtime
function compile_ovn {
local build_modules=${1:-False}
local prefix=$2
local localstatedir=$3
if [ -n "$prefix" ]; then
prefix="--prefix=$prefix"
fi
if [ -n "$localstatedir" ]; then
localstatedir="--localstatedir=$localstatedir"
fi
clone_repository $OVN_REPO $DEST/$OVN_REPO_NAME $OVN_BRANCH
pushd $DEST/$OVN_REPO_NAME
if [ ! -f configure ] ; then
./boot.sh
fi
if [ ! -f config.status ] || [ configure -nt config.status ] ; then
./configure --with-ovs-source=$DEST/$OVS_REPO_NAME $prefix $localstatedir
fi
make -j$(($(nproc) + 1))
sudo make install
popd
}
# OVN Neutron driver functions
# ----------------------------
# OVN service sanity check
function ovn_sanity_check {
if is_service_enabled q-agt neutron-agt; then
die $LINENO "The q-agt/neutron-agt service must be disabled with OVN."
elif is_service_enabled q-l3 neutron-l3; then
die $LINENO "The q-l3/neutron-l3 service must be disabled with OVN."
elif is_service_enabled q-svc neutron-api && [[ ! $Q_ML2_PLUGIN_MECHANISM_DRIVERS =~ "ovn" ]]; then
die $LINENO "OVN needs to be enabled in \$Q_ML2_PLUGIN_MECHANISM_DRIVERS"
elif is_service_enabled q-svc neutron-api && [[ ! $Q_ML2_PLUGIN_TYPE_DRIVERS =~ "geneve" ]]; then
die $LINENO "Geneve needs to be enabled in \$Q_ML2_PLUGIN_TYPE_DRIVERS to be used with OVN"
fi
}
# install_ovn() - Collect source and prepare
function install_ovn {
if [[ "$Q_BUILD_OVS_FROM_GIT" == "False" ]]; then
echo "Installation of OVS from source disabled."
return 0
fi
echo "Installing OVN and dependent packages"
# Check the OVN configuration
ovn_sanity_check
# Install tox, used to generate the config (see devstack/override-defaults)
pip_install tox
sudo mkdir -p $OVS_RUNDIR
sudo chown $(whoami) $OVS_RUNDIR
# NOTE(lucasagomes): To keep things simpler, let's reuse the same
# RUNDIR for both OVS and OVN. This way we avoid having to specify the
# --db option in the ovn-{n,s}bctl commands while playing with DevStack
sudo ln -s $OVS_RUNDIR $OVN_RUNDIR
if [[ "$OVN_BUILD_FROM_SOURCE" == "True" ]]; then
# If OVS is already installed, remove it, because we're about to
# re-install it from source.
for package in openvswitch openvswitch-switch openvswitch-common; do
if is_package_installed $package ; then
uninstall_package $package
fi
done
remove_ovs_packages
sudo rm -f $OVS_RUNDIR/*
compile_ovs $OVN_BUILD_MODULES
if use_new_ovn_repository; then
compile_ovn $OVN_BUILD_MODULES
fi
sudo mkdir -p $OVS_PREFIX/var/log/openvswitch
sudo chown $(whoami) $OVS_PREFIX/var/log/openvswitch
sudo mkdir -p $OVS_PREFIX/var/log/ovn
sudo chown $(whoami) $OVS_PREFIX/var/log/ovn
else
fixup_ovn_centos
install_package $(get_packages openvswitch)
install_package $(get_packages ovn)
fi
# Ensure that the OVS commands are accessible in the PATH
export PATH=$OVS_BINDIR:$PATH
# Archive log files and create new
local log_archive_dir=$LOGDIR/archive
mkdir -p $log_archive_dir
for logfile in ovs-vswitchd.log ovn-northd.log ovn-controller.log ovn-controller-vtep.log ovs-vtep.log ovsdb-server.log ovsdb-server-nb.log ovsdb-server-sb.log; do
if [ -f "$LOGDIR/$logfile" ] ; then
mv "$LOGDIR/$logfile" "$log_archive_dir/$logfile.${CURRENT_LOG_TIME}"
fi
done
# Install ovsdbapp from source if requested
if use_library_from_git "ovsdbapp"; then
git_clone_by_name "ovsdbapp"
setup_dev_lib "ovsdbapp"
fi
# Install ovs python module from ovs source.
if [[ "$OVN_INSTALL_OVS_PYTHON_MODULE" == "True" ]]; then
sudo pip uninstall -y ovs
# Clone the OVS repository if it's not yet present
clone_repository $OVS_REPO $DEST/$OVS_REPO_NAME $OVS_BRANCH
sudo pip install -e $DEST/$OVS_REPO_NAME/python
fi
}
# filter_network_api_extensions() - Remove non-supported API extensions by
# the OVN driver from the list of enabled API extensions
function filter_network_api_extensions {
SUPPORTED_NETWORK_API_EXTENSIONS=$($PYTHON -c \
'from neutron.common.ovn import extensions ;\
print(",".join(extensions.ML2_SUPPORTED_API_EXTENSIONS))')
SUPPORTED_NETWORK_API_EXTENSIONS=$SUPPORTED_NETWORK_API_EXTENSIONS,$($PYTHON -c \
'from neutron.common.ovn import extensions ;\
print(",".join(extensions.ML2_SUPPORTED_API_EXTENSIONS_OVN_L3))')
if is_service_enabled q-qos neutron-qos ; then
SUPPORTED_NETWORK_API_EXTENSIONS="$SUPPORTED_NETWORK_API_EXTENSIONS,qos"
fi
NETWORK_API_EXTENSIONS=${NETWORK_API_EXTENSIONS:-$SUPPORTED_NETWORK_API_EXTENSIONS}
extensions=$(echo $NETWORK_API_EXTENSIONS | tr ', ' '\n' | sort -u)
supported_ext=$(echo $SUPPORTED_NETWORK_API_EXTENSIONS | tr ', ' '\n' | sort -u)
enabled_ext=$(comm -12 <(echo -e "$extensions") <(echo -e "$supported_ext"))
disabled_ext=$(comm -3 <(echo -e "$extensions") <(echo -e "$enabled_ext"))
# Log a message in case some extensions had to be disabled because
# they are not supported by the OVN driver
if [ ! -z "$disabled_ext" ]; then
_disabled=$(echo $disabled_ext | tr ' ' ',')
echo "The folling network API extensions have been disabled because they are not supported by OVN: $_disabled"
fi
# Export the final list of extensions that have been enabled and are
# supported by OVN
export NETWORK_API_EXTENSIONS=$(echo $enabled_ext | tr ' ' ',')
}
function configure_ovn_plugin {
echo "Configuring Neutron for OVN"
if is_service_enabled q-svc ; then
filter_network_api_extensions
populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_type_geneve max_header_size=$OVN_GENEVE_OVERHEAD
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_nb_connection="$OVN_NB_REMOTE"
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_sb_connection="$OVN_SB_REMOTE"
if is_service_enabled tls-proxy; then
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_sb_ca_cert="$INT_CA_DIR/ca-chain.pem"
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_sb_certificate="$INT_CA_DIR/$DEVSTACK_CERT_NAME.crt"
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_sb_private_key="$INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key"
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_nb_ca_cert="$INT_CA_DIR/ca-chain.pem"
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_nb_certificate="$INT_CA_DIR/$DEVSTACK_CERT_NAME.crt"
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_nb_private_key="$INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key"
fi
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn neutron_sync_mode="$OVN_NEUTRON_SYNC_MODE"
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_l3_scheduler="$OVN_L3_SCHEDULER"
populate_ml2_config /$Q_PLUGIN_CONF_FILE securitygroup enable_security_group="$Q_USE_SECGROUP"
inicomment /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver
if is_service_enabled q-log neutron-log; then
populate_ml2_config /$Q_PLUGIN_CONF_FILE network_log rate_limit="$Q_LOG_DRIVER_RATE_LIMIT"
populate_ml2_config /$Q_PLUGIN_CONF_FILE network_log burst_limit="$Q_LOG_DRIVER_BURST_LIMIT"
inicomment /$Q_PLUGIN_CONF_FILE network_log local_output_log_base="$Q_LOG_DRIVER_LOG_BASE"
fi
if is_service_enabled q-ovn-metadata-agent; then
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_metadata_enabled=True
else
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_metadata_enabled=False
fi
if is_service_enabled q-dns neutron-dns ; then
iniset $NEUTRON_CONF DEFAULT dns_domain openstackgate.local
populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn dns_servers="$OVN_DNS_SERVERS"
fi
iniset $NEUTRON_CONF ovs igmp_snooping_enable $OVN_IGMP_SNOOPING_ENABLE
fi
if is_service_enabled q-dhcp neutron-dhcp ; then
iniset $NEUTRON_CONF DEFAULT dhcp_agent_notification True
else
iniset $NEUTRON_CONF DEFAULT dhcp_agent_notification False
fi
if is_service_enabled n-api-meta ; then
if is_service_enabled q-ovn-metadata-agent ; then
iniset $NOVA_CONF neutron service_metadata_proxy True
fi
fi
}
function configure_ovn {
echo "Configuring OVN"
if [ -z "$OVN_UUID" ] ; then
if [ -f $OVS_SYSCONFDIR/system-id.conf ]; then
OVN_UUID=$(cat $OVS_SYSCONFDIR/system-id.conf)
else
OVN_UUID=$(uuidgen)
echo $OVN_UUID | sudo tee $OVS_SYSCONFDIR/system-id.conf
fi
else
local ovs_uuid
ovs_uuid=$(cat $OVS_SYSCONFDIR/system-id.conf)
if [ "$ovs_uuid" != $OVN_UUID ]; then
echo $OVN_UUID | sudo tee $OVS_SYSCONFDIR/system-id.conf
fi
fi
# Erase the pre-set configurations from packages. DevStack will
# configure OVS and OVN accordingly for its use.
if [[ "$OVN_BUILD_FROM_SOURCE" == "False" ]] && is_fedora; then
sudo truncate -s 0 /etc/openvswitch/default.conf
sudo truncate -s 0 /etc/sysconfig/openvswitch
sudo truncate -s 0 /etc/sysconfig/ovn
fi
# Metadata
if is_service_enabled q-ovn-metadata-agent && is_service_enabled ovn-controller; then
sudo install -d -o $STACK_USER $NEUTRON_CONF_DIR
mkdir -p $NEUTRON_DIR/etc/neutron/plugins/ml2
(cd $NEUTRON_DIR && exec ./tools/generate_config_file_samples.sh)
cp $NEUTRON_DIR/etc/neutron_ovn_metadata_agent.ini.sample $OVN_META_CONF
configure_root_helper_options $OVN_META_CONF
iniset $OVN_META_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
iniset $OVN_META_CONF DEFAULT nova_metadata_host $OVN_META_DATA_HOST
iniset $OVN_META_CONF DEFAULT metadata_workers $API_WORKERS
iniset $OVN_META_CONF DEFAULT state_path $NEUTRON_STATE_PATH
iniset $OVN_META_CONF ovs ovsdb_connection tcp:$OVSDB_SERVER_LOCAL_HOST:6640
iniset $OVN_META_CONF ovn ovn_sb_connection $OVN_SB_REMOTE
if is_service_enabled tls-proxy; then
iniset $OVN_META_CONF ovn \
ovn_sb_ca_cert $INT_CA_DIR/ca-chain.pem
iniset $OVN_META_CONF ovn \
ovn_sb_certificate $INT_CA_DIR/$DEVSTACK_CERT_NAME.crt
iniset $OVN_META_CONF ovn \
ovn_sb_private_key $INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key
fi
fi
}
function init_ovn {
# clean up from previous (possibly aborted) runs
# create required data files
# Assumption: this is a dedicated test system and there is nothing important
# in the ovn, ovn-nb, or ovs databases. We're going to trash them and
# create new ones on each devstack run.
_disable_libvirt_apparmor
mkdir -p $OVN_DATADIR
mkdir -p $OVS_DATADIR
rm -f $OVS_DATADIR/*.db
rm -f $OVS_DATADIR/.*.db.~lock~
rm -f $OVN_DATADIR/*.db
rm -f $OVN_DATADIR/.*.db.~lock~
}
function _start_ovs {
echo "Starting OVS"
if is_service_enabled ovn-controller ovn-controller-vtep ovn-northd; then
# ovsdb-server and ovs-vswitchd are used privately in OVN as openvswitch service names.
enable_service ovsdb-server
enable_service ovs-vswitchd
if [[ "$OVN_BUILD_FROM_SOURCE" == "True" ]]; then
if [ ! -f $OVS_DATADIR/conf.db ]; then
ovsdb-tool create $OVS_DATADIR/conf.db $OVS_SHAREDIR/vswitch.ovsschema
fi
if is_service_enabled ovn-controller-vtep; then
if [ ! -f $OVS_DATADIR/vtep.db ]; then
ovsdb-tool create $OVS_DATADIR/vtep.db $OVS_SHAREDIR/vtep.ovsschema
fi
fi
local dbcmd="$OVS_SBINDIR/ovsdb-server --remote=punix:$OVS_RUNDIR/db.sock --remote=ptcp:6640:$OVSDB_SERVER_LOCAL_HOST --pidfile --detach --log-file"
dbcmd+=" --remote=db:Open_vSwitch,Open_vSwitch,manager_options"
if is_service_enabled ovn-controller-vtep; then
dbcmd+=" --remote=db:hardware_vtep,Global,managers $OVS_DATADIR/vtep.db"
fi
dbcmd+=" $OVS_DATADIR/conf.db"
_run_process ovsdb-server "$dbcmd"
# Note: ovn-controller will create and configure br-int once it is started.
# So, no need to create it now because nothing depends on that bridge here.
local ovscmd="$OVS_SBINDIR/ovs-vswitchd --log-file --pidfile --detach"
_run_process ovs-vswitchd "$ovscmd" "" "$STACK_GROUP" "root"
else
_start_process "$OVSDB_SERVER_SERVICE"
_start_process "$OVS_VSWITCHD_SERVICE"
fi
echo "Configuring OVSDB"
if is_service_enabled tls-proxy; then
sudo ovs-vsctl --no-wait set-ssl \
$INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key \
$INT_CA_DIR/$DEVSTACK_CERT_NAME.crt \
$INT_CA_DIR/ca-chain.pem
fi
sudo ovs-vsctl --no-wait set-manager ptcp:6640:$OVSDB_SERVER_LOCAL_HOST
sudo ovs-vsctl --no-wait set open_vswitch . system-type="devstack"
sudo ovs-vsctl --no-wait set open_vswitch . external-ids:system-id="$OVN_UUID"
sudo ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-remote="$OVN_SB_REMOTE"
sudo ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-bridge="br-int"
sudo ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-encap-type="geneve"
sudo ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-encap-ip="$HOST_IP"
sudo ovs-vsctl --no-wait set open_vswitch . external-ids:hostname="$LOCAL_HOSTNAME"
# Select this chassis to host gateway routers
if [[ "$ENABLE_CHASSIS_AS_GW" == "True" ]]; then
sudo ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-cms-options="enable-chassis-as-gw"
fi
if is_provider_network || [[ $Q_USE_PROVIDERNET_FOR_PUBLIC == "True" ]]; then
ovn_base_setup_bridge $OVS_PHYSICAL_BRIDGE
sudo ovs-vsctl set open . external-ids:ovn-bridge-mappings=${PHYSICAL_NETWORK}:${OVS_PHYSICAL_BRIDGE}
fi
if is_service_enabled ovn-controller-vtep ; then
ovn_base_setup_bridge br-v
vtep-ctl add-ps br-v
vtep-ctl set Physical_Switch br-v tunnel_ips=$HOST_IP
enable_service ovs-vtep
local vtepcmd="$OVS_SCRIPTDIR/ovs-vtep --log-file --pidfile --detach br-v"
_run_process ovs-vtep "$vtepcmd" "" "$STACK_GROUP" "root"
vtep-ctl set-manager tcp:$HOST_IP:6640
fi
fi
}
function _start_ovn_services {
_start_process "$OVSDB_SERVER_SERVICE"
_start_process "$OVS_VSWITCHD_SERVICE"
if is_service_enabled ovn-northd ; then
_start_process "$OVN_NORTHD_SERVICE"
fi
if is_service_enabled ovn-controller ; then
_start_process "$OVN_CONTROLLER_SERVICE"
fi
if is_service_enabled ovn-controller-vtep ; then
_start_process "$OVN_CONTROLLER_VTEP_SERVICE"
fi
if is_service_enabled ovs-vtep ; then
_start_process "devstack@ovs-vtep.service"
fi
if is_service_enabled q-ovn-metadata-agent; then
_start_process "devstack@q-ovn-metadata-agent.service"
fi
}
# start_ovn() - Start running processes, including screen
function start_ovn {
echo "Starting OVN"
_start_ovs
local SCRIPTDIR=$OVN_SCRIPTDIR
if ! use_new_ovn_repository; then
SCRIPTDIR=$OVS_SCRIPTDIR
fi
if is_service_enabled ovn-northd ; then
if [[ "$OVN_BUILD_FROM_SOURCE" == "True" ]]; then
local cmd="/bin/bash $SCRIPTDIR/ovn-ctl --no-monitor start_northd"
local stop_cmd="/bin/bash $SCRIPTDIR/ovn-ctl stop_northd"
_run_process ovn-northd "$cmd" "$stop_cmd"
else
_start_process "$OVN_NORTHD_SERVICE"
fi
# Wait for the service to be ready
wait_for_sock_file $OVS_RUNDIR/ovnnb_db.sock
wait_for_sock_file $OVS_RUNDIR/ovnsb_db.sock
if is_service_enabled tls-proxy; then
sudo ovn-nbctl --db=unix:$OVS_RUNDIR/ovnnb_db.sock set-ssl $INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key $INT_CA_DIR/$DEVSTACK_CERT_NAME.crt $INT_CA_DIR/ca-chain.pem
sudo ovn-sbctl --db=unix:$OVS_RUNDIR/ovnsb_db.sock set-ssl $INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key $INT_CA_DIR/$DEVSTACK_CERT_NAME.crt $INT_CA_DIR/ca-chain.pem
fi
sudo ovn-nbctl --db=unix:$OVS_RUNDIR/ovnnb_db.sock set-connection p${OVN_PROTO}:6641:$SERVICE_LISTEN_ADDRESS -- set connection . inactivity_probe=60000
sudo ovn-sbctl --db=unix:$OVS_RUNDIR/ovnsb_db.sock set-connection p${OVN_PROTO}:6642:$SERVICE_LISTEN_ADDRESS -- set connection . inactivity_probe=60000
sudo ovs-appctl -t $OVS_RUNDIR/ovnnb_db.ctl vlog/set console:off syslog:$OVN_DBS_LOG_LEVEL file:$OVN_DBS_LOG_LEVEL
sudo ovs-appctl -t $OVS_RUNDIR/ovnsb_db.ctl vlog/set console:off syslog:$OVN_DBS_LOG_LEVEL file:$OVN_DBS_LOG_LEVEL
fi
if is_service_enabled ovn-controller ; then
if [[ "$OVN_BUILD_FROM_SOURCE" == "True" ]]; then
local cmd="/bin/bash $SCRIPTDIR/ovn-ctl --no-monitor start_controller"
local stop_cmd="/bin/bash $SCRIPTDIR/ovn-ctl stop_controller"
_run_process ovn-controller "$cmd" "$stop_cmd" "$STACK_GROUP" "root"
else
_start_process "$OVN_CONTROLLER_SERVICE"
fi
fi
if is_service_enabled ovn-controller-vtep ; then
if [[ "$OVN_BUILD_FROM_SOURCE" == "True" ]]; then
local cmd="$OVS_BINDIR/ovn-controller-vtep --log-file --pidfile --detach --ovnsb-db=$OVN_SB_REMOTE"
_run_process ovn-controller-vtep "$cmd" "" "$STACK_GROUP" "root"
else
_start_process "$OVN_CONTROLLER_VTEP_SERVICE"
fi
fi
if is_service_enabled q-ovn-metadata-agent; then
run_process q-ovn-metadata-agent "$NEUTRON_OVN_BIN_DIR/$NEUTRON_OVN_METADATA_BINARY --config-file $OVN_META_CONF"
# Format logging
setup_logging $OVN_META_CONF
fi
_start_ovn_services
}
function _stop_ovs_dp {
sudo ovs-dpctl dump-dps | sudo xargs -n1 ovs-dpctl del-dp
modprobe -q -r vport_geneve vport_vxlan openvswitch || true
}
function _stop_process {
local service=$1
echo "Stopping process $service"
if $SYSTEMCTL is-enabled $service; then
$SYSTEMCTL stop $service
$SYSTEMCTL disable $service
fi
}
function stop_ovn {
if is_service_enabled q-ovn-metadata-agent; then
sudo pkill -9 -f haproxy || :
_stop_process "devstack@q-ovn-metadata-agent.service"
fi
if is_service_enabled ovn-controller-vtep ; then
_stop_process "$OVN_CONTROLLER_VTEP_SERVICE"
fi
if is_service_enabled ovn-controller ; then
_stop_process "$OVN_CONTROLLER_SERVICE"
fi
if is_service_enabled ovn-northd ; then
_stop_process "$OVN_NORTHD_SERVICE"
fi
if is_service_enabled ovs-vtep ; then
_stop_process "devstack@ovs-vtep.service"
fi
_stop_process "$OVS_VSWITCHD_SERVICE"
_stop_process "$OVSDB_SERVER_SERVICE"
_stop_ovs_dp
}
function _cleanup {
local path=${1:-$DEST/$OVN_REPO_NAME}
pushd $path
cd $path
sudo make uninstall
sudo make distclean
popd
}
# cleanup_ovn() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_ovn {
local ovn_path=$DEST/$OVN_REPO_NAME
local ovs_path=$DEST/$OVS_REPO_NAME
if [ -d $ovn_path ]; then
_cleanup $ovn_path
fi
if [ -d $ovs_path ]; then
_cleanup $ovs_path
fi
sudo rm -f $OVN_RUNDIR
}