blob: f647f85c3ddec8f6d8647be794b218fd6861de1b [file] [log] [blame]
Lucas Alvares Gomes1d468d42020-06-09 14:35:52 +01001#!/bin/bash
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14#
15
16# Global Sources
17# --------------
18
19# There are some ovs functions OVN depends on that must be sourced from
20# the ovs neutron plugins.
21source ${TOP_DIR}/lib/neutron_plugins/ovs_base
22source ${TOP_DIR}/lib/neutron_plugins/openvswitch_agent
23
24# Load devstack ovs base functions
25source $NEUTRON_DIR/devstack/lib/ovs
26
27
28# Defaults
29# --------
30
31# Set variables for building OVN from source
32OVN_REPO=${OVN_REPO:-https://github.com/ovn-org/ovn.git}
33OVN_REPO_NAME=$(basename ${OVN_REPO} | cut -f1 -d'.')
34OVN_REPO_NAME=${OVN_REPO_NAME:-ovn}
35OVN_BRANCH=${OVN_BRANCH:-v20.06.1}
36# The commit removing OVN bits from the OVS tree, it is the commit that is not
37# present in OVN tree and is used to distinguish if OVN is part of OVS or not.
38# https://github.com/openvswitch/ovs/commit/05bf1dbb98b0635a51f75e268ef8aed27601401d
39OVN_SPLIT_HASH=05bf1dbb98b0635a51f75e268ef8aed27601401d
40
41if is_service_enabled tls-proxy; then
42 OVN_PROTO=ssl
43else
44 OVN_PROTO=tcp
45fi
46
47# How to connect to ovsdb-server hosting the OVN SB database.
48OVN_SB_REMOTE=${OVN_SB_REMOTE:-$OVN_PROTO:$SERVICE_HOST:6642}
49
50# How to connect to ovsdb-server hosting the OVN NB database
51OVN_NB_REMOTE=${OVN_NB_REMOTE:-$OVN_PROTO:$SERVICE_HOST:6641}
52
53# ml2/config for neutron_sync_mode
54OVN_NEUTRON_SYNC_MODE=${OVN_NEUTRON_SYNC_MODE:-log}
55
56# Configured DNS servers to be used with internal_dns extension, only
57# if the subnet DNS is not configured.
58OVN_DNS_SERVERS=${OVN_DNS_SERVERS:-8.8.8.8}
59
60# The type of OVN L3 Scheduler to use. The OVN L3 Scheduler determines the
61# hypervisor/chassis where a routers gateway should be hosted in OVN. The
62# default OVN L3 scheduler is leastloaded
63OVN_L3_SCHEDULER=${OVN_L3_SCHEDULER:-leastloaded}
64
65# A UUID to uniquely identify this system. If one is not specified, a random
66# one will be generated. A randomly generated UUID will be saved in a file
67# 'ovn-uuid' so that the same one will be re-used if you re-run DevStack.
68OVN_UUID=${OVN_UUID:-}
69
70# Whether or not to build the openvswitch kernel module from ovs. This is required
71# unless the distro kernel includes ovs+conntrack support.
72OVN_BUILD_MODULES=$(trueorfalse False OVN_BUILD_MODULES)
73
74# Whether or not to install the ovs python module from ovs source. This can be
75# used to test and validate new ovs python features. This should only be used
76# for development purposes since the ovs python version is controlled by OpenStack
77# requirements.
78OVN_INSTALL_OVS_PYTHON_MODULE=$(trueorfalse False OVN_INSTALL_OVS_PYTHON_MODULE)
79
80# GENEVE overlay protocol overhead. Defaults to 38 bytes plus the IP version
81# overhead (20 bytes for IPv4 (default) or 40 bytes for IPv6) which is determined
82# based on the ML2 overlay_ip_version option. The ML2 framework will use this to
83# configure the MTU DHCP option.
84OVN_GENEVE_OVERHEAD=${OVN_GENEVE_OVERHEAD:-38}
85
86# The log level of the OVN databases (north and south)
87OVN_DBS_LOG_LEVEL=${OVN_DBS_LOG_LEVEL:-info}
88
89OVN_META_CONF=$NEUTRON_CONF_DIR/neutron_ovn_metadata_agent.ini
90OVN_META_DATA_HOST=${OVN_META_DATA_HOST:-$(ipv6_unquote $SERVICE_HOST)}
91
92OVSDB_SERVER_LOCAL_HOST=$SERVICE_LOCAL_HOST
93
94OVN_IGMP_SNOOPING_ENABLE=$(trueorfalse False OVN_IGMP_SNOOPING_ENABLE)
95
96OVS_PREFIX=/usr/local
97OVS_SBINDIR=$OVS_PREFIX/sbin
98OVS_BINDIR=$OVS_PREFIX/bin
99OVS_RUNDIR=$OVS_PREFIX/var/run/openvswitch
100OVS_SHAREDIR=$OVS_PREFIX/share/openvswitch
101OVS_SCRIPTDIR=$OVS_SHAREDIR/scripts
102OVS_DATADIR=$DATA_DIR/ovs
103
104OVN_DATADIR=$DATA_DIR/ovn
105OVN_SHAREDIR=$OVS_PREFIX/share/ovn
106OVN_SCRIPTDIR=$OVN_SHAREDIR/scripts
107OVN_RUNDIR=$OVS_PREFIX/var/run/ovn
108
109NEUTRON_OVN_BIN_DIR=$(get_python_exec_prefix)
110NEUTRON_OVN_METADATA_BINARY="neutron-ovn-metadata-agent"
111
112STACK_GROUP="$( id --group --name "$STACK_USER" )"
113
114# Defaults Overwrite
115# ------------------
116
117Q_ML2_PLUGIN_MECHANISM_DRIVERS=${Q_ML2_PLUGIN_MECHANISM_DRIVERS:-ovn,logger}
118Q_ML2_PLUGIN_TYPE_DRIVERS=${Q_ML2_PLUGIN_TYPE_DRIVERS:-local,flat,vlan,geneve}
119Q_ML2_TENANT_NETWORK_TYPE=${Q_ML2_TENANT_NETWORK_TYPE:-"geneve"}
120Q_ML2_PLUGIN_GENEVE_TYPE_OPTIONS=${Q_ML2_PLUGIN_GENEVE_TYPE_OPTIONS:-"vni_ranges=1:65536"}
Lucas Alvares Gomese7625fc2020-08-26 09:46:35 +0100121Q_ML2_PLUGIN_EXT_DRIVERS=${Q_ML2_PLUGIN_EXT_DRIVERS:-port_security,qos}
Lucas Alvares Gomes1d468d42020-06-09 14:35:52 +0100122# this one allows empty:
123ML2_L3_PLUGIN=${ML2_L3_PLUGIN-"ovn-router"}
124
125
126# Utility Functions
127# -----------------
128
129function use_new_ovn_repository {
130 if [ -z "$is_new_ovn" ]; then
131 local ovs_repo_dir=$DEST/$OVS_REPO_NAME
132 if [ ! -d $ovs_repo_dir ]; then
133 clone_repository $OVS_REPO $ovs_repo_dir $OVS_BRANCH
134 fi
135 # Check the split commit exists in the current branch
136 pushd $ovs_repo_dir
137 git log $OVS_BRANCH --pretty=format:"%H" | grep -q $OVN_SPLIT_HASH
138 is_new_ovn=$?
139 popd
140 fi
141 return $is_new_ovn
142}
143
144# NOTE(rtheis): Function copied from DevStack _neutron_ovs_base_setup_bridge
145# and _neutron_ovs_base_add_bridge with the call to neutron-ovs-cleanup
146# removed. The call is not relevant for OVN, as it is specific to the use
147# of Neutron's OVS agent and hangs when running stack.sh because
148# neutron-ovs-cleanup uses the OVSDB native interface.
149function ovn_base_setup_bridge {
150 local bridge=$1
151 local addbr_cmd="ovs-vsctl --no-wait -- --may-exist add-br $bridge -- set bridge $bridge protocols=OpenFlow13,OpenFlow15"
152
153 if [ "$OVS_DATAPATH_TYPE" != "system" ] ; then
154 addbr_cmd="$addbr_cmd -- set Bridge $bridge datapath_type=${OVS_DATAPATH_TYPE}"
155 fi
156
157 $addbr_cmd
158 ovs-vsctl --no-wait br-set-external-id $bridge bridge-id $bridge
159}
160
161function _start_process {
162 $SYSTEMCTL daemon-reload
163 $SYSTEMCTL enable $1
164 $SYSTEMCTL restart $1
165}
166
167function _run_process {
168 local service=$1
169 local cmd="$2"
170 local stop_cmd="$3"
171 local group=$4
172 local user=${5:-$STACK_USER}
173
174 local systemd_service="devstack@$service.service"
175 local unit_file="$SYSTEMD_DIR/$systemd_service"
176 local environment="OVN_RUNDIR=$OVS_RUNDIR OVN_DBDIR=$OVN_DATADIR OVN_LOGDIR=$LOGDIR OVS_RUNDIR=$OVS_RUNDIR OVS_DBDIR=$OVS_DATADIR OVS_LOGDIR=$LOGDIR"
177
178 echo "Starting $service executed command": $cmd
179
180 write_user_unit_file $systemd_service "$cmd" "$group" "$user"
181 iniset -sudo $unit_file "Service" "Type" "forking"
182 iniset -sudo $unit_file "Service" "RemainAfterExit" "yes"
183 iniset -sudo $unit_file "Service" "KillMode" "mixed"
184 iniset -sudo $unit_file "Service" "LimitNOFILE" "65536"
185 iniset -sudo $unit_file "Service" "Environment" "$environment"
186 if [ -n "$stop_cmd" ]; then
187 iniset -sudo $unit_file "Service" "ExecStop" "$stop_cmd"
188 fi
189
190 _start_process $systemd_service
191
192 local testcmd="test -e $OVS_RUNDIR/$service.pid"
193 test_with_retry "$testcmd" "$service did not start" $SERVICE_TIMEOUT 1
194 sudo ovs-appctl -t $service vlog/set console:off syslog:info file:info
195}
196
197function clone_repository {
198 local repo=$1
199 local dir=$2
200 local branch=$3
201 # Set ERROR_ON_CLONE to false to avoid the need of having the
202 # repositories like OVN and OVS in the required_projects of the job
203 # definition.
204 ERROR_ON_CLONE=false git_clone $repo $dir $branch
205}
206
207function get_ext_gw_interface {
208 # Get ext_gw_interface depending on value of Q_USE_PUBLIC_VETH
209 # This function is copied directly from the devstack neutron-legacy script
210 if [[ "$Q_USE_PUBLIC_VETH" == "True" ]]; then
211 echo $Q_PUBLIC_VETH_EX
212 else
213 # Disable in-band as we are going to use local port
214 # to communicate with VMs
215 sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE \
216 other_config:disable-in-band=true
217 echo $PUBLIC_BRIDGE
218 fi
219}
220
221function create_public_bridge {
222 # Create the public bridge that OVN will use
223 # This logic is based on the devstack neutron-legacy _neutron_configure_router_v4 and _v6
224 local ext_gw_ifc
225 ext_gw_ifc=$(get_ext_gw_interface)
226
227 ovs-vsctl --may-exist add-br $ext_gw_ifc -- set bridge $ext_gw_ifc protocols=OpenFlow13,OpenFlow15
228 ovs-vsctl set open . external-ids:ovn-bridge-mappings=$PHYSICAL_NETWORK:$ext_gw_ifc
229 if [ -n "$FLOATING_RANGE" ]; then
230 local cidr_len=${FLOATING_RANGE#*/}
231 sudo ip addr flush dev $ext_gw_ifc
232 sudo ip addr add $PUBLIC_NETWORK_GATEWAY/$cidr_len dev $ext_gw_ifc
233 fi
234
235 # Ensure IPv6 RAs are accepted on the interface with the default route.
236 # This is needed for neutron-based devstack clouds to work in
237 # IPv6-only clouds in the gate. Please do not remove this without
238 # talking to folks in Infra. This fix is based on a devstack fix for
239 # neutron L3 agent: https://review.openstack.org/#/c/359490/.
240 default_route_dev=$(ip route | grep ^default | awk '{print $5}')
241 sudo sysctl -w net.ipv6.conf.$default_route_dev.accept_ra=2
242
243 sudo sysctl -w net.ipv6.conf.all.forwarding=1
244 if [ -n "$IPV6_PUBLIC_RANGE" ]; then
245 local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/}
246 sudo ip -6 addr flush dev $ext_gw_ifc
247 sudo ip -6 addr add $IPV6_PUBLIC_NETWORK_GATEWAY/$ipv6_cidr_len dev $ext_gw_ifc
248 fi
249
250 sudo ip link set $ext_gw_ifc up
251}
252
253function _disable_libvirt_apparmor {
254 if ! sudo aa-status --enabled ; then
255 return 0
256 fi
257 # NOTE(arosen): This is used as a work around to allow newer versions
258 # of libvirt to work with ovs configured ports. See LP#1466631.
259 # requires the apparmor-utils
260 install_package apparmor-utils
261 # disables apparmor for libvirtd
262 sudo aa-complain /etc/apparmor.d/usr.sbin.libvirtd
263}
264
265
266# OVN compilation functions
267# -------------------------
268
269
270# compile_ovn() - Compile OVN from source and load needed modules
271# Accepts three parameters:
272# - first optional is False by default and means that
273# modules are built and installed.
274# - second optional parameter defines prefix for
275# ovn compilation
276# - third optional parameter defines localstatedir for
277# ovn single machine runtime
278function compile_ovn {
279 local build_modules=${1:-False}
280 local prefix=$2
281 local localstatedir=$3
282
283 if [ -n "$prefix" ]; then
284 prefix="--prefix=$prefix"
285 fi
286
287 if [ -n "$localstatedir" ]; then
288 localstatedir="--localstatedir=$localstatedir"
289 fi
290
291 clone_repository $OVN_REPO $DEST/$OVN_REPO_NAME $OVN_BRANCH
292 pushd $DEST/$OVN_REPO_NAME
293
294 if [ ! -f configure ] ; then
295 ./boot.sh
296 fi
297
298 if [ ! -f config.status ] || [ configure -nt config.status ] ; then
299 ./configure --with-ovs-source=$DEST/$OVS_REPO_NAME $prefix $localstatedir
300 fi
301 make -j$(($(nproc) + 1))
302 sudo make install
303 popd
304}
305
306
307# OVN Neutron driver functions
308# ----------------------------
309
310# OVN service sanity check
311function ovn_sanity_check {
312 if is_service_enabled q-agt neutron-agt; then
313 die $LINENO "The q-agt/neutron-agt service must be disabled with OVN."
314 elif is_service_enabled q-l3 neutron-l3; then
315 die $LINENO "The q-l3/neutron-l3 service must be disabled with OVN."
316 elif is_service_enabled q-svc neutron-api && [[ ! $Q_ML2_PLUGIN_MECHANISM_DRIVERS =~ "ovn" ]]; then
317 die $LINENO "OVN needs to be enabled in \$Q_ML2_PLUGIN_MECHANISM_DRIVERS"
318 elif is_service_enabled q-svc neutron-api && [[ ! $Q_ML2_PLUGIN_TYPE_DRIVERS =~ "geneve" ]]; then
319 die $LINENO "Geneve needs to be enabled in \$Q_ML2_PLUGIN_TYPE_DRIVERS to be used with OVN"
320 fi
321}
322
323# install_ovn() - Collect source and prepare
324function install_ovn {
325 echo "Installing OVN and dependent packages"
326
327 # Check the OVN configuration
328 ovn_sanity_check
329
330 # If OVS is already installed, remove it, because we're about to re-install
331 # it from source.
332 for package in openvswitch openvswitch-switch openvswitch-common; do
333 if is_package_installed $package ; then
334 uninstall_package $package
335 fi
336 done
337
338 # Install tox, used to generate the config (see devstack/override-defaults)
339 pip_install tox
340 remove_ovs_packages
341 sudo rm -f $OVS_RUNDIR/*
342
343 compile_ovs $OVN_BUILD_MODULES
344 if use_new_ovn_repository; then
345 compile_ovn $OVN_BUILD_MODULES
346 fi
347
348 # Ensure that the OVS commands are accessible in the PATH
349 OVS_BINDIR=${OVS_BINDIR:-/usr/local/bin}
350 export PATH=$OVS_BINDIR:$PATH
351
352 sudo mkdir -p $OVS_RUNDIR
353 sudo chown $(whoami) $OVS_RUNDIR
354 sudo mkdir -p $OVS_PREFIX/var/log/openvswitch
355 sudo chown $(whoami) $OVS_PREFIX/var/log/openvswitch
356 sudo mkdir -p $OVS_PREFIX/var/log/ovn
357 sudo chown $(whoami) $OVS_PREFIX/var/log/ovn
358
359 # Archive log files and create new
360 local log_archive_dir=$LOGDIR/archive
361 mkdir -p $log_archive_dir
362 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
363 if [ -f "$LOGDIR/$logfile" ] ; then
364 mv "$LOGDIR/$logfile" "$log_archive_dir/$logfile.${CURRENT_LOG_TIME}"
365 fi
366 done
367
368 # Install ovsdbapp from source if requested
369 if use_library_from_git "ovsdbapp"; then
370 git_clone_by_name "ovsdbapp"
371 setup_dev_lib "ovsdbapp"
372 fi
373
374 # Install ovs python module from ovs source.
375 if [[ "$OVN_INSTALL_OVS_PYTHON_MODULE" == "True" ]]; then
376 sudo pip uninstall -y ovs
377 # Clone the OVS repository if it's not yet present
378 clone_repository $OVS_REPO $DEST/$OVS_REPO_NAME $OVS_BRANCH
379 sudo pip install -e $DEST/$OVS_REPO_NAME/python
380 fi
381}
382
383# filter_network_api_extensions() - Remove non-supported API extensions by
384# the OVN driver from the list of enabled API extensions
385function filter_network_api_extensions {
386 SUPPORTED_NETWORK_API_EXTENSIONS=$($PYTHON -c \
387 'from neutron.common.ovn import extensions ;\
388 print(",".join(extensions.ML2_SUPPORTED_API_EXTENSIONS))')
389 SUPPORTED_NETWORK_API_EXTENSIONS=$SUPPORTED_NETWORK_API_EXTENSIONS,$($PYTHON -c \
390 'from neutron.common.ovn import extensions ;\
391 print(",".join(extensions.ML2_SUPPORTED_API_EXTENSIONS_OVN_L3))')
392 if is_service_enabled q-qos neutron-qos ; then
393 SUPPORTED_NETWORK_API_EXTENSIONS="$SUPPORTED_NETWORK_API_EXTENSIONS,qos"
394 fi
395 NETWORK_API_EXTENSIONS=${NETWORK_API_EXTENSIONS:-$SUPPORTED_NETWORK_API_EXTENSIONS}
396 extensions=$(echo $NETWORK_API_EXTENSIONS | tr ', ' '\n' | sort -u)
397 supported_ext=$(echo $SUPPORTED_NETWORK_API_EXTENSIONS | tr ', ' '\n' | sort -u)
398 enabled_ext=$(comm -12 <(echo -e "$extensions") <(echo -e "$supported_ext"))
399 disabled_ext=$(comm -3 <(echo -e "$extensions") <(echo -e "$enabled_ext"))
400
401 # Log a message in case some extensions had to be disabled because
402 # they are not supported by the OVN driver
403 if [ ! -z "$disabled_ext" ]; then
404 _disabled=$(echo $disabled_ext | tr ' ' ',')
405 echo "The folling network API extensions have been disabled because they are not supported by OVN: $_disabled"
406 fi
407
408 # Export the final list of extensions that have been enabled and are
409 # supported by OVN
410 export NETWORK_API_EXTENSIONS=$(echo $enabled_ext | tr ' ' ',')
411}
412
413function configure_ovn_plugin {
414 echo "Configuring Neutron for OVN"
415
416 if is_service_enabled q-svc ; then
417 filter_network_api_extensions
418 populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_type_geneve max_header_size=$OVN_GENEVE_OVERHEAD
419 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_nb_connection="$OVN_NB_REMOTE"
420 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_sb_connection="$OVN_SB_REMOTE"
421 if is_service_enabled tls-proxy; then
422 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_sb_ca_cert="$INT_CA_DIR/ca-chain.pem"
423 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_sb_certificate="$INT_CA_DIR/$DEVSTACK_CERT_NAME.crt"
424 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_sb_private_key="$INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key"
425 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_nb_ca_cert="$INT_CA_DIR/ca-chain.pem"
426 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_nb_certificate="$INT_CA_DIR/$DEVSTACK_CERT_NAME.crt"
427 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_nb_private_key="$INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key"
428 fi
429 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn neutron_sync_mode="$OVN_NEUTRON_SYNC_MODE"
430 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_l3_scheduler="$OVN_L3_SCHEDULER"
431 populate_ml2_config /$Q_PLUGIN_CONF_FILE securitygroup enable_security_group="$Q_USE_SECGROUP"
432 inicomment /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver
433
434 if is_service_enabled q-ovn-metadata-agent; then
435 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_metadata_enabled=True
436 else
437 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn ovn_metadata_enabled=False
438 fi
439
440 if is_service_enabled q-dns neutron-dns ; then
441 iniset $NEUTRON_CONF DEFAULT dns_domain openstackgate.local
442 populate_ml2_config /$Q_PLUGIN_CONF_FILE ovn dns_servers="$OVN_DNS_SERVERS"
443 fi
444
445 iniset $NEUTRON_CONF ovs igmp_snooping_enable $OVN_IGMP_SNOOPING_ENABLE
446 fi
447
448 if is_service_enabled q-dhcp neutron-dhcp ; then
449 iniset $NEUTRON_CONF DEFAULT dhcp_agent_notification True
450 else
451 iniset $NEUTRON_CONF DEFAULT dhcp_agent_notification False
452 fi
453
454 if is_service_enabled n-api-meta ; then
455 if is_service_enabled q-ovn-metadata-agent ; then
456 iniset $NOVA_CONF neutron service_metadata_proxy True
457 fi
458 fi
459}
460
461function configure_ovn {
462 echo "Configuring OVN"
463
464 if [ -z "$OVN_UUID" ] ; then
465 if [ -f ./ovn-uuid ] ; then
466 OVN_UUID=$(cat ovn-uuid)
467 else
468 OVN_UUID=$(uuidgen)
469 echo $OVN_UUID > ovn-uuid
470 fi
471 fi
472
473 # Metadata
474 if is_service_enabled q-ovn-metadata-agent && is_service_enabled ovn-controller; then
475 sudo install -d -o $STACK_USER $NEUTRON_CONF_DIR
476
477 mkdir -p $NEUTRON_DIR/etc/neutron/plugins/ml2
478 (cd $NEUTRON_DIR && exec ./tools/generate_config_file_samples.sh)
479
480 cp $NEUTRON_DIR/etc/neutron_ovn_metadata_agent.ini.sample $OVN_META_CONF
481 configure_root_helper_options $OVN_META_CONF
482
483 iniset $OVN_META_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
484 iniset $OVN_META_CONF DEFAULT nova_metadata_host $OVN_META_DATA_HOST
485 iniset $OVN_META_CONF DEFAULT metadata_workers $API_WORKERS
486 iniset $OVN_META_CONF DEFAULT state_path $NEUTRON_STATE_PATH
487 iniset $OVN_META_CONF ovs ovsdb_connection unix:$OVS_RUNDIR/db.sock
488 iniset $OVN_META_CONF ovn ovn_sb_connection $OVN_SB_REMOTE
489 if is_service_enabled tls-proxy; then
490 iniset $OVN_META_CONF ovn \
491 ovn_sb_ca_cert $INT_CA_DIR/ca-chain.pem
492 iniset $OVN_META_CONF ovn \
493 ovn_sb_certificate $INT_CA_DIR/$DEVSTACK_CERT_NAME.crt
494 iniset $OVN_META_CONF ovn \
495 ovn_sb_private_key $INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key
496 fi
497 fi
498}
499
500function init_ovn {
501 # clean up from previous (possibly aborted) runs
502 # create required data files
503
504 # Assumption: this is a dedicated test system and there is nothing important
505 # in the ovn, ovn-nb, or ovs databases. We're going to trash them and
506 # create new ones on each devstack run.
507
508 _disable_libvirt_apparmor
509
510 mkdir -p $OVN_DATADIR
511 mkdir -p $OVS_DATADIR
512
513 rm -f $OVS_DATADIR/*.db
514 rm -f $OVS_DATADIR/.*.db.~lock~
515 rm -f $OVN_DATADIR/*.db
516 rm -f $OVN_DATADIR/.*.db.~lock~
517}
518
519function _start_ovs {
520 echo "Starting OVS"
521 if is_service_enabled ovn-controller ovn-controller-vtep ovn-northd; then
522 # ovsdb-server and ovs-vswitchd are used privately in OVN as openvswitch service names.
523 enable_service ovsdb-server
524 enable_service ovs-vswitchd
525
526 if [ ! -f $OVS_DATADIR/conf.db ]; then
527 ovsdb-tool create $OVS_DATADIR/conf.db $OVS_SHAREDIR/vswitch.ovsschema
528 fi
529
530 if is_service_enabled ovn-controller-vtep; then
531 if [ ! -f $OVS_DATADIR/vtep.db ]; then
532 ovsdb-tool create $OVS_DATADIR/vtep.db $OVS_SHAREDIR/vtep.ovsschema
533 fi
534 fi
535
536 local dbcmd="$OVS_SBINDIR/ovsdb-server --remote=punix:$OVS_RUNDIR/db.sock --remote=ptcp:6640:$OVSDB_SERVER_LOCAL_HOST --pidfile --detach --log-file"
537 dbcmd+=" --remote=db:Open_vSwitch,Open_vSwitch,manager_options"
538 if is_service_enabled ovn-controller-vtep; then
539 dbcmd+=" --remote=db:hardware_vtep,Global,managers $OVS_DATADIR/vtep.db"
540 fi
541 dbcmd+=" $OVS_DATADIR/conf.db"
542 _run_process ovsdb-server "$dbcmd"
543
544 echo "Configuring OVSDB"
545 if is_service_enabled tls-proxy; then
546 ovs-vsctl --no-wait set-ssl \
547 $INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key \
548 $INT_CA_DIR/$DEVSTACK_CERT_NAME.crt \
549 $INT_CA_DIR/ca-chain.pem
550 fi
551 ovs-vsctl --no-wait set open_vswitch . system-type="devstack"
552 ovs-vsctl --no-wait set open_vswitch . external-ids:system-id="$OVN_UUID"
553 ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-remote="$OVN_SB_REMOTE"
554 ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-bridge="br-int"
555 ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-encap-type="geneve"
556 ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-encap-ip="$HOST_IP"
557 # Select this chassis to host gateway routers
558 if [[ "$ENABLE_CHASSIS_AS_GW" == "True" ]]; then
559 ovs-vsctl --no-wait set open_vswitch . external-ids:ovn-cms-options="enable-chassis-as-gw"
560 fi
561
562 # Note: ovn-controller will create and configure br-int once it is started.
563 # So, no need to create it now because nothing depends on that bridge here.
564
565 local ovscmd="$OVS_SBINDIR/ovs-vswitchd --log-file --pidfile --detach"
566 _run_process ovs-vswitchd "$ovscmd" "" "$STACK_GROUP" "root"
567
568 if is_provider_network || [[ $Q_USE_PROVIDERNET_FOR_PUBLIC == "True" ]]; then
569 ovn_base_setup_bridge $OVS_PHYSICAL_BRIDGE
570 ovs-vsctl set open . external-ids:ovn-bridge-mappings=${PHYSICAL_NETWORK}:${OVS_PHYSICAL_BRIDGE}
571 fi
572
573 if is_service_enabled ovn-controller-vtep ; then
574 ovn_base_setup_bridge br-v
575 vtep-ctl add-ps br-v
576 vtep-ctl set Physical_Switch br-v tunnel_ips=$HOST_IP
577
578 enable_service ovs-vtep
579 local vtepcmd="$OVS_SCRIPTDIR/ovs-vtep --log-file --pidfile --detach br-v"
580 _run_process ovs-vtep "$vtepcmd" "" "$STACK_GROUP" "root"
581
582 vtep-ctl set-manager tcp:$HOST_IP:6640
583 fi
584 fi
585}
586
587function _start_ovn_services {
588 _start_process "devstack@ovsdb-server.service"
589 _start_process "devstack@ovs-vswitchd.service"
590
591 if is_service_enabled ovs-vtep ; then
592 _start_process "devstack@ovs-vtep.service"
593 fi
594 if is_service_enabled ovn-northd ; then
595 _start_process "devstack@ovn-northd.service"
596 fi
597 if is_service_enabled ovn-controller ; then
598 _start_process "devstack@ovn-controller.service"
599 fi
600 if is_service_enabled ovn-controller-vtep ; then
601 _start_process "devstack@ovn-controller-vtep.service"
602 fi
603 if is_service_enabled q-ovn-metadata-agent; then
604 _start_process "devstack@q-ovn-metadata-agent.service"
605 fi
606}
607
608# start_ovn() - Start running processes, including screen
609function start_ovn {
610 echo "Starting OVN"
611
612 _start_ovs
613
614 local SCRIPTDIR=$OVN_SCRIPTDIR
615 if ! use_new_ovn_repository; then
616 SCRIPTDIR=$OVS_SCRIPTDIR
617 fi
618
619 if is_service_enabled ovn-northd ; then
620 if is_service_enabled tls-proxy; then
621 local tls_args="\
622 --ovn-nb-db-ssl-ca-cert=$INT_CA_DIR/ca-chain.pem \
623 --ovn-nb-db-ssl-cert=$INT_CA_DIR/$DEVSTACK_CERT_NAME.crt \
624 --ovn-nb-db-ssl-key=$INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key \
625 --ovn-sb-db-ssl-ca-cert=$INT_CA_DIR/ca-chain.pem \
626 --ovn-sb-db-ssl-cert=$INT_CA_DIR/$DEVSTACK_CERT_NAME.crt \
627 --ovn-sb-db-ssl-key=$INT_CA_DIR/private/$DEVSTACK_CERT_NAME.key \
628 "
629 else
630 local tls_args=""
631 fi
632 local cmd="/bin/bash $SCRIPTDIR/ovn-ctl --no-monitor $tls_args start_northd"
633 local stop_cmd="/bin/bash $SCRIPTDIR/ovn-ctl stop_northd"
634
635 _run_process ovn-northd "$cmd" "$stop_cmd"
636 ovn-nbctl --db=unix:$OVS_RUNDIR/ovnnb_db.sock set-connection p${OVN_PROTO}:6641:$SERVICE_LISTEN_ADDRESS -- set connection . inactivity_probe=60000
637 ovn-sbctl --db=unix:$OVS_RUNDIR/ovnsb_db.sock set-connection p${OVN_PROTO}:6642:$SERVICE_LISTEN_ADDRESS -- set connection . inactivity_probe=60000
638 sudo ovs-appctl -t $OVS_RUNDIR/ovnnb_db.ctl vlog/set console:off syslog:$OVN_DBS_LOG_LEVEL file:$OVN_DBS_LOG_LEVEL
639 sudo ovs-appctl -t $OVS_RUNDIR/ovnsb_db.ctl vlog/set console:off syslog:$OVN_DBS_LOG_LEVEL file:$OVN_DBS_LOG_LEVEL
640 fi
641
642 if is_service_enabled ovn-controller ; then
643 local cmd="/bin/bash $SCRIPTDIR/ovn-ctl --no-monitor start_controller"
644 local stop_cmd="/bin/bash $SCRIPTDIR/ovn-ctl stop_controller"
645
646 _run_process ovn-controller "$cmd" "$stop_cmd" "$STACK_GROUP" "root"
647 fi
648
649 if is_service_enabled ovn-controller-vtep ; then
650 local cmd="$OVS_BINDIR/ovn-controller-vtep --log-file --pidfile --detach --ovnsb-db=$OVN_SB_REMOTE"
651
652 _run_process ovn-controller-vtep "$cmd" "" "$STACK_GROUP" "root"
653 fi
654
655 if is_service_enabled q-ovn-metadata-agent; then
656 run_process q-ovn-metadata-agent "$NEUTRON_OVN_BIN_DIR/$NEUTRON_OVN_METADATA_BINARY --config-file $OVN_META_CONF"
657 # Format logging
658 setup_logging $OVN_META_CONF
659 fi
660
661 # NOTE(lucasagomes): To keep things simpler, let's reuse the same
662 # RUNDIR for both OVS and OVN. This way we avoid having to specify the
663 # --db option in the ovn-{n,s}bctl commands while playing with DevStack
664 if use_new_ovn_repository; then
665 sudo ln -s $OVS_RUNDIR $OVN_RUNDIR
666 fi
667
668 _start_ovn_services
669}
670
671function _stop_ovs_dp {
672 sudo ovs-dpctl dump-dps | sudo xargs -n1 ovs-dpctl del-dp
673 modprobe -q -r vport_geneve vport_vxlan openvswitch || true
674}
675
676function stop_ovn {
677 if is_service_enabled q-ovn-metadata-agent; then
678 sudo pkill -9 -f haproxy || :
679 stop_process neutron-ovn-metadata-agent
680 fi
681 if is_service_enabled ovn-controller-vtep ; then
682 stop_process ovn-controller-vtep
683 fi
684 if is_service_enabled ovn-controller ; then
685 stop_process ovn-controller
686 fi
687 if is_service_enabled ovn-northd ; then
688 stop_process ovn-northd
689 fi
690 if is_service_enabled ovs-vtep ; then
691 stop_process ovs-vtep
692 fi
693
694 stop_process ovs-vswitchd
695 stop_process ovsdb-server
696
697 _stop_ovs_dp
698}
699
700function _cleanup {
701 local path=${1:-$DEST/$OVN_REPO_NAME}
702 pushd $path
703 cd $path
704 sudo make uninstall
705 sudo make distclean
706 popd
707}
708
709# cleanup_ovn() - Remove residual data files, anything left over from previous
710# runs that a clean run would need to clean up
711function cleanup_ovn {
712 local ovn_path=$DEST/$OVN_REPO_NAME
713 local ovs_path=$DEST/$OVS_REPO_NAME
714
715 if [ -d $ovn_path ]; then
716 _cleanup $ovn_path
717 fi
718
719 if [ -d $ovs_path ]; then
720 _cleanup $ovs_path
721 fi
722
723 sudo rm -f $OVN_RUNDIR
724}