Move DevStack OVN module to Neutron

This patch is moving the DevStack module to deploy OVN to the Neutron
DevStack plugin.

As a first step, this plugin will continue to use the
openstack/networking-ovn repository and, as we advance into the mergings
steps we will modify this plugin (just few lines) to use the code in
the Neutron repository itself.

TODO's where left in the code on top of all the bits that will change
once the networking-ovn code is merged into Neutron.

Below is a snippet of the what needs to be enabled in local.conf to get
OVN deployed:

[[local|localrc]]

enable_plugin neutron https://opendev.org/openstack/neutron

Q_AGENT=ovn
Q_ML2_PLUGIN_MECHANISM_DRIVERS=ovn,logger
Q_ML2_PLUGIN_TYPE_DRIVERS=local,flat,vlan,geneve
Q_ML2_TENANT_NETWORK_TYPE="geneve"

Partially-Implements: blueprint neutron-ovn-merge
Change-Id: I24ab11ab923339959eecfbaed79a3ceadc4a87f4
Signed-off-by: Lucas Alvares Gomes <lucasagomes@gmail.com>
This commit is contained in:
Lucas Alvares Gomes 2019-11-28 14:35:41 +00:00
parent 7ba82ebcdf
commit 96741866a7
3 changed files with 875 additions and 0 deletions

790
devstack/lib/ovn_agent Normal file
View File

@ -0,0 +1,790 @@
#!/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. After doing this, the OVN overrides must be
# re-sourced.
source $TOP_DIR/lib/neutron_plugins/ovs_base
source $TOP_DIR/lib/neutron_plugins/openvswitch_agent
# Defaults
# --------
# TODO(lucasagomes): Remove this after the networking-ovn code is
# merged into Neutron
# networking-ovn neutron driver
NETWORKING_OVN_REPO=${NETWORKING_OVN_REPO:-${GIT_BASE}/openstack/networking-ovn.git}
NETWORKING_OVN_BRANCH=${NETWORKING_OVN_BRANCH:-$TARGET_BRANCH}
# 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_BRANCH=${OVN_BRANCH:-master}
# Set variables for building OVS from source
OVS_REPO=${OVS_REPO:-https://github.com/openvswitch/ovs.git}
OVS_REPO_NAME=$(basename ${OVS_REPO} | cut -f1 -d'.')
OVS_BRANCH=$OVN_BRANCH
# How to connect to ovsdb-server hosting the OVN SB database.
OVN_SB_REMOTE=${OVN_SB_REMOTE:-tcp:$SERVICE_HOST:6642}
# How to connect to ovsdb-server hosting the OVN NB database
OVN_NB_REMOTE=${OVN_NB_REMOTE:-tcp:$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
# 'ovn-uuid' so that the same one will be re-used if you re-run DevStack.
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)
# 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)
OVN_DBS_LOG_LEVEL=${OVN_DBS_LOG_LEVEL:-info}
OVN_META_CONF=$NEUTRON_CONF_DIR/networking_ovn_metadata_agent.ini
OVS_PREFIX=/usr/local
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
OVN_DATADIR=$DATA_DIR/ovn
OVN_SHAREDIR=$OVS_PREFIX/share/ovn
OVN_SCRIPTDIR=$OVN_SHAREDIR/scripts
OVN_RUNDIR=$OVS_PREFIX/var/run/ovn
# TODO(lucasagomes): These paths will change once the networking-ovn
# code is merged into Neutron
NETWORKING_OVN_BIN_DIR=$(get_python_exec_prefix)
NETWORKING_OVN_METADATA_BINARY="networking-ovn-metadata-agent"
NETWORKING_OVN_DIR=$DEST/networking-ovn
# Libs from source
# ----------------
# ovsdbapp used by neutron
GITREPO["ovsdbapp"]=${OVSDBAPP_REPO:-${GIT_BASE}/openstack/ovsdbapp.git}
GITBRANCH["ovsdbapp"]=${OVSDBAPP_BRANCH:-$TARGET_BRANCH}
GITDIR["ovsdbapp"]=$DEST/ovsdbapp
# Defaults Overwrite
# ------------------
Q_PLUGIN=${Q_PLUGIN:-"ml2"}
Q_AGENT=${Q_AGENT:-""}
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,dns}
# TODO(lucasagomes): Modify this after the networking-ovn code is
# merged into Neutron
ML2_L3_PLUGIN="networking_ovn.l3.l3_ovn.OVNL3RouterPlugin,trunk"
# Utility Functions
# -----------------
function is_kernel_module_loaded {
if lsmod | grep $1 >& /dev/null; then
return 0
else
return 1
fi
}
function use_new_ovn_repository {
# IF OVN_BRANCH is "master" or branch-2.13 (or higher), use the new
# OVN repository
if [ "$OVN_BRANCH" == "master" ] || \
[ $(echo $OVN_BRANCH | sed -e 's/^branch-\([0-9]*\)\.//') -ge 13 ]; then
return 0
else
return 1
fi
}
# 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="ovs-vsctl --no-wait -- --may-exist add-br $bridge"
if [ "$OVS_DATAPATH_TYPE" != "system" ] ; then
addbr_cmd="$addbr_cmd -- set Bridge $bridge datapath_type=${OVS_DATAPATH_TYPE}"
fi
$addbr_cmd
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 branch=$2
repo_name=$(basename ${repo} | cut -f1 -d'.')
REPO_DIR=$DEST/$repo_name
if [ ! -d $REPO_DIR ] ; then
git_timed clone $repo $REPO_DIR
pushd $REPO_DIR
git checkout $branch
popd
else
# Even though the directory already exists, call git_clone to update it
# if needed based on the RECLONE option
git_clone $repo $REPO_DIR $branch
fi
}
function get_ext_gw_interface {
# Get ext_gw_interface depending on value of Q_USE_PUBLIC_VETH
# This function is copied directly from the devstack neutron-legacy script
if [[ "$Q_USE_PUBLIC_VETH" == "True" ]]; then
echo $Q_PUBLIC_VETH_EX
else
# Disable in-band as we are going to use local port
# to communicate with VMs
sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE \
other_config:disable-in-band=true
echo $PUBLIC_BRIDGE
fi
}
function create_public_bridge {
# Create the public bridge that OVN will use
# This logic is based on the devstack neutron-legacy _neutron_configure_router_v4 and _v6
local ext_gw_ifc
ext_gw_ifc=$(get_ext_gw_interface)
ovs-vsctl --may-exist add-br $ext_gw_ifc -- set bridge $ext_gw_ifc protocols=OpenFlow13
ovs-vsctl set open . external-ids:ovn-bridge-mappings=$PHYSICAL_NETWORK:$ext_gw_ifc
if [ -n "$FLOATING_RANGE" ]; then
local cidr_len=${FLOATING_RANGE#*/}
sudo ip addr add $PUBLIC_NETWORK_GATEWAY/$cidr_len dev $ext_gw_ifc
fi
# Ensure IPv6 RAs are accepted on the interface with the default route.
# This is needed for neutron-based devstack clouds to work in
# IPv6-only clouds in the gate. Please do not remove this without
# talking to folks in Infra. This fix is based on a devstack fix for
# neutron L3 agent: https://review.openstack.org/#/c/359490/.
default_route_dev=$(ip route | grep ^default | awk '{print $5}')
sudo sysctl -w net.ipv6.conf.$default_route_dev.accept_ra=2
sudo sysctl -w net.ipv6.conf.all.forwarding=1
if [ -n "$IPV6_PUBLIC_RANGE" ]; then
local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/}
sudo ip -6 addr add $IPV6_PUBLIC_NETWORK_GATEWAY/$ipv6_cidr_len dev $ext_gw_ifc
# NOTE(numans): Commenting the below code for now as this is breaking
# the CI after xenial upgrade.
# https://bugs.launchpad.net/networking-ovn/+bug/1648670
# sudo ip -6 route replace $FIXED_RANGE_V6 via $IPV6_PUBLIC_NETWORK_GATEWAY dev $ext_gw_ifc
fi
sudo ip link set $ext_gw_ifc up
}
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
# -------------------------
# Fetch the ovs git repository and install packages needed for
# the compilation.
function _prepare_for_ovs_compilation {
local build_modules=$1
clone_repository $OVS_REPO $OVS_BRANCH
if [[ "$build_modules" == "False" ]]; then
return
fi
KERNEL_VERSION=`uname -r`
if is_fedora ; then
# is_fedora covers Fedora, RHEL, CentOS, etc...
if [[ "$os_VENDOR" == "Fedora" ]]; then
install_package elfutils-libelf-devel
KERNEL_VERSION=`echo $KERNEL_VERSION | cut --delimiter='-' --field 1`
elif [[ ${KERNEL_VERSION:0:2} != "3." ]]; then
# dash is illegal character in rpm version so replace
# them with underscore like it is done in the kernel
# https://github.com/torvalds/linux/blob/master/scripts/package/mkspec#L25
# but only for latest series of the kernel, not 3.x
KERNEL_VERSION=`echo $KERNEL_VERSION | tr - _`
fi
echo NOTE: if kernel-devel-$KERNEL_VERSION or kernel-headers-$KERNEL_VERSION installation
echo failed, please, provide a repository with the package, or yum update / reboot
echo your machine to get the latest kernel.
install_package kernel-devel-$KERNEL_VERSION
install_package kernel-headers-$KERNEL_VERSION
elif is_ubuntu ; then
install_package linux-headers-$KERNEL_VERSION
fi
}
# Reload the ovs kernel modules
function _reload_ovs_kernel_modules {
ovs_system=$(sudo ovs-dpctl dump-dps | grep ovs-system)
if [ -n "$ovs_system" ]; then
sudo ovs-dpctl del-dp ovs-system
fi
sudo modprobe -r vport_geneve
sudo modprobe -r openvswitch
sudo modprobe openvswitch || (dmesg && die $LINENO "FAILED TO LOAD openvswitch")
sudo modprobe vport-geneve || (dmesg && echo "FAILED TO LOAD vport-geneve")
}
# Compile openvswitch and its kernel module
function _compile_ovs {
local build_modules=$1
# Install the dependencies
install_package autoconf automake libtool gcc patch make
# TODO(flaviof): Would prefer to use pip_install wrapper, but that is not
# useable right now because REQUIREMENTS_DIR variable is hard coded in
# starckrc
sudo pip3 install six
_prepare_for_ovs_compilation $build_modules
pushd $DEST/$OVS_REPO_NAME
[ -f configure ] || ./boot.sh
if [ ! -f config.status ] || [ configure -nt config.status ] ; then
if [[ "$build_modules" == "True" ]]; then
./configure --with-linux=/lib/modules/$(uname -r)/build
else
./configure
fi
fi
make -j$(($(nproc) + 1))
sudo make install
if [[ "$build_modules" == "True" ]]; then
sudo make INSTALL_MOD_DIR=kernel/net/openvswitch modules_install
if [ $? -eq 0 ]; then
_reload_ovs_kernel_modules
else
echo "Compiling OVS kernel modules failed"
fi
fi
popd
}
# 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
# First, compile OVS
_compile_ovs $build_modules
if [ -n "$prefix" ]; then
prefix="--prefix=$prefix"
fi
if [ -n "$localstatedir" ]; then
localstatedir="--localstatedir=$localstatedir"
fi
clone_repository $OVN_REPO $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 [[ ! $Q_ML2_PLUGIN_MECHANISM_DRIVERS =~ "ovn" ]]; then
die $LINENO "OVN needs to be enabled in \$Q_ML2_PLUGIN_MECHANISM_DRIVERS"
elif [[ ! $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 {
echo "Installing OVN and dependent packages"
# Check the OVN configuration
ovn_sanity_check
# 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
# Install tox, used to generate the config (see devstack/override-defaults)
pip_install tox
source $NEUTRON_DIR/devstack/lib/ovs
remove_ovs_packages
sudo rm -f $OVS_RUNDIR/*
if use_new_ovn_repository; then
compile_ovn $OVN_BUILD_MODULES
else
compile_ovs $OVN_BUILD_MODULES
fi
sudo mkdir -p $OVS_RUNDIR
sudo chown $(whoami) $OVS_RUNDIR
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
# 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
# TODO(lucasagomes): Remove this after the networking-ovn code is
# merged into Neutron
git_clone $NETWORKING_OVN_REPO $NETWORKING_OVN_DIR $NETWORKING_OVN_BRANCH
setup_develop $NETWORKING_OVN_DIR
# 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 $OVS_BRANCH
sudo pip install -e $DEST/$OVS_REPO_NAME/python
fi
}
function configure_ovn_plugin {
echo "Configuring Neutron for OVN"
if is_service_enabled q-svc ; then
# NOTE(arosen) needed for tempest
export NETWORK_API_EXTENSIONS=$($PYTHON -c \
'from neutron.common.ovn import extensions ;\
print(",".join(extensions.ML2_SUPPORTED_API_EXTENSIONS))')
export NETWORK_API_EXTENSIONS=$NETWORK_API_EXTENSIONS,$($PYTHON -c \
'from neutron.common.ovn import extensions ;\
print(",".join(extensions.ML2_SUPPORTED_API_EXTENSIONS_OVN_L3))')
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"
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 networking-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
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 networking-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 ./ovn-uuid ] ; then
OVN_UUID=$(cat ovn-uuid)
else
OVN_UUID=$(uuidgen)
echo $OVN_UUID > ovn-uuid
fi
fi
# Metadata
if is_service_enabled networking-ovn-metadata-agent && is_service_enabled ovn-controller; then
sudo install -d -o $STACK_USER $NEUTRON_CONF_DIR
mkdir -p $NETWORKING_OVN_DIR/etc/neutron/plugins/ml2
(cd $NETWORKING_OVN_DIR && exec ./tools/generate_config_file_samples.sh)
cp $NETWORKING_OVN_DIR/etc/networking_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 $SERVICE_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 unix:$OVS_RUNDIR/db.sock
iniset $OVN_META_CONF ovn ovn_sb_connection $OVN_SB_REMOTE
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 || is_service_enabled ovn-controller-vtep ; then
# ovsdb-server and ovs-vswitchd are used privately in OVN as openvswitch service names.
enable_service ovsdb-server
enable_service ovs-vswitchd
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:127.0.0.1 --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"
echo "Configuring OVSDB"
ovs-vsctl --no-wait set open_vswitch . system-type="devstack"
ovs-vsctl --no-wait set open_vswitch . external-ids:system-id="$OVN_UUID"
ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-remote="$OVN_SB_REMOTE"
ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-bridge="br-int"
ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-encap-type="geneve"
ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-encap-ip="$HOST_IP"
# Select this chassis to host gateway routers
if [[ "$ENABLE_CHASSIS_AS_GW" == "True" ]]; then
ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-cms-options="enable-chassis-as-gw"
fi
ovn_base_setup_bridge br-int
ovs-vsctl --no-wait set bridge br-int fail-mode=secure other-config:disable-in-band=true
local ovscmd="$OVS_SBINDIR/ovs-vswitchd --log-file --pidfile --detach"
_run_process ovs-vswitchd "$ovscmd" "" "$STACK_USER" "root"
if is_provider_network || [[ $Q_USE_PROVIDERNET_FOR_PUBLIC == "True" ]]; then
ovn_base_setup_bridge $OVS_PHYSICAL_BRIDGE
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_USER" "root"
vtep-ctl set-manager tcp:$HOST_IP:6640
fi
fi
cd $_pwd
}
function _start_ovn_services {
_start_process "devstack@ovsdb-server.service"
_start_process "devstack@ovs-vswitchd.service"
if is_service_enabled ovs-vtep ; then
_start_process "devstack@ovs-vtep.service"
fi
if is_service_enabled ovn-northd ; then
_start_process "devstack@ovn-northd.service"
fi
if is_service_enabled ovn-controller ; then
_start_process "devstack@ovn-controller.service"
fi
if is_service_enabled ovn-controller-vtep ; then
_start_process "devstack@ovn-controller-vtep.service"
fi
if is_service_enabled networking-ovn-metadata-agent; then
_start_process "devstack@networking-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
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"
ovn-nbctl --db=unix:$OVS_RUNDIR/ovnnb_db.sock set-connection ptcp:6641:0.0.0.0 -- set connection . inactivity_probe=60000
ovn-sbctl --db=unix:$OVS_RUNDIR/ovnsb_db.sock set-connection ptcp:6642:0.0.0.0 -- 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
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_USER" "root"
fi
if is_service_enabled ovn-controller-vtep ; then
local cmd="$OVS_BINDIR/ovn-controller-vtep --log-file --pidfile --detach --ovnsb-db=$OVN_SB_REMOTE"
_run_process ovn-controller-vtep "$cmd" "" "$STACK_USER" "root"
fi
if is_service_enabled networking-ovn-metadata-agent; then
run_process networking-ovn-metadata-agent "$NETWORKING_OVN_BIN_DIR/$NETWORKING_OVN_METADATA_BINARY --config-file $OVN_META_CONF"
# Format logging
setup_logging $OVN_META_CONF
fi
if is_service_enabled br-ex-tcpdump ; then
# tcpdump monitor on br-ex for ARP, reverse ARP and ICMP v4 / v6 packets
sudo ip link set dev $PUBLIC_BRIDGE up
run_process br-ex-tcpdump "/usr/sbin/tcpdump -i $PUBLIC_BRIDGE arp or rarp or icmp or icmp6 -enlX" $STACK_USER root
fi
if is_service_enabled br-int-flows ; then
run_process br-int-flows "/bin/sh -c \"set +e; while true; do echo ovs-ofctl dump-flows br-int; ovs-ofctl dump-flows br-int ; sleep 30; done; \"" $STACK_USER root
fi
# 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
if use_new_ovn_repository; then
sudo ln -s $OVS_RUNDIR $OVN_RUNDIR
fi
_start_ovn_services
}
function _stop_ovs_dp {
sudo ovs-dpctl dump-dps | sudo xargs -n1 ovs-dpctl del-dp
is_kernel_module_loaded vport_geneve && sudo rmmod vport_geneve
is_kernel_module_loaded vport_vxlan && sudo rmmod vport_vxlan
is_kernel_module_loaded openvswitch && sudo rmmod openvswitch
}
function stop_ovn {
if is_service_enabled networking-ovn-metadata-agent; then
sudo pkill -9 -f haproxy || :
stop_process networking-ovn-metadata-agent
fi
if is_service_enabled ovn-controller-vtep ; then
stop_process ovn-controller-vtep
fi
if is_service_enabled ovn-controller ; then
stop_process ovn-controller
fi
if is_service_enabled ovn-northd ; then
stop_process ovn-northd
fi
if is_service_enabled ovs-vtep ; then
stop_process ovs-vtep
fi
stop_process ovs-vswitchd
stop_process ovsdb-server
_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
}

View File

@ -19,6 +19,11 @@ source $LIBDIR/uplink_status_propagation
Q_BUILD_OVS_FROM_GIT=$(trueorfalse False Q_BUILD_OVS_FROM_GIT)
function is_ovn_enabled {
[[ $NEUTRON_AGENT == "ovn" ]] && return 0
return 1
}
if [ -f $LIBDIR/${NEUTRON_AGENT}_agent ]; then
source $LIBDIR/${NEUTRON_AGENT}_agent
fi
@ -33,6 +38,11 @@ if [[ "$1" == "stack" ]]; then
load_conntrack_gre_module
start_new_ovs
fi
if is_ovn_enabled; then
install_ovn
configure_ovn
init_ovn
fi
;;
post-config)
if is_service_enabled neutron-uplink-status-propagation; then
@ -94,11 +104,26 @@ if [[ "$1" == "stack" ]]; then
if [ $NEUTRON_CORE_PLUGIN = ml2 ]; then
configure_ml2_extension_drivers
fi
if is_ovn_enabled; then
configure_ovn_plugin
start_ovn
fi
;;
extra)
if is_service_enabled q-sriov-agt neutron-sriov-agent; then
start_l2_agent_sriov
fi
if is_ovn_enabled; then
if [[ "$OVN_L3_CREATE_PUBLIC_NETWORK" == "True" ]]; then
if [[ "$NEUTRON_CREATE_INITIAL_NETWORKS" != "True" ]]; then
echo "OVN_L3_CREATE_PUBLIC_NETWORK=True is being ignored because"
echo "NEUTRON_CREATE_INITIAL_NETWORKS is set to False"
else
create_public_bridge
fi
fi
fi
;;
esac
elif [[ "$1" == "unstack" ]]; then
@ -109,4 +134,9 @@ elif [[ "$1" == "unstack" ]]; then
[[ "$Q_BUILD_OVS_FROM_GIT" == "True" ]]; then
stop_new_ovs
fi
if is_ovn_enabled; then
stop_ovn
cleanup_ovn
fi
fi

View File

@ -0,0 +1,55 @@
#
# 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.
# NOTE(russellb) This remains in its own file (vs constants.py) because we want
# to be able to easily import it and export the info without any dependencies
# on external imports.
# NOTE(russellb) If you update these lists, please also update
# doc/source/features.rst and the current release note.
ML2_SUPPORTED_API_EXTENSIONS_OVN_L3 = [
'router',
'extraroute',
'ext-gw-mode',
'pagination',
'sorting',
'project-id',
'dns-integration',
]
ML2_SUPPORTED_API_EXTENSIONS = [
'address-scope',
'agent',
'allowed-address-pairs',
'auto-allocated-topology',
'availability_zone',
'binding',
'default-subnetpools',
'external-net',
'extra_dhcp_opt',
'multi-provider',
'net-mtu',
'network_availability_zone',
'network-ip-availability',
'port-security',
'provider',
'quotas',
'rbac-policies',
'standard-attr-revisions',
'security-group',
'standard-attr-description',
'subnet_allocation',
'standard-attr-tag',
'standard-attr-timestamp',
'trunk',
'quota_details',
]