From 43fb71d9c1feebcf6af5dfbc42922791aca0a3db Mon Sep 17 00:00:00 2001 From: Hui Xiang Date: Tue, 23 Dec 2014 09:36:40 +0800 Subject: [PATCH] Add NeutronAgentMon --- files/NeutronAgentMon | 265 +++++++++++++++++++++++++++++++++++++ hooks/ha-relation-departed | 1 + hooks/quantum_hooks.py | 36 ++--- hooks/quantum_utils.py | 15 ++- 4 files changed, 295 insertions(+), 22 deletions(-) create mode 100644 files/NeutronAgentMon create mode 120000 hooks/ha-relation-departed diff --git a/files/NeutronAgentMon b/files/NeutronAgentMon new file mode 100644 index 00000000..4d04274c --- /dev/null +++ b/files/NeutronAgentMon @@ -0,0 +1,265 @@ +#!/bin/sh +# +# +# NeutronAgentMon OCF RA. +# Starts crm_mon in background which logs cluster status as +# html to the specified file. +# +# Copyright (c) 2004 SUSE LINUX AG, Lars Marowsky-Brée +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# OCF instance parameters: +# OCF_RESKEY_user +# OCF_RESKEY_pidfile +# OCF_RESKEY_update +# OCF_RESKEY_extra_options +# OCF_RESKEY_htmlfile + +####################################################################### +# Initialization: +: ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} +. ${OCF_FUNCTIONS} +: ${__OCF_ACTION=$1} + +####################################################################### + +meta_data() { + cat < + + +1.0 + + +This is a NeutronAgentMon Resource Agent. +It outputs current cluster status to the html. + +Runs crm_mon in the background, recording the cluster status to an HTML file + + + + + +The user we want to run crm_mon as + +The user we want to run crm_mon as + + + + + +How frequently should we update the cluster status + +Update interval + + + + + +Additional options to pass to crm_mon. Eg. -n -r + +Extra options + + + + + +PID file location to ensure only one instance is running + +PID file + + + + + +Location to write HTML output to. + +HTML output + + + + + + + + + + + + +END +} + +####################################################################### + +NeutronAgentMon_usage() { + cat <> /dev/null 2>&1 & echo $! + else + ocf_log warn "Monitor daemon already running." + fi + NeutronAgentMon_exit $? +} + +NeutronAgentMon_stop() { + pid=`ps -aux | grep m\[o\]nitor.py | awk -F' ' '{print $2}'` + if [ ! -z $pid ]; then + ocf_log warn "Stop Monitor daemon." + sudo kill -s 9 $pid + else + ocf_log warn "Monitor daemon already stopped." + fi + NeutronAgentMon_exit 0 +} + +NeutronAgentMon_monitor() { + pid=`ps -aux | grep m\[o\]nitor.py | awk -F' ' '{print $2}'` + if [ ! -z $pid ]; then + kill -s 0 $pid >/dev/null 2>&1; rc=$? + case $rc in + 0) exit $OCF_SUCCESS;; + 1) exit $OCF_NOT_RUNNING;; + *) exit $OCF_ERR_GENERIC;; + esac + fi + exit $OCF_NOT_RUNNING +} + +CheckOptions() { +while getopts Vi:nrh:cdp: OPTION +do + case $OPTION in + V|n|r|c|d);; + i) ocf_log warn "You should not have specified the -i option, since OCF_RESKEY_update is set already!";; + h) ocf_log warn "You should not have specified the -h option, since OCF_RESKEY_htmlfile is set already!";; + p) ocf_log warn "You should not have specified the -p option, since OCF_RESKEY_pidfile is set already!";; + *) return $OCF_ERR_ARGS;; + esac +done + +if [ $? -ne 0 ]; then + return $OCF_ERR_ARGS +fi + +# We should have eaten all options at this stage +shift $(($OPTIND -1)) +if [ $# -gt 0 ]; then + false +else + true +fi +} + +NeutronAgentMon_validate() { +# Existence of the user + if [ ! -z $OCF_RESKEY_user ]; then + getent passwd "$OCF_RESKEY_user" >/dev/null + if [ $? -eq 0 ]; then + : Yes, user exists. We can further check his permission on crm_mon if necessary + else + ocf_log err "The user $OCF_RESKEY_user does not exist!" + exit $OCF_ERR_ARGS + fi + fi + +# Pidfile better be an absolute path + case $OCF_RESKEY_pidfile in + /*) ;; + *) ocf_log warn "You should have pidfile($OCF_RESKEY_pidfile) of absolute path!" ;; + esac + +# Check the update interval + if ocf_is_decimal "$OCF_RESKEY_update" && [ $OCF_RESKEY_update -gt 0 ]; then + : + else + ocf_log err "Invalid update interval $OCF_RESKEY_update. It should be positive integer!" + exit $OCF_ERR_ARGS + fi + + if CheckOptions $OCF_RESKEY_extra_options; then + : + else + ocf_log err "Invalid options $OCF_RESKEY_extra_options!" + exit $OCF_ERR_ARGS + fi + +# Htmlfile better be an absolute path + case $OCF_RESKEY_htmlfile in + /*) ;; + *) ocf_log warn "You should have htmlfile($OCF_RESKEY_htmlfile) of absolute path!" ;; + esac + + + echo "Validate OK" + return $OCF_SUCCESS +} + +if [ $# -ne 1 ]; then + NeutronAgentMon_usage + exit $OCF_ERR_ARGS +fi + +: ${OCF_RESKEY_update:="15000"} +: ${OCF_RESKEY_pidfile:="/tmp/NeutronAgentMon_${OCF_RESOURCE_INSTANCE}.pid"} +: ${OCF_RESKEY_htmlfile:="/tmp/NeutronAgentMon_${OCF_RESOURCE_INSTANCE}.html"} + +OCF_RESKEY_update=`expr $OCF_RESKEY_update / 1000` + +case $__OCF_ACTION in +meta-data) meta_data + exit $OCF_SUCCESS + ;; +start) NeutronAgentMon_start + ;; +stop) NeutronAgentMon_stop + ;; +monitor) NeutronAgentMon_monitor + ;; +validate-all) NeutronAgentMon_validate + ;; +usage|help) NeutronAgentMon_usage + exit $OCF_SUCCESS + ;; +*) NeutronAgentMon_usage + exit $OCF_ERR_UNIMPLEMENTED + ;; +esac + +exit $? diff --git a/hooks/ha-relation-departed b/hooks/ha-relation-departed new file mode 120000 index 00000000..9a2da58e --- /dev/null +++ b/hooks/ha-relation-departed @@ -0,0 +1 @@ +quantum_hooks.py \ No newline at end of file diff --git a/hooks/quantum_hooks.py b/hooks/quantum_hooks.py index 6b129cff..db36613a 100755 --- a/hooks/quantum_hooks.py +++ b/hooks/quantum_hooks.py @@ -228,29 +228,33 @@ def stop(): def ha_relation_joined(): if config('ha-legacy-mode'): cache_env_data() - dns_hosts = get_dns_host() - debug = config('ocf_ping_debug') - external_agent = get_external_agent_f() + #dns_hosts = get_dns_host() + #debug = config('ocf_ping_debug') + #external_agent = get_external_agent_f() cluster_config = get_hacluster_config(excludes_key=['vip']) resources = { - 'res_ClusterMon': 'ocf:pacemaker:ClusterMon', - 'res_PingCheck': 'ocf:pacemaker:ping', + 'res_monitor': 'ocf:canonical:NeutronAgentMon', + #'res_ClusterMon': 'ocf:pacemaker:ClusterMon', + #'res_PingCheck': 'ocf:pacemaker:ping', } resource_params = { - 'res_ClusterMon': 'params user="root" update="30" ' - 'extra_options="-E {external_agent}" ' - 'op monitor on-fail="restart" interval="10s"' - .format(external_agent=external_agent), - 'res_PingCheck': 'params host_list="{host}" dampen="5s" ' - 'debug={debug} multiplier="1000" ' - 'op monitor on-fail="restart" interval="10s" ' - 'timeout="60s" '.format(host=dns_hosts, - debug=debug), + 'res_monitor': 'op monitor on-fail="restart" interval="10s"', + + #'res_ClusterMon': 'params user="root" update="30" ' + # 'extra_options="-E {external_agent}" ' + # 'op monitor on-fail="restart" interval="10s"' + # .format(external_agent=external_agent), + #'res_PingCheck': 'params host_list="{host}" dampen="5s" ' + # 'debug={debug} multiplier="1000" ' + # 'op monitor on-fail="restart" interval="10s" ' + # 'timeout="60s" '.format(host=dns_hosts, + # debug=debug), } clones = { - 'cl_ClusterMon': 'res_ClusterMon meta interleave="true"', - 'cl_PingCheck': 'res_PingCheck meta interleave="true"', + 'cl_monitor': 'res_monitor meta interleave="true"', + #'cl_ClusterMon': 'res_ClusterMon meta interleave="true"', + #'cl_PingCheck': 'res_PingCheck meta interleave="true"', } relation_set(corosync_bindiface=cluster_config['ha-bindiface'], diff --git a/hooks/quantum_utils.py b/hooks/quantum_utils.py index d6fb617c..734d0257 100644 --- a/hooks/quantum_utils.py +++ b/hooks/quantum_utils.py @@ -164,8 +164,13 @@ LEGACY_FILES_MAP = { 'monitor.conf': { 'path': '/tmp', 'permission': None - } + }, + 'NeutronAgentMon': { + 'path': '/usr/lib/ocf/resource.d/canonical', + 'permission': None + }, } +LEGACY_RES_MAP = ['res_monitor'] def get_early_packages(): @@ -719,8 +724,6 @@ def delete_legacy_resources(): def crm_op(op, res): cmd = 'crm -w -F %s %s' % (op, res) subprocess.call(cmd.split()) - - crm_op('resource stop', 'res_PingCheck') - crm_op('resource stop', 'res_ClusterMon') - crm_op('configure delete', 'res_PingCheck') - crm_op('configure delete', 'res_ClusterMon') + for res in LEGACY_RES_MAP: + crm_op('resource stop', res) + crm_op('configure delete', res)