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

Reply via email to