apiVersion: v1 data: functions: | #!/bin//bash # # Copyright 2022 Red Hat Inc. # # 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. # Configs are obtained from ENV variables. OVNBridge=${OVNBridge:-"br-int"} OVNRemote=${OVNRemote:-"tcp:localhost:6642"} OVNEncapType=${OVNEncapType:-"geneve"} OVNAvailabilityZones=${OVNAvailabilityZones:-""} EnableChassisAsGateway=${EnableChassisAsGateway:-true} PhysicalNetworks=${PhysicalNetworks:-""} OVNHostName=${OVNHostName:-""} DB_FILE=/etc/openvswitch/conf.db ovs_dir=/var/lib/openvswitch FLOWS_RESTORE_SCRIPT=$ovs_dir/flows-script FLOWS_RESTORE_DIR=$ovs_dir/saved-flows SAFE_TO_STOP_OVSDB_SERVER_SEMAPHORE=$ovs_dir/is_safe_to_stop_ovsdb_server function cleanup_ovsdb_server_semaphore() { rm -f $SAFE_TO_STOP_OVSDB_SERVER_SEMAPHORE 2>&1 > /dev/null } function cleanup_flows_backup() { rm -f $FLOWS_RESTORE_SCRIPT 2>&1 > /dev/null rm -rf $FLOWS_RESTORE_DIR 2>&1 > /dev/null } function wait_for_ovsdb_server { while true; do /usr/bin/ovs-vsctl show if [ $? -eq 0 ]; then break else echo "ovsdb-server seems not be ready yet. Waiting..." sleep 1 fi done } # configure external-ids in OVS function configure_external_ids { ovs-vsctl set open . external-ids:ovn-bridge=${OVNBridge} ovs-vsctl set open . external-ids:ovn-remote=${OVNRemote} ovs-vsctl set open . external-ids:ovn-encap-type=${OVNEncapType} if [ -n "$OVNHostName" ]; then ovs-vsctl set open . external-ids:hostname=${OVNHostName} fi local cms_options="" if [ "$EnableChassisAsGateway" == "true" ]; then cms_options="enable-chassis-as-gw" fi if [ -n "$OVNAvailabilityZones" ]; then cms_options+=",availability-zones="$OVNAvailabilityZones fi if [ -n "${cms_options}" ]; then ovs-vsctl set open . external-ids:ovn-cms-options=${cms_options#,} else ovs-vsctl --if-exists remove open . external_ids ovn-cms-options fi } # Returns the set difference between $1 and $2 function set_difference { echo "$(comm -23 <(sort <(echo $1 | xargs -n1)) <(sort <(echo $2 | xargs -n1)))" } # Configure bridge mappings and physical bridges function configure_physical_networks { local OVNBridgeMappings="" local br_new="" for physicalNetwork in ${PhysicalNetworks}; do br_name="br-${physicalNetwork}" bridgeMapping="${physicalNetwork}:${br_name}" if [ -z "$OVNBridgeMappings" ]; then OVNBridgeMappings=$bridgeMapping br_new=$br_name else OVNBridgeMappings="${OVNBridgeMappings},${bridgeMapping}" br_new="${br_new} ${br_name}" fi done # Current configured bridges. ovn_bms=$(ovs-vsctl --if-exists get open . external_ids:ovn-bridge-mappings|tr -d '"') local br_current="" for bm in ${ovn_bms/,/ }; do if [ -z "$br_current"]; then br_current=${bm##*:} else br_current="${br_current} ${bm##*:}" fi done # Bridges to add and delete. local br_to_delete="" local br_to_add="" br_to_delete=$(set_difference "$br_current" "$br_new") br_to_add=$(set_difference "$br_new" "$br_current") # Add the new bridges. for br_name in ${br_to_add}; do ovs-vsctl --may-exist add-br ${br_name} ovs-vsctl --may-exist add-port ${br_name} ${br_name#*-} done # Delete the old bridges not longer present in "OVNBridgeMappings" and the # patch ports in "br-int". for br_name in ${br_to_delete}; do # List all ports "type=patch", retrieve the "options:peer" parameter # and delete the peer port. The "$port" will be deleted during the # bridge deletion. # $ ovs-vsctl --column=options --bare find interface name=patch-provnet1-to-br-int type=patch # peer=patch-br-int-to-provnet1 if ovs-vsctl br-exists ${br_name}; then for iface in $(ovs-vsctl list-ifaces ${br_name}); do port_type=$(ovs-vsctl --column=type --bare list interface ${iface}) if [ "$port_type" == "patch" ]; then peer=$(ovs-vsctl get interface ${iface} options:peer) ovs-vsctl --if-exists del-port ${OVNBridge} ${peer} fi done ovs-vsctl --if-exists del-br ${br_name} fi done # Set or remove the local OVS Open vSwitch "external-ids:ovn-bridge-mappings" if [ -n "$OVNBridgeMappings" ]; then ovs-vsctl set open . external-ids:ovn-bridge-mappings=${OVNBridgeMappings} else ovs-vsctl --if-exists remove open . external_ids ovn-bridge-mappings fi } function wait_for_db_creation { while [ ! -s ${DB_FILE} ]; do echo "${DB_FILE} does not exist yet or is empty. Waiting..." sleep 1 done } init-ovsdb-server.sh: | #!/bin/sh # # Copyright 2023 Red Hat Inc. # # 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. set -ex source $(dirname $0)/functions trap wait_for_db_creation EXIT # If db file is empty, remove it; otherwise service won't start. # See https://issues.redhat.com/browse/FDP-689 for more details. if ! [ -s ${DB_FILE} ]; then rm -f ${DB_FILE} fi # Compact the Database file if it exists if [ -f ${DB_FILE} ]; then ovsdb-tool compact ${DB_FILE} fi # Initialize or upgrade database if needed CTL_ARGS="--system-id=random --no-ovs-vswitchd" /usr/share/openvswitch/scripts/ovs-ctl start $CTL_ARGS /usr/share/openvswitch/scripts/ovs-ctl stop $CTL_ARGS wait_for_db_creation trap - EXIT init.sh: | #!/bin//bash # # Copyright 2022 Red Hat Inc. # # 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. source $(dirname $0)/functions wait_for_ovsdb_server # From now on, we should exit immediatelly when any command exits with non-zero status set -ex configure_external_ids configure_physical_networks ovn_controller_liveness.sh: | #!/bin/bash set -e error_exit() { echo "$1" >&2 exit 1 } # Check if ovn-controller is running check_ovn_controller_pid() { if ! pidof -q ovn-controller; then error_exit "ERROR - ovn-controller is not running" fi } # Function to check the running status of ovn-controller check_ovn_controller_status() { # Capture output and check exit status if ! output=$(ovn-appctl -t ovn-controller debug/status 2>&1); then error_exit "ERROR - Failed to get status from ovn-controller, ovn-appctl exit status: $?" fi if [ "$output" != "running" ]; then error_exit "ERROR - ovn-controller status is '$output', expecting 'running' status" fi } check_ovn_controller_pid check_ovn_controller_status ovn_controller_readiness.sh: | #!/bin/bash set -e error_exit() { echo "$1" >&2 exit 1 } # Check if ovn-controller is connected to the OVN SB database check_ovn_controller_connection() { if ! output=$(ovn-appctl -t ovn-controller connection-status 2>&1); then error_exit "ERROR - Failed to get connection status from ovn-controller, ovn-appctl exit status: $?" fi if [ "$output" != "connected" ]; then error_exit "ERROR - ovn-controller connection status is '$output', expecting 'connected' status" fi } check_ovn_controller_connection ovsdb_server_liveness.sh: | #!/bin/bash set -e error_exit() { echo "$1" >&2 exit 1 } # Check if ovsdb-server is running check_ovsdb_server_pid() { if ! pidof -q ovsdb-server; then error_exit "ERROR - ovsdb-server is not running" fi } # Function to check the running status of ovsdb-server check_ovsdb_server_status() { if ! /usr/bin/ovs-vsctl show 2>&1; then error_exit "ERROR - Failed to get output from ovsdb-server, ovs-vsctl exit status: $?" fi } check_ovsdb_server_pid check_ovsdb_server_status ovsdb_server_readiness.sh: | #!/bin/bash set -e error_exit() { echo "$1" >&2 exit 1 } # Check ovsdb-server status check_ovsdb_server_status() { if ! pid=$(cat /var/run/openvswitch/ovsdb-server.pid); then error_exit "ERROR - Failed to get pid for ovsdb-server, exit status: $?" fi if ! output=$(ovs-appctl -t /var/run/openvswitch/ovsdb-server."$pid".ctl ovsdb-server/list-dbs); then error_exit "ERROR - Failed retrieving list of databases from ovsdb-server" fi if [[ "$output" != *"Open_vSwitch"* ]]; then error_exit "ERROR - 'Open_vSwitch' not found on databases" fi } check_ovsdb_server_status start-ovsdb-server.sh: | #!/bin/sh # # Copyright 2023 Red Hat Inc. # # 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. set -ex source $(dirname $0)/functions # Remove the obsolete semaphore file in case it still exists. cleanup_ovsdb_server_semaphore # Start the service ovsdb-server ${DB_FILE} \ --pidfile \ --remote=punix:/var/run/openvswitch/db.sock \ --private-key=db:Open_vSwitch,SSL,private_key \ --certificate=db:Open_vSwitch,SSL,certificate \ --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert start-vswitchd.sh: | #!/bin/sh # # Copyright 2024 Red Hat Inc. # # 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. source $(dirname $0)/functions wait_for_ovsdb_server # The order - first wait for db server, then set -ex - is important. Otherwise, # wait_for_ovsdb_server interrim check would make the script exit. set -ex # Configure encap IP. OVNEncapIP=$(ip -o addr show dev tenant scope global | awk '{print $4}' | cut -d/ -f1) ovs-vsctl --no-wait set open . external-ids:ovn-encap-ip=${OVNEncapIP} # Before starting vswitchd, block it from flushing existing datapath flows. ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait=true # It's safe to start vswitchd now. Do it. # --detach to allow the execution to continue to restoring the flows. # We need to use --log-file since --detach disables all logging explicitly. # Once https://issues.redhat.com/browse/FDP-1292 is fixed we will be able to # use system logs only. /usr/sbin/ovs-vswitchd --pidfile --mlockall --detach --log-file # Restore saved flows. if [ -f $FLOWS_RESTORE_SCRIPT ]; then # It's unsafe to leave these files in place if they fail once. Make sure we # remove them if the eval fails. trap cleanup_flows_backup EXIT eval "$(cat $FLOWS_RESTORE_SCRIPT)" trap - EXIT fi # It's also unsafe to leave these files after flow-restore-wait flag is removed # because the backup will become stale and if a container later crashes, it may # mistakenly try to restore from this old backup. cleanup_flows_backup # Now, inform vswitchd that we are done. ovs-vsctl remove open_vswitch . other_config flow-restore-wait # This is container command script. Block it from exiting, otherwise k8s will # restart the container again. tail -f /var/log/openvswitch/ovs-vswitchd.log stop-ovsdb-server.sh: | #!/bin/sh # # Copyright 2024 Red Hat Inc. # # 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. set -ex source $(dirname $0)/functions # The ovs_vswitchd container has to terminate before ovsdb-server because it # needs access to db in its preStop script. The preStop script backs up flows # for restoration during the next startup. This semaphore ensures the vswitchd # container is not torn down before flows are saved. while [ ! -f $SAFE_TO_STOP_OVSDB_SERVER_SEMAPHORE ]; do sleep 0.5 done cleanup_ovsdb_server_semaphore # Now it's safe to stop db server. Do it. /usr/share/openvswitch/scripts/ovs-ctl stop --no-ovs-vswitchd stop-vswitchd.sh: | #!/bin/sh # # Copyright 2024 Red Hat Inc. # # 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. set -ex source $(dirname $0)/functions # Clean up any previously created flow backups to avoid conflict with newly # generated backup. cleanup_flows_backup # Passing --real to mimic what upstream startup scripts do; maybe redundant. bridges=$(ovs-vsctl -- --real list-br) # Saving flows to avoid disrupting gateway datapath. mkdir $FLOWS_RESTORE_DIR TMPDIR=$FLOWS_RESTORE_DIR /usr/share/openvswitch/scripts/ovs-save save-flows $bridges > $FLOWS_RESTORE_SCRIPT # Once save-flows logic is complete it no longer needs ovsdb-server, this file # unlocks the db preStop script, working as a semaphore touch $SAFE_TO_STOP_OVSDB_SERVER_SEMAPHORE # Finally, stop vswitchd. /usr/share/openvswitch/scripts/ovs-ctl stop --no-ovsdb-server vswitchd_liveness.sh: | #!/bin/bash set -e error_exit() { echo "$1" >&2 exit 1 } # Check if ovs-vswitchd is running check_ovs_vswitchd_pid() { if ! pidof -q ovs-vswitchd; then error_exit "ERROR - ovs-vswitchd is not running" fi } # Function to check the running status of ovs-vswitchd check_ovs_vswitchd_status() { if ! /usr/bin/ovs-appctl bond/show 2>&1; then error_exit "ERROR - Failed to get output from ovs-vswitchd, ovs-appctl exit status: $?" fi } check_ovs_vswitchd_pid check_ovs_vswitchd_status vswitchd_readiness.sh: | #!/bin/bash set -e error_exit() { echo "$1" >&2 exit 1 } # Check ovs-vswitchd status check_ovs_vswitchd_status() { if ! pid=$(cat /var/run/openvswitch/ovs-vswitchd.pid); then error_exit "ERROR - Failed to get pid for ovs-vswitchd, exit status: $?" fi if ! output=$(ovs-appctl -t /var/run/openvswitch/ovs-vswitchd."$pid".ctl ofproto/list); then error_exit "ERROR - Failed retrieving ofproto/list from ovs-vswitchd" fi if [ -z "$output" ]; then error_exit "ERROR - No bridges on ofproto/list output" fi } check_ovs_vswitchd_status kind: ConfigMap metadata: creationTimestamp: "2025-10-11T10:53:00Z" labels: ovn-controller.openstack.org/name: ovncontroller ovn-controller.openstack.org/namespace: openstack ovn-controller.openstack.org/uid: 03efddb7-9133-4e85-abfb-a97dae0db64c name: ovncontroller-scripts namespace: openstack ownerReferences: - apiVersion: ovn.openstack.org/v1beta1 blockOwnerDeletion: true controller: true kind: OVNController name: ovncontroller uid: 03efddb7-9133-4e85-abfb-a97dae0db64c resourceVersion: "35042" uid: 7045eb4a-3119-4a2c-ae4a-26f50c6423e8