Yes Andrew. The database is never reset while testing in all the
scenarios that we discussed.
On Thursday 29 September 2016 09:14 AM, Andrew Beekhof wrote:
no problem. it went well in testing?
On Wed, Sep 28, 2016 at 2:32 PM, Babu Shanmugam <bscha...@redhat.com> wrote:
Hi Andrew,
I have added "Signed-off-by" on your behalf. Hope you don't mind.
On Wednesday 28 September 2016 10:00 AM, bscha...@redhat.com wrote:
From: Babu Shanmugam <bscha...@redhat.com>
Co-authored-by: Numan Siddique <nusid...@redhat.com>
Signed-off-by: Numan Siddique <nusid...@redhat.com>
Co-authored-by: Andrew Beekhof <abeek...@redhat.com>
Signed-off-by: Andrew Beekhof <abeek...@redhat.com>
Signed-off-by: Babu Shanmugam <bscha...@redhat.com>
---
ovn/utilities/automake.mk | 6 +-
ovn/utilities/ovndb-servers.ocf | 349
++++++++++++++++++++++++++++++++++++++++
2 files changed, 353 insertions(+), 2 deletions(-)
create mode 100755 ovn/utilities/ovndb-servers.ocf
diff --git a/ovn/utilities/automake.mk b/ovn/utilities/automake.mk
index b03d125..164cdda 100644
--- a/ovn/utilities/automake.mk
+++ b/ovn/utilities/automake.mk
@@ -1,5 +1,6 @@
scripts_SCRIPTS += \
- ovn/utilities/ovn-ctl
+ ovn/utilities/ovn-ctl \
+ ovn/utilities/ovndb-servers.ocf
man_MANS += \
ovn/utilities/ovn-ctl.8 \
@@ -20,7 +21,8 @@ EXTRA_DIST += \
ovn/utilities/ovn-docker-overlay-driver \
ovn/utilities/ovn-docker-underlay-driver \
ovn/utilities/ovn-nbctl.8.xml \
- ovn/utilities/ovn-trace.8.xml
+ ovn/utilities/ovn-trace.8.xml \
+ ovn/utilities/ovndb-servers.ocf
DISTCLEANFILES += \
ovn/utilities/ovn-ctl.8 \
diff --git a/ovn/utilities/ovndb-servers.ocf
b/ovn/utilities/ovndb-servers.ocf
new file mode 100755
index 0000000..bb6c9dc
--- /dev/null
+++ b/ovn/utilities/ovndb-servers.ocf
@@ -0,0 +1,349 @@
+#!/bin/bash
+
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+: ${OVN_CTL_DEFAULT="/usr/share/openvswitch/scripts/ovn-ctl"}
+CRM_MASTER="${HA_SBIN_DIR}/crm_master -l reboot"
+CRM_ATTR_REPL_INFO="${HA_SBIN_DIR}/crm_attribute --type crm_config --name
OVN_REPL_INFO -s ovn_ovsdb_master_server"
+OVN_CTL=${OCF_RESKEY_ovn_ctl:-${OVN_CTL_DEFAULT}}
+MASTER_IP=${OCF_RESKEY_master_ip}
+
+# Invalid IP address is an address that can never exist in the network,
as
+# mentioned in rfc-5737. The ovsdb servers connects to this IP address
till
+# a master is promoted and the IPAddr2 resource is started.
+INVALID_IP_ADDRESS=192.0.2.254
+
+host_name=$(ocf_local_nodename)
+: ${slave_score=5}
+: ${master_score=10}
+
+ovsdb_server_metadata() {
+ cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="ovsdb-server">
+ <version>1.0</version>
+
+ <longdesc lang="en">
+ This resource manages ovsdb-server.
+ </longdesc>
+
+ <shortdesc lang="en">
+ Manages ovsdb-server.
+ </shortdesc>
+
+ <parameters>
+
+ <parameter name="ovn_ctl" unique="1">
+ <longdesc lang="en">
+ Location to the ovn-ctl script file
+ </longdesc>
+ <shortdesc lang="en">ovn-ctl script</shortdesc>
+ <content type="string" default="${OVN_CTL_DEFAULT}" />
+ </parameter>
+
+ <parameter name="master_ip" unique="1">
+ <longdesc lang="en">
+ The IP address resource which will be available on the master ovsdb
server
+ </longdesc>
+ <shortdesc lang="en">master ip address</shortdesc>
+ <content type="string" />
+ </parameter>
+
+ </parameters>
+
+ <actions>
+ <action name="notify" timeout="20s" />
+ <action name="start" timeout="30s" />
+ <action name="stop" timeout="20s" />
+ <action name="promote" timeout="50s" />
+ <action name="demote" timeout="50s" />
+ <action name="monitor" timeout="20s" depth="0" interval="10s"
/>
+ <action name="meta-data" timeout="5s" />
+ <action name="validate-all" timeout="20s" />
+ </actions>
+</resource-agent>
+END
+ exit $OCF_SUCCESS
+}
+
+ovsdb_server_notify() {
+ # requires the notify=true meta resource attribute
+ local
type_op="${OCF_RESKEY_CRM_meta_notify_type}-${OCF_RESKEY_CRM_meta_notify_operation}"
+
+ if [ "$type_op" != "post-promote" ]; then
+ # We are only interested in specific events
+ return $OCF_SUCCESS
+ fi
+
+ if [ "x${OCF_RESKEY_CRM_meta_notify_promote_uname}" = "x${host_name}"
]; then
+ # Record ourselves so that the agent has a better chance of doing
+ # the right thing at startup
+ ${CRM_ATTR_REPL_INFO} -v "$host_name"
+
+ else
+ # Synchronize with the new master
+ ${OVN_CTL} demote_ovnnb --db-nb-sync-from-addr=${MASTER_IP}
+ ${OVN_CTL} demote_ovnsb --db-sb-sync-from-addr=${MASTER_IP}
+ fi
+}
+
+ovsdb_server_usage() {
+ cat <<END
+usage: $0 {start|stop|status|monitor|notify|validate-all|meta-data}
+
+Expects to have a fully populated OCF RA-compliant environment set.
+END
+ exit $1
+}
+
+ovsdb_server_find_active_master() {
+ # Operation sequence is Demote -> Stop -> Start -> Promote
+ # At the point this is run, the only active masters will be
+ # previous masters minus any that were scheduled to be demoted
+
+ for master in ${OCF_RESKEY_CRM_meta_notify_master_uname}; do
+ found=0
+ for old in ${OCF_RESKEY_CRM_meta_notify_demote_uname}; do
+ if [ $master = $old ]; then
+ found=1
+ fi
+ done
+ if [ $found = 0 ]; then
+ # Rely on master-max=1
+ # Pacemaker will demote any additional ones it finds before
starting new copies
+ echo "$master"
+ return
+ fi
+ done
+
+ local expected_master=$($CRM_ATTR_REPL_INFO --query -q 2>/dev/null)
+ case "x${OCF_RESKEY_CRM_meta_notify_start_uname}x" in
+ *${expected_master}*) echo "${expected_master}";; # The previous
master is expected to start
+ esac
+}
+
+ovsdb_server_find_active_peers() {
+ # Do we have any peers that are not stopping
+ for peer in ${OCF_RESKEY_CRM_meta_notify_slave_uname}; do
+ found=0
+ for old in ${OCF_RESKEY_CRM_meta_notify_stop_uname}; do
+ if [ $peer = $old ]; then
+ found=1
+ fi
+ done
+ if [ $found = 0 ]; then
+ # Rely on master-max=1
+ # Pacemaker will demote any additional ones it finds before
starting new copies
+ echo "$peer"
+ return
+ fi
+ done
+}
+
+ovsdb_server_master_update() {
+
+ case $1 in
+ $OCF_SUCCESS)
+ $CRM_MASTER -v ${slave_score};;
+ $OCF_RUNNING_MASTER)
+ $CRM_MASTER -v ${master_score};;
+ #*) $CRM_MASTER -D;;
+ esac
+}
+
+ovsdb_server_monitor() {
+ ovsdb_server_check_status
+ rc=$?
+
+ ovsdb_server_master_update $rc
+ return $rc
+}
+
+ovsdb_server_check_status() {
+ local sb_status=`${OVN_CTL} status_ovnsb`
+ local nb_status=`${OVN_CTL} status_ovnnb`
+
+ if [[ $sb_status == "running/backup" && $nb_status ==
"running/backup" ]]; then
+ return $OCF_SUCCESS
+ fi
+
+ if [[ $sb_status == "running/active" && $nb_status ==
"running/active" ]]; then
+ return $OCF_RUNNING_MASTER
+ fi
+
+ # TODO: What about service running but not in either state above?
+ # Eg. a transient state where one db is "active" and the other
+ # "backup"
+
+ return $OCF_NOT_RUNNING
+}
+
+ovsdb_server_start() {
+ ovsdb_server_check_status
+ local status=$?
+ # If not in stopped state, return
+ if [ $status -ne $OCF_NOT_RUNNING ]; then
+ return $status
+ fi
+
+ local present_master=$(ovsdb_server_find_active_master)
+
+ set ${OVN_CTL}
+
+ if [ "x${present_master}" = x ]; then
+ # No master detected, or the previous master is not among the
+ # set starting.
+ #
+ # Force all copies to come up as slaves by pointing them into
+ # space and let pacemaker pick one to promote:
+ #
+ set $@ --db-nb-sync-from-addr=${INVALID_IP_ADDRESS}
--db-sb-sync-from-addr=${INVALID_IP_ADDRESS}
+
+ elif [ ${present_master} != ${host_name} ]; then
+ # An existing master is active, connect to it
+ set $@ --db-nb-sync-from-addr=${MASTER_IP}
--db-sb-sync-from-addr=${MASTER_IP}
+ fi
+
+ $@ start_ovsdb
+
+ while [ 1 = 1 ]; do
+ # It is important that we don't return until we're in a
functional state
+ ovsdb_server_monitor
+ rc=$?
+ case $rc in
+ $OCF_SUCCESS) return $rc;;
+ $OCF_RUNNING_MASTER) return $rc;;
+ $OCF_ERR_GENERIC) return $rc;;
+ # Otherwise loop, waiting for the service to start, until
+ # the cluster times the operation out
+ esac
+ done
+}
+
+ovsdb_server_stop() {
+ ovsdb_server_check_status
+ case $? in
+ $OCF_NOT_RUNNING) return ${OCF_SUCCESS};;
+ $OCF_RUNNING_MASTER) return ${OCF_RUNNING_MASTER};;
+ esac
+
+ ${OVN_CTL} stop_ovsdb
+ ovsdb_server_master_update ${OCF_NOT_RUNNING}
+
+ while [ 1 = 1 ]; do
+ # It is important that we don't return until we're stopped
+ ovsdb_server_check_status
+ rc=$?
+ case $rc in
+ $OCF_SUCCESS)
+ # Loop, waiting for the service to stop, until the
+ # cluster times the operation out
+ ;;
+ $OCF_NOT_RUNNING)
+ return $OCF_SUCCESS
+ ;;
+ *)
+ return $rc
+ ;;
+ esac
+ done
+
+ return $OCF_ERR_GENERIC
+}
+
+ovsdb_server_promote() {
+ ovsdb_server_check_status
+ rc=$?
+ case $rc in
+ ${OCF_SUCCESS}) ;;
+ ${OCF_RUNNING_MASTER}) return ${OCF_SUCCESS};;
+ *)
+ ovsdb_server_master_update $OCF_RUNNING_MASTER
+ return ${rc}
+ ;;
+ esac
+
+ ${OVN_CTL} promote_ovnnb
+ ${OVN_CTL} promote_ovnsb
+
+ # Record ourselves so that the agent has a better chance of doing
+ # the right thing at startup
+ ${CRM_ATTR_REPL_INFO} -v "$host_name"
+ ovsdb_server_master_update $OCF_RUNNING_MASTER
+ return $OCF_SUCCESS
+}
+
+ovsdb_server_demote() {
+ ovsdb_server_check_status
+ if [ $? = $OCF_NOT_RUNNING ]; then
+ return $OCF_NOT_RUNNING
+ fi
+
+ local present_master=$(ovsdb_server_find_active_master)
+ local recorded_master=$($CRM_ATTR_REPL_INFO --query -q 2>/dev/null)
+
+ if [ "x${recorded_master}" = "x${host_name}" -a "x${present_master}"
= x ]; then
+ # We are the one and only master
+ # This should be the "normal" case
+ # The only way to be demoted is to call demote_ovn*
+ #
+ # The local database is only reset once we successfully
+ # connect to the peer. So specify one that doesn't exist.
+ #
+ # Eventually a new master will be promoted and we'll resync
+ # using the logic in ovsdb_server_notify()
+ ${OVN_CTL} demote_ovnnb
--db-nb-sync-from-addr=${INVALID_IP_ADDRESS}
+ ${OVN_CTL} demote_ovnsb
--db-sb-sync-from-addr=${INVALID_IP_ADDRESS}
+
+ elif [ "x${present_master}" = "x${host_name}" ]; then
+ # Safety check, should never be called
+ #
+ # Never allow sync'ing from ourselves, its a great way to
+ # erase the local DB
+ ${OVN_CTL} demote_ovnnb
--db-nb-sync-from-addr=${INVALID_IP_ADDRESS}
+ ${OVN_CTL} demote_ovnsb
--db-sb-sync-from-addr=${INVALID_IP_ADDRESS}
+
+ elif [ "x${present_master}" != x ]; then
+ # There are too many masters and we're an extra one that is
+ # being demoted. Sync to the surviving one
+ ${OVN_CTL} demote_ovnnb --db-nb-sync-from-addr=${MASTER_IP}
+ ${OVN_CTL} demote_ovnsb --db-sb-sync-from-addr=${MASTER_IP}
+
+ else
+ # For completeness, should never be called
+ #
+ # Something unexpected happened, perhaps CRM_ATTR_REPL_INFO is
incorrect
+ ${OVN_CTL} demote_ovnnb
--db-nb-sync-from-addr=${INVALID_IP_ADDRESS}
+ ${OVN_CTL} demote_ovnsb
--db-sb-sync-from-addr=${INVALID_IP_ADDRESS}
+ fi
+
+ ovsdb_server_master_update $OCF_SUCCESS
+ return $OCF_SUCCESS
+}
+
+ovsdb_server_validate() {
+ if [ ! -e ${OVN_CTL} ]; then
+ return $OCF_ERR_INSTALLED
+ fi
+ return $OCF_SUCCESS
+}
+
+
+case $__OCF_ACTION in
+start) ovsdb_server_start;;
+stop) ovsdb_server_stop;;
+promote) ovsdb_server_promote;;
+demote) ovsdb_server_demote;;
+start) ovsdb_server_start;;
+notify) ovsdb_server_notify;;
+meta-data) ovsdb_server_metadata;;
+validate-all) ovsdb_server_validate;;
+status|monitor) ovsdb_server_monitor;;
+usage|help) ovsdb_server_usage $OCF_SUCCESS;;
+*) ovsdb_server_usage $OCF_ERR_UNIMPLEMENTED ;;
+esac
+
+rc=$?
+exit $rc
+
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev