[ovs-dev] [PATCH v3 2/4] ovn: OCF script for OVN OVSDB servers

Andrew Beekhof abeekhof at redhat.com
Thu Sep 29 03:44:38 UTC 2016


no problem. it went well in testing?

On Wed, Sep 28, 2016 at 2:32 PM, Babu Shanmugam <bschanmu at 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, bschanmu at redhat.com wrote:
>>
>> From: Babu Shanmugam <bschanmu at redhat.com>
>>
>> Co-authored-by: Numan Siddique <nusiddiq at redhat.com>
>> Signed-off-by: Numan Siddique <nusiddiq at redhat.com>
>> Co-authored-by: Andrew Beekhof <abeekhof at redhat.com>
>> Signed-off-by: Andrew Beekhof <abeekhof at redhat.com>
>> Signed-off-by: Babu Shanmugam <bschanmu at 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
>> +
>
>



More information about the dev mailing list