diff --git a/centos_iso_image.inc b/centos_iso_image.inc index 32db1582..a0ac14ba 100644 --- a/centos_iso_image.inc +++ b/centos_iso_image.inc @@ -177,3 +177,6 @@ openstack-swift-object openstack-swift-account openstack-swift-container openstack-swift-proxy + +# stx-ocf-scripts +stx-ocf-scripts diff --git a/centos_pkg_dirs b/centos_pkg_dirs index b65bb0a7..7f63c03b 100644 --- a/centos_pkg_dirs +++ b/centos_pkg_dirs @@ -48,3 +48,4 @@ openstack/python-django-openstack-auth openstack/python-wsme openstack/distributedcloud openstack/distributedcloud-client +openstack/stx-ocf-scripts diff --git a/openstack/openstack-ras/centos/openstack-ras.spec b/openstack/openstack-ras/centos/openstack-ras.spec index 223ef2cd..5cc5d6fa 100644 --- a/openstack/openstack-ras/centos/openstack-ras.spec +++ b/openstack/openstack-ras/centos/openstack-ras.spec @@ -31,25 +31,11 @@ rm -rf ${RPM_BUILD_ROOT}/usr/lib/ocf/resource.d/openstack/ceilometer-alarm-notif %files %defattr(-,root,root,-) %dir "/usr/lib/ocf/resource.d/openstack" -"/usr/lib/ocf/resource.d/openstack/aodh-api" -"/usr/lib/ocf/resource.d/openstack/aodh-evaluator" -"/usr/lib/ocf/resource.d/openstack/aodh-listener" -"/usr/lib/ocf/resource.d/openstack/aodh-notifier" -"/usr/lib/ocf/resource.d/openstack/murano-engine" -"/usr/lib/ocf/resource.d/openstack/murano-api" -"/usr/lib/ocf/resource.d/openstack/magnum-conductor" -"/usr/lib/ocf/resource.d/openstack/magnum-api" -"/usr/lib/ocf/resource.d/openstack/ironic-conductor" -"/usr/lib/ocf/resource.d/openstack/ironic-api" -"/usr/lib/ocf/resource.d/openstack/nova-compute" -"/usr/lib/ocf/resource.d/openstack/heat-api" "/usr/lib/ocf/resource.d/openstack/glance-registry" "/usr/lib/ocf/resource.d/openstack/nova-network" "/usr/lib/ocf/resource.d/openstack/keystone" "/usr/lib/ocf/resource.d/openstack/heat-engine" "/usr/lib/ocf/resource.d/openstack/nova-novnc" -"/usr/lib/ocf/resource.d/openstack/nova-serialproxy" -"/usr/lib/ocf/resource.d/openstack/heat-api-cfn" "/usr/lib/ocf/resource.d/openstack/cinder-api" "/usr/lib/ocf/resource.d/openstack/neutron-agent-dhcp" "/usr/lib/ocf/resource.d/openstack/cinder-volume" @@ -58,14 +44,8 @@ rm -rf ${RPM_BUILD_ROOT}/usr/lib/ocf/resource.d/openstack/ceilometer-alarm-notif "/usr/lib/ocf/resource.d/openstack/nova-consoleauth" "/usr/lib/ocf/resource.d/openstack/ceilometer-api" "/usr/lib/ocf/resource.d/openstack/nova-scheduler" -"/usr/lib/ocf/resource.d/openstack/nova-conductor" "/usr/lib/ocf/resource.d/openstack/neutron-server" -"/usr/lib/ocf/resource.d/openstack/validation" -"/usr/lib/ocf/resource.d/openstack/heat-api-cloudwatch" -"/usr/lib/ocf/resource.d/openstack/ceilometer-agent-notification" "/usr/lib/ocf/resource.d/openstack/glance-api" "/usr/lib/ocf/resource.d/openstack/nova-api" "/usr/lib/ocf/resource.d/openstack/neutron-metadata-agent" "/usr/lib/ocf/resource.d/openstack/ceilometer-collector" -"/usr/lib/ocf/resource.d/openstack/panko-api" -"/usr/lib/ocf/resource.d/openstack/nova-placement-api" diff --git a/openstack/stx-ocf-scripts/centos/build_srpm.data b/openstack/stx-ocf-scripts/centos/build_srpm.data new file mode 100644 index 00000000..68c4f32d --- /dev/null +++ b/openstack/stx-ocf-scripts/centos/build_srpm.data @@ -0,0 +1,2 @@ +SRC_DIR="$PKG_BASE/src" +TIS_PATCH_VER=1 diff --git a/openstack/stx-ocf-scripts/centos/stx-ocf-scripts.spec b/openstack/stx-ocf-scripts/centos/stx-ocf-scripts.spec new file mode 100644 index 00000000..76453f30 --- /dev/null +++ b/openstack/stx-ocf-scripts/centos/stx-ocf-scripts.spec @@ -0,0 +1,30 @@ +Summary: Miscellaneous OCF scripts added by StarlingX +Name: stx-ocf-scripts +Version: 1.0 +Release: %{tis_patch_ver}%{?_tis_dist} +License: Apache-2.0 +Group: base +Packager: Wind River +URL: unknown + +Source0: %{name}-%{version}.tar.gz + +BuildArch: noarch +Requires: openstack-ras + +%description +Miscellaneous OCF scripts added by StarlingX + +%prep +%setup +%build + +%install +install -d -m 755 ${RPM_BUILD_ROOT}/usr/lib/ocf/resource.d/openstack +install -p -D -m 755 ocf/* ${RPM_BUILD_ROOT}/usr/lib/ocf/resource.d/openstack/ + +%files +%dir %attr(0755,root,root) /usr/lib/ocf/resource.d/openstack +%defattr(-,root,root,-) +/usr/lib/ocf/resource.d/openstack/* + diff --git a/openstack/stx-ocf-scripts/src/ocf/aodh-api b/openstack/stx-ocf-scripts/src/ocf/aodh-api new file mode 100644 index 00000000..391a9a2b --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/aodh-api @@ -0,0 +1,368 @@ +#!/bin/sh +# +# +# OpenStack Alarming API Service (aodh-api) +# +# Description: Manages an OpenStack Alarming API Service (aodh-api) process as an HA resource +# +# Authors: Emilien Macchi +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="aodh-api" +OCF_RESKEY_config_default="/etc/aodh/aodh.conf" +OCF_RESKEY_user_default="root" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_server_port_default="8042" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_server_port=${OCF_RESKEY_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Alarming API Service (aodh-api) +May manage a aodh-api instance or a clone set that +creates a distributed aodh-api cluster. + +Manages the OpenStack Alarming API Service (aodh-api) + + + + +Location of the OpenStack Alarming API server binary (aodh-api) + +OpenStack Alarming API server binary (aodh-api) + + + + + +Location of the OpenStack Alarming API Service (aodh-api) configuration file + +OpenStack Alarming API (aodh-api) config file + + + + + +User running OpenStack Alarming API Service (aodh-api) + +OpenStack Alarming API Service (aodh-api) user + + + + + +The pid file to use for this OpenStack Alarming API Service (aodh-api) instance + +OpenStack Alarming API Service (aodh-api) pid file + + + + + +The listening port number of the aodh-api server. + + +aodh-api listening port + + + + + +Additional parameters to pass on to the OpenStack Alarming API Service (aodh-api) + +Additional parameters for aodh-api + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +aodh_api_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +aodh_api_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + aodh_api_check_port $OCF_RESKEY_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +aodh_api_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Alarming API (aodh-api) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Alarming API (aodh-api) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +aodh_api_monitor() { + local rc + local pid + local rc_db + local engine_db_check + + aodh_api_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check the server is listening on the server port + engine_db_check=`netstat -an | grep -s "$OCF_RESKEY_console_port" | grep -qs "LISTEN"` + rc_db=$? + if [ $rc_db -ne 0 ]; then + ocf_log err "aodh-api is not listening on $OCF_RESKEY_console_port: $rc_db" + return $OCF_NOT_RUNNING + fi + + ocf_log debug "OpenStack Alarming API (aodh-api) monitor succeeded" + return $OCF_SUCCESS +} + +aodh_api_start() { + local rc + local host + + aodh_api_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Alarming API (aodh-api) already running" + return $OCF_SUCCESS + fi + + # run the actual aodh-api daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} + /bin/python /usr/bin/gunicorn --config /usr/share/aodh/aodh-api.conf --pythonpath /usr/share/aodh aodh-api \ + >> /var/log/aodh/aodh-api.log 2>&1 & echo $! > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + aodh_api_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Alarming API (aodh-api) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Alarming API (aodh-api) started" + return $OCF_SUCCESS +} + +aodh_api_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +aodh_api_stop() { + local rc + local pid + + aodh_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Alarming API (aodh-api) already stopped" + aodh_api_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Alarming API (aodh-api) couldn't be stopped" + aodh_api_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + aodh_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Alarming API (aodh-api) still hasn't stopped yet. Waiting ..." + done + + aodh_api_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Alarming API (aodh-api) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + aodh_api_confirm_stop + + ocf_log info "OpenStack Alarming API (aodh-api) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +aodh_api_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) aodh_api_start;; + stop) aodh_api_stop;; + status) aodh_api_status;; + monitor) aodh_api_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/aodh-evaluator b/openstack/stx-ocf-scripts/src/ocf/aodh-evaluator new file mode 100644 index 00000000..7088550b --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/aodh-evaluator @@ -0,0 +1,358 @@ +#!/bin/sh +# +# +# OpenStack Alarming Evaluator Service (aodh-evaluator) +# +# Description: Manages an OpenStack Alarming Evaluator Service (aodh-evaluator) process as an HA resource +# +# Authors: Emilien Macchi +# Mainly inspired by the Nova Scheduler resource agent written by Sebastien Han +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014-2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_amqp_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs +. /usr/bin/tsconfig + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="aodh-evaluator" +OCF_RESKEY_config_default="/etc/aodh/aodh.conf" +OCF_RESKEY_user_default="root" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_amqp_server_port_default="5672" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_amqp_server_port=${OCF_RESKEY_amqp_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Alarming Evaluator Service (aodh-evaluator) +May manage a aodh-evaluator instance or a clone set that +creates a distributed aodh-evaluator cluster. + +Manages the OpenStack Alarming Evaluator Service (aodh-evaluator) + + + + +Location of the OpenStack Alarming Evaluator server binary (aodh-evaluator) + +OpenStack Alarming Evaluator server binary (aodh-evaluator) + + + + + +Location of the OpenStack Alarming Evaluator Service (aodh-evaluator) configuration file + +OpenStack Alarming Evaluator (aodh-evaluator registry) config file + + + + + +User running OpenStack Alarming Evaluator Service (aodh-evaluator) + +OpenStack Alarming Evaluator Service (aodh-evaluator) user + + + + + +The pid file to use for this OpenStack Alarming Evaluator Service (aodh-evaluator) instance + +OpenStack Alarming Evaluator Service (aodh-evaluator) pid file + + + + + +The listening port number of the AMQP server. Use for monitoring purposes + +AMQP listening port + + + + + + +Additional parameters to pass on to the OpenStack Alarming Evaluator Service (aodh-evaluator) + +Additional parameters for aodh-evaluator + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +aodh_evaluator_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +aodh_evaluator_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + aodh_evaluator_check_port $OCF_RESKEY_amqp_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +aodh_evaluator_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Alarming Evaluator (aodh-evaluator) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Alarming Evaluator (aodh-evaluator) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +aodh_evaluator_monitor() { + local rc + local pid + local scheduler_amqp_check + + aodh_evaluator_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + ocf_log debug "OpenStack Alarming Evaluator (aodh-evaluator) monitor succeeded" + return $OCF_SUCCESS +} + +aodh_evaluator_start() { + local rc + + aodh_evaluator_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Alarming Evaluator (aodh-evaluator) already running" + return $OCF_SUCCESS + fi + + # run the actual aodh-evaluator daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + aodh_evaluator_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Alarming Evaluator (aodh-evaluator) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Alarming Evaluator (aodh-evaluator) started" + return $OCF_SUCCESS +} + +aodh_evaluator_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +aodh_evaluator_stop() { + local rc + local pid + + aodh_evaluator_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Alarming Evaluator (aodh-evaluator) already stopped" + aodh_evaluator_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Alarming Evaluator (aodh-evaluator) couldn't be stopped" + aodh_evaluator_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=2 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + aodh_evaluator_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Alarming Evaluator (aodh-evaluator) still hasn't stopped yet. Waiting ..." + done + + aodh_evaluator_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Alarming Evaluator (aodh-evaluator) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + aodh_evaluator_confirm_stop + + ocf_log info "OpenStack Alarming Evaluator (aodh-evaluator) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +aodh_evaluator_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) aodh_evaluator_start;; + stop) aodh_evaluator_stop;; + status) aodh_evaluator_status;; + monitor) aodh_evaluator_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac diff --git a/openstack/stx-ocf-scripts/src/ocf/aodh-listener b/openstack/stx-ocf-scripts/src/ocf/aodh-listener new file mode 100644 index 00000000..d3ce1aa8 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/aodh-listener @@ -0,0 +1,358 @@ +#!/bin/sh +# +# +# OpenStack Alarming Listener Service (aodh-listener) +# +# Description: Manages an OpenStack Alarming Listener Service (aodh-listener) process as an HA resource +# +# Authors: Emilien Macchi +# Mainly inspired by the Nova Scheduler resource agent written by Sebastien Han +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014-2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_amqp_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs +. /usr/bin/tsconfig + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="aodh-listener" +OCF_RESKEY_config_default="/etc/aodh/aodh.conf" +OCF_RESKEY_user_default="root" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_amqp_server_port_default="5672" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_amqp_server_port=${OCF_RESKEY_amqp_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Alarming Listener Service (aodh-listener) +May manage a aodh-listener instance or a clone set that +creates a distributed aodh-listener cluster. + +Manages the OpenStack Alarming Listener Service (aodh-listener) + + + + +Location of the OpenStack Alarming Listener server binary (aodh-listener) + +OpenStack Alarming Listener server binary (aodh-listener) + + + + + +Location of the OpenStack Alarming Listener Service (aodh-listener) configuration file + +OpenStack Alarming Listener (aodh-listener registry) config file + + + + + +User running OpenStack Alarming Listener Service (aodh-listener) + +OpenStack Alarming Listener Service (aodh-listener) user + + + + + +The pid file to use for this OpenStack Alarming Listener Service (aodh-listener) instance + +OpenStack Alarming Listener Service (aodh-listener) pid file + + + + + +The listening port number of the AMQP server. Use for monitoring purposes + +AMQP listening port + + + + + + +Additional parameters to pass on to the OpenStack Alarming Listener Service (aodh-listener) + +Additional parameters for aodh-listener + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +aodh_listener_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +aodh_listener_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + aodh_listener_check_port $OCF_RESKEY_amqp_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +aodh_listener_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Alarming Listener (aodh-listener) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Alarming Listener (aodh-listener) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +aodh_listener_monitor() { + local rc + local pid + local scheduler_amqp_check + + aodh_listener_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + ocf_log debug "OpenStack Alarming Listener (aodh-listener) monitor succeeded" + return $OCF_SUCCESS +} + +aodh_listener_start() { + local rc + + aodh_listener_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Alarming Listener (aodh-listener) already running" + return $OCF_SUCCESS + fi + + # run the actual aodh-listener daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + aodh_listener_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Alarming Listener (aodh-listener) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Alarming Listener (aodh-listener) started" + return $OCF_SUCCESS +} + +aodh_listener_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +aodh_listener_stop() { + local rc + local pid + + aodh_listener_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Alarming Listener (aodh-listener) already stopped" + aodh_listener_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Alarming Listener (aodh-listener) couldn't be stopped" + aodh_listener_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=2 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + aodh_listener_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Alarming Listener (aodh-listener) still hasn't stopped yet. Waiting ..." + done + + aodh_listener_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Alarming Listener (aodh-listener) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + aodh_listener_confirm_stop + + ocf_log info "OpenStack Alarming Listener (aodh-listener) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +aodh_listener_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) aodh_listener_start;; + stop) aodh_listener_stop;; + status) aodh_listener_status;; + monitor) aodh_listener_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac diff --git a/openstack/stx-ocf-scripts/src/ocf/aodh-notifier b/openstack/stx-ocf-scripts/src/ocf/aodh-notifier new file mode 100644 index 00000000..5dc72fe2 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/aodh-notifier @@ -0,0 +1,358 @@ +#!/bin/sh +# +# +# OpenStack Alarming Notifier Service (aodh-notifier) +# +# Description: Manages an OpenStack Alarming Notifier Service (aodh-notifier) process as an HA resource +# +# Authors: Emilien Macchi +# Mainly inspired by the Nova Scheduler resource agent written by Sebastien Han +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014-2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_amqp_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs +. /usr/bin/tsconfig + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="aodh-notifier" +OCF_RESKEY_config_default="/etc/aodh/aodh.conf" +OCF_RESKEY_user_default="root" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_amqp_server_port_default="5672" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_amqp_server_port=${OCF_RESKEY_amqp_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Alarming Notifier Service (aodh-notifier) +May manage a aodh-notifier instance or a clone set that +creates a distributed aodh-notifier cluster. + +Manages the OpenStack Alarming Notifier Service (aodh-notifier) + + + + +Location of the OpenStack Alarming Notifier server binary (aodh-notifier) + +OpenStack Alarming Notifier server binary (aodh-notifier) + + + + + +Location of the OpenStack Alarming Notifier Service (aodh-notifier) configuration file + +OpenStack Alarming Notifier (aodh-notifier registry) config file + + + + + +User running OpenStack Alarming Notifier Service (aodh-notifier) + +OpenStack Alarming Notifier Service (aodh-notifier) user + + + + + +The pid file to use for this OpenStack Alarming Notifier Service (aodh-notifier) instance + +OpenStack Alarming Notifier Service (aodh-notifier) pid file + + + + + +The listening port number of the AMQP server. Use for monitoring purposes + +AMQP listening port + + + + + + +Additional parameters to pass on to the OpenStack Alarming Notifier Service (aodh-notifier) + +Additional parameters for aodh-notifier + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +aodh_notifier_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +aodh_notifier_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + aodh_notifier_check_port $OCF_RESKEY_amqp_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +aodh_notifier_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Alarming Notifier (aodh-notifier) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Alarming Notifier (aodh-notifier) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +aodh_notifier_monitor() { + local rc + local pid + local scheduler_amqp_check + + aodh_notifier_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + ocf_log debug "OpenStack Alarming Notifier (aodh-notifier) monitor succeeded" + return $OCF_SUCCESS +} + +aodh_notifier_start() { + local rc + + aodh_notifier_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Alarming Notifier (aodh-notifier) already running" + return $OCF_SUCCESS + fi + + # run the actual aodh-notifier daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + aodh_notifier_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Alarming Notifier (aodh-notifier) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Alarming Notifier (aodh-notifier) started" + return $OCF_SUCCESS +} + +aodh_notifier_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +aodh_notifier_stop() { + local rc + local pid + + aodh_notifier_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Alarming Notifier (aodh-notifier) already stopped" + aodh_notifier_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Alarming Notifier (aodh-notifier) couldn't be stopped" + aodh_notifier_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=2 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + aodh_notifier_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Alarming Notifier (aodh-notifier) still hasn't stopped yet. Waiting ..." + done + + aodh_notifier_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Alarming Notifier (aodh-notifier) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + aodh_notifier_confirm_stop + + ocf_log info "OpenStack Alarming Notifier (aodh-notifier) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +aodh_notifier_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) aodh_notifier_start;; + stop) aodh_notifier_stop;; + status) aodh_notifier_status;; + monitor) aodh_notifier_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac diff --git a/openstack/stx-ocf-scripts/src/ocf/ceilometer-agent-notification b/openstack/stx-ocf-scripts/src/ocf/ceilometer-agent-notification new file mode 100644 index 00000000..47612706 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/ceilometer-agent-notification @@ -0,0 +1,370 @@ +#!/bin/sh +# +# +# OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) +# +# Description: Manages an OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) process as an HA resource +# +# Authors: Emilien Macchi +# Mainly inspired by the Nova Scheduler resource agent written by Sebastien Han +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014-2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_pipeline +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_amqp_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs +. /usr/bin/tsconfig + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="ceilometer-agent-notification" +OCF_RESKEY_config_default="/etc/ceilometer/ceilometer.conf" +OCF_RESKEY_pipeline_default="/opt/cgcs/ceilometer/${SW_VERSION}/pipeline.yaml" +OCF_RESKEY_user_default="root" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_amqp_server_port_default="5672" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_pipeline=${OCF_RESKEY_pipeline_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_amqp_server_port=${OCF_RESKEY_amqp_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) +May manage a ceilometer-agent-notification instance or a clone set that +creates a distributed ceilometer-agent-notification cluster. + +Manages the OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) + + + + +Location of the OpenStack Ceilometer Central Agent server binary (ceilometer-agent-notification) + +OpenStack Ceilometer Central Agent server binary (ceilometer-agent-notification) + + + + + +Location of the OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) configuration file + +OpenStack Ceilometer Central Agent (ceilometer-agent-notification registry) config file + + + + + +Location of the OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) pipeline file + +OpenStack Ceilometer Central Agent (ceilometer-agent-notification registry) pipeline file + + + + + +User running OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) + +OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) user + + + + + +The pid file to use for this OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) instance + +OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) pid file + + + + + +The listening port number of the AMQP server. Use for monitoring purposes + +AMQP listening port + + + + + + +Additional parameters to pass on to the OpenStack Ceilometer Central Agent Service (ceilometer-agent-notification) + +Additional parameters for ceilometer-agent-notification + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +ceilometer_agent_notification_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +ceilometer_agent_notification_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + ceilometer_agent_notification_check_port $OCF_RESKEY_amqp_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +ceilometer_agent_notification_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Ceilometer Central Agent (ceilometer-agent-notification) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +ceilometer_agent_notification_monitor() { + local rc + local pid + local scheduler_amqp_check + + ceilometer_agent_notification_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + ocf_log debug "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) monitor succeeded" + return $OCF_SUCCESS +} + +ceilometer_agent_notification_start() { + local rc + + ceilometer_agent_notification_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) already running" + return $OCF_SUCCESS + fi + + # run the actual ceilometer-agent-notification daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + --pipeline_cfg_file=$OCF_RESKEY_pipeline \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + ceilometer_agent_notification_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) started" + return $OCF_SUCCESS +} + +ceilometer_agent_notification_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +ceilometer_agent_notification_stop() { + local rc + local pid + + ceilometer_agent_notification_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) already stopped" + ceilometer_agent_notification_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) couldn't be stopped" + ceilometer_agent_notification_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=2 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + ceilometer_agent_notification_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) still hasn't stopped yet. Waiting ..." + done + + ceilometer_agent_notification_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + ceilometer_agent_notification_confirm_stop + + ocf_log info "OpenStack Ceilometer Central Agent (ceilometer-agent-notification) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +ceilometer_agent_notification_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) ceilometer_agent_notification_start;; + stop) ceilometer_agent_notification_stop;; + status) ceilometer_agent_notification_status;; + monitor) ceilometer_agent_notification_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac diff --git a/openstack/stx-ocf-scripts/src/ocf/heat-api b/openstack/stx-ocf-scripts/src/ocf/heat-api new file mode 100644 index 00000000..d7ffa311 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/heat-api @@ -0,0 +1,366 @@ +#!/bin/sh +# +# +# OpenStack Orchestration Engine Service (heat-api) +# +# Description: Manages an OpenStack Orchestration Engine Service (heat-api) process as an HA resource +# +# Authors: Emilien Macchi +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="heat-api" +OCF_RESKEY_config_default="/etc/heat/heat.conf" +OCF_RESKEY_user_default="heat" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_server_port_default="8004" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_server_port=${OCF_RESKEY_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Orchestration Engine Service (heat-api) +May manage a heat-api instance or a clone set that +creates a distributed heat-api cluster. + +Manages the OpenStack Orchestration Engine Service (heat-api) + + + + +Location of the OpenStack Orchestration Engine server binary (heat-api) + +OpenStack Orchestration Engine server binary (heat-api) + + + + + +Location of the OpenStack Orchestration Engine Service (heat-api) configuration file + +OpenStack Orchestration Engine (heat-api) config file + + + + + +User running OpenStack Orchestration Engine Service (heat-api) + +OpenStack Orchestration Engine Service (heat-api) user + + + + + +The pid file to use for this OpenStack Orchestration Engine Service (heat-api) instance + +OpenStack Orchestration Engine Service (heat-api) pid file + + + + + +The listening port number of the heat-api server. + + +heat-api listening port + + + + + +Additional parameters to pass on to the OpenStack Orchestration Engine Service (heat-api) + +Additional parameters for heat-api + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +heat_api_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +heat_api_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + heat_api_check_port $OCF_RESKEY_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +heat_api_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Orchestration Engine (heat-api) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Orchestration Engine (heat-api) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +heat_api_monitor() { + local rc + local pid + local rc_db + local engine_db_check + + heat_api_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check the server is listening on the server port + engine_db_check=`netstat -an | grep -s "$OCF_RESKEY_console_port" | grep -qs "LISTEN"` + rc_db=$? + if [ $rc_db -ne 0 ]; then + ocf_log err "heat-api is not listening on $OCF_RESKEY_console_port: $rc_db" + return $OCF_NOT_RUNNING + fi + + ocf_log debug "OpenStack Orchestration Engine (heat-api) monitor succeeded" + return $OCF_SUCCESS +} + +heat_api_start() { + local rc + + heat_api_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Orchestration Engine (heat-api) already running" + return $OCF_SUCCESS + fi + + # run the actual heat-api daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + heat_api_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Orchestration Engine (heat-api) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Orchestration Engine (heat-api) started" + return $OCF_SUCCESS +} + +heat_api_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +heat_api_stop() { + local rc + local pid + + heat_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Orchestration Engine (heat-api) already stopped" + heat_api_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Orchestration Engine (heat-api) couldn't be stopped" + heat_api_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + heat_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Orchestration Engine (heat-api) still hasn't stopped yet. Waiting ..." + done + + heat_api_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Orchestration Engine (heat-api) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + heat_api_confirm_stop + + ocf_log info "OpenStack Orchestration Engine (heat-api) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +heat_api_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) heat_api_start;; + stop) heat_api_stop;; + status) heat_api_status;; + monitor) heat_api_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/heat-api-cfn b/openstack/stx-ocf-scripts/src/ocf/heat-api-cfn new file mode 100644 index 00000000..c5d41f52 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/heat-api-cfn @@ -0,0 +1,366 @@ +#!/bin/sh +# +# +# OpenStack Orchestration Engine Service (heat-api-cfn) +# +# Description: Manages an OpenStack Orchestration Engine Service (heat-api-cfn) process as an HA resource +# +# Authors: Emilien Macchi +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="heat-api-cfn" +OCF_RESKEY_config_default="/etc/heat/heat.conf" +OCF_RESKEY_user_default="heat" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_server_port_default="8000" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_server_port=${OCF_RESKEY_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Orchestration Engine Service (heat-api-cfn) +May manage a heat-api-cfn instance or a clone set that +creates a distributed heat-api-cfn cluster. + +Manages the OpenStack Orchestration Engine Service (heat-api-cfn) + + + + +Location of the OpenStack Orchestration Engine server binary (heat-api-cfn) + +OpenStack Orchestration Engine server binary (heat-api-cfn) + + + + + +Location of the OpenStack Orchestration Engine Service (heat-api-cfn) configuration file + +OpenStack Orchestration Engine (heat-api-cfn) config file + + + + + +User running OpenStack Orchestration Engine Service (heat-api-cfn) + +OpenStack Orchestration Engine Service (heat-api-cfn) user + + + + + +The pid file to use for this OpenStack Orchestration Engine Service (heat-api-cfn) instance + +OpenStack Orchestration Engine Service (heat-api-cfn) pid file + + + + + +The listening port number of the heat-api-cfn server. + + +heat-api-cfn listening port + + + + + +Additional parameters to pass on to the OpenStack Orchestration Engine Service (heat-api-cfn) + +Additional parameters for heat-api-cfn + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +heat_api_cfn_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +heat_api_cfn_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + heat_api_cfn_check_port $OCF_RESKEY_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +heat_api_cfn_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Orchestration Engine (heat-api-cfn) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Orchestration Engine (heat-api-cfn) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +heat_api_cfn_monitor() { + local rc + local pid + local rc_db + local engine_db_check + + heat_api_cfn_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check the server is listening on the server port + engine_db_check=`netstat -an | grep -s "$OCF_RESKEY_console_port" | grep -qs "LISTEN"` + rc_db=$? + if [ $rc_db -ne 0 ]; then + ocf_log err "heat-api-cfn is not listening on $OCF_RESKEY_console_port: $rc_db" + return $OCF_NOT_RUNNING + fi + + ocf_log debug "OpenStack Orchestration Engine (heat-api-cfn) monitor succeeded" + return $OCF_SUCCESS +} + +heat_api_cfn_start() { + local rc + + heat_api_cfn_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Orchestration Engine (heat-api-cfn) already running" + return $OCF_SUCCESS + fi + + # run the actual heat-api-cfn daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + heat_api_cfn_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Orchestration Engine (heat-api-cfn) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Orchestration Engine (heat-api-cfn) started" + return $OCF_SUCCESS +} + +heat_api_cfn_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +heat_api_cfn_stop() { + local rc + local pid + + heat_api_cfn_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Orchestration Engine (heat-api-cfn) already stopped" + heat_api_cfn_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Orchestration Engine (heat-api-cfn) couldn't be stopped" + heat_api_cfn_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + heat_api_cfn_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Orchestration Engine (heat-api-cfn) still hasn't stopped yet. Waiting ..." + done + + heat_api_cfn_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Orchestration Engine (heat-api-cfn) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + heat_api_cfn_confirm_stop + + ocf_log info "OpenStack Orchestration Engine (heat-api-cfn) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +heat_api_cfn_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) heat_api_cfn_start;; + stop) heat_api_cfn_stop;; + status) heat_api_cfn_status;; + monitor) heat_api_cfn_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/heat-api-cloudwatch b/openstack/stx-ocf-scripts/src/ocf/heat-api-cloudwatch new file mode 100644 index 00000000..6623d610 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/heat-api-cloudwatch @@ -0,0 +1,366 @@ +#!/bin/sh +# +# +# OpenStack Orchestration Engine Service (heat-api-cloudwatch) +# +# Description: Manages an OpenStack Orchestration Engine Service (heat-api-cloudwatch) process as an HA resource +# +# Authors: Emilien Macchi +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="heat-api-cloudwatch" +OCF_RESKEY_config_default="/etc/heat/heat.conf" +OCF_RESKEY_user_default="heat" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_server_port_default="8000" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_server_port=${OCF_RESKEY_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Orchestration Engine Service (heat-api-cloudwatch) +May manage a heat-api-cloudwatch instance or a clone set that +creates a distributed heat-api-cloudwatch cluster. + +Manages the OpenStack Orchestration Engine Service (heat-api-cloudwatch) + + + + +Location of the OpenStack Orchestration Engine server binary (heat-api-cloudwatch) + +OpenStack Orchestration Engine server binary (heat-api-cloudwatch) + + + + + +Location of the OpenStack Orchestration Engine Service (heat-api-cloudwatch) configuration file + +OpenStack Orchestration Engine (heat-api-cloudwatch) config file + + + + + +User running OpenStack Orchestration Engine Service (heat-api-cloudwatch) + +OpenStack Orchestration Engine Service (heat-api-cloudwatch) user + + + + + +The pid file to use for this OpenStack Orchestration Engine Service (heat-api-cloudwatch) instance + +OpenStack Orchestration Engine Service (heat-api-cloudwatch) pid file + + + + + +The listening port number of the heat-api-cloudwatch server. + + +heat-api-cloudwatch listening port + + + + + +Additional parameters to pass on to the OpenStack Orchestration Engine Service (heat-api-cloudwatch) + +Additional parameters for heat-api-cloudwatch + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +heat_api_cloudwatch_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +heat_api_cloudwatch_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + heat_api_cloudwatch_check_port $OCF_RESKEY_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +heat_api_cloudwatch_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Orchestration Engine (heat-api-cloudwatch) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Orchestration Engine (heat-api-cloudwatch) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +heat_api_cloudwatch_monitor() { + local rc + local pid + local rc_db + local engine_db_check + + heat_api_cloudwatch_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check the server is listening on the server port + engine_db_check=`netstat -an | grep -s "$OCF_RESKEY_console_port" | grep -qs "LISTEN"` + rc_db=$? + if [ $rc_db -ne 0 ]; then + ocf_log err "heat-api-cloudwatch is not listening on $OCF_RESKEY_console_port: $rc_db" + return $OCF_NOT_RUNNING + fi + + ocf_log debug "OpenStack Orchestration Engine (heat-api-cloudwatch) monitor succeeded" + return $OCF_SUCCESS +} + +heat_api_cloudwatch_start() { + local rc + + heat_api_cloudwatch_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Orchestration Engine (heat-api-cloudwatch) already running" + return $OCF_SUCCESS + fi + + # run the actual heat-api-cloudwatch daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + heat_api_cloudwatch_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Orchestration Engine (heat-api-cloudwatch) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Orchestration Engine (heat-api-cloudwatch) started" + return $OCF_SUCCESS +} + +heat_api_cloudwatch_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +heat_api_cloudwatch_stop() { + local rc + local pid + + heat_api_cloudwatch_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Orchestration Engine (heat-api-cloudwatch) already stopped" + heat_api_cloudwatch_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Orchestration Engine (heat-api-cloudwatch) couldn't be stopped" + heat_api_cloudwatch_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + heat_api_cloudwatch_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Orchestration Engine (heat-api-cloudwatch) still hasn't stopped yet. Waiting ..." + done + + heat_api_cloudwatch_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Orchestration Engine (heat-api-cloudwatch) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + heat_api_cloudwatch_confirm_stop + + ocf_log info "OpenStack Orchestration Engine (heat-api-cloudwatch) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +heat_api_cloudwatch_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) heat_api_cloudwatch_start;; + stop) heat_api_cloudwatch_stop;; + status) heat_api_cloudwatch_status;; + monitor) heat_api_cloudwatch_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/ironic-api b/openstack/stx-ocf-scripts/src/ocf/ironic-api new file mode 100644 index 00000000..846842b9 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/ironic-api @@ -0,0 +1,366 @@ +#!/bin/sh +# +# +# OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) +# +# Description: Manages an OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) process as an HA resource +# +# Authors: Emilien Macchi +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="ironic-api" +OCF_RESKEY_config_default="/etc/ironic/ironic.conf" +OCF_RESKEY_user_default="ironic" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_server_port_default="6485" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_server_port=${OCF_RESKEY_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) +May manage a ironic-api instance or a clone set that +creates a distributed ironic-api cluster. + +Manages the OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) + + + + +Location of the OpenStack Container Orchestration Engine Provisioning API server binary (ironic-api) + +OpenStack Container Orchestration Engine Provisioning API server binary (ironic-api) + + + + + +Location of the OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) configuration file + +OpenStack Container Orchestration Engine Provisioning API (ironic-api) config file + + + + + +User running OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) + +OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) user + + + + + +The pid file to use for this OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) instance + +OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) pid file + + + + + +The listening port number of the ironic-api server. + + +ironic-api listening port + + + + + +Additional parameters to pass on to the OpenStack Container Orchestration Engine Provisioning API Service (ironic-api) + +Additional parameters for ironic-api + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +ironic_api_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +ironic_api_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + ironic_api_check_port $OCF_RESKEY_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +ironic_api_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (ironic-api) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Container Orchestration Engine Provisioning API (ironic-api) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +ironic_api_monitor() { + local rc + local pid + local rc_db + local engine_db_check + + ironic_api_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check the server is listening on the server port + engine_db_check=`netstat -an | grep -s "$OCF_RESKEY_console_port" | grep -qs "LISTEN"` + rc_db=$? + if [ $rc_db -ne 0 ]; then + ocf_log err "ironic-api is not listening on $OCF_RESKEY_console_port: $rc_db" + return $OCF_NOT_RUNNING + fi + + ocf_log debug "OpenStack Container Orchestration Engine Provisioning API (ironic-api) monitor succeeded" + return $OCF_SUCCESS +} + +ironic_api_start() { + local rc + + ironic_api_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (ironic-api) already running" + return $OCF_SUCCESS + fi + + # run the actual ironic-api daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + ironic_api_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Container Orchestration Engine Provisioning API (ironic-api) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (ironic-api) started" + return $OCF_SUCCESS +} + +ironic_api_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +ironic_api_stop() { + local rc + local pid + + ironic_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (ironic-api) already stopped" + ironic_api_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Bare Metal Provisioning Service API (ironic-api) couldn't be stopped" + ironic_api_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + ironic_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Container Orchestration Engine Provisioning API (ironic-api) still hasn't stopped yet. Waiting ..." + done + + ironic_api_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (ironic-api) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + ironic_api_confirm_stop + + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (ironic-api) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +ironic_api_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) ironic_api_start;; + stop) ironic_api_stop;; + status) ironic_api_status;; + monitor) ironic_api_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/ironic-conductor b/openstack/stx-ocf-scripts/src/ocf/ironic-conductor new file mode 100644 index 00000000..84970cdd --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/ironic-conductor @@ -0,0 +1,376 @@ +#!/bin/sh +# +# +# OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) +# +# Description: Manages an OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) process as an HA resource +# +# Authors: Emilien Macchi +# Mainly inspired by the Nova Scheduler resource agent written by Sebastien Han +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_amqp_server_port +# OCF_RESKEY_additional_parameters +# OCF_RESKEY_tftproot +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs +. /usr/bin/tsconfig + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="ironic-conductor" +OCF_RESKEY_config_default="/etc/ironic/ironic.conf" +OCF_RESKEY_user_default="root" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_amqp_server_port_default="5672" +OCF_RESKEY_tftproot_default="/opt/cgcs/ironic/" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_amqp_server_port=${OCF_RESKEY_amqp_server_port_default}} +: ${OCF_RESKEY_tftproot=${OCF_RESKEY_tftproot_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) +May manage a ironic-conductor instance or a clone set that +creates a distributed ironic-conductor cluster. + +Manages the OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) + + + + +Location of the OpenStack Bare Metal Provisioning Service Conductor server binary (ironic-conductor) + +OpenStack Bare Metal Provisioning Service Conductor server binary (ironic-conductor) + + + + + +Location of the OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) configuration file + +OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor registry) config file + + + + + +User running OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) + +OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) user + + + + + +The pid file to use for this OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) instance + +OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) pid file + + + + + +The listening port number of the AMQP server. Use for monitoring purposes + +AMQP listening port + + + + + + +Additional parameters to pass on to the OpenStack Bare Metal Provisioning Service Conductor Service (ironic-conductor) + +Additional parameters for ironic-conductor + + + + + +TFTP root directory to copy the base tftp files to + +OpenStack Bare Metal Provisioning Service TFTP root + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +ironic_conductor_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +ironic_conductor_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + ironic_conductor_check_port $OCF_RESKEY_amqp_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +ironic_conductor_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +ironic_conductor_monitor() { + local rc + local pid + local scheduler_amqp_check + + ironic_conductor_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + ocf_log debug "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) monitor succeeded" + return $OCF_SUCCESS +} + +ironic_conductor_start() { + local rc + + ironic_conductor_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) already running" + return $OCF_SUCCESS + fi + + # copy tftp server required files: pxelinux.0 and chain.c32 + rsync -c \ + /usr/share/syslinux/pxelinux.0 \ + /usr/share/syslinux/chain.c32 \ + ${OCF_RESKEY_tftproot}/ + chown ironic ${OCF_RESKEY_tftproot}/pxelinux.0 ${OCF_RESKEY_tftproot}/chain.c32 + + # run the actual ironic-conductor daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + ironic_conductor_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) started" + return $OCF_SUCCESS +} + +ironic_conductor_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +ironic_conductor_stop() { + local rc + local pid + + ironic_conductor_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) already stopped" + ironic_conductor_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) couldn't be stopped" + ironic_conductor_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=2 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + ironic_conductor_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) still hasn't stopped yet. Waiting ..." + done + + ironic_conductor_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + ironic_conductor_confirm_stop + + ocf_log info "OpenStack Bare Metal Provisioning Service Conductor (ironic-conductor) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +ironic_conductor_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) ironic_conductor_start;; + stop) ironic_conductor_stop;; + status) ironic_conductor_status;; + monitor) ironic_conductor_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac diff --git a/openstack/stx-ocf-scripts/src/ocf/magnum-api b/openstack/stx-ocf-scripts/src/ocf/magnum-api new file mode 100644 index 00000000..17e1daa4 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/magnum-api @@ -0,0 +1,366 @@ +#!/bin/sh +# +# +# OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) +# +# Description: Manages an OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) process as an HA resource +# +# Authors: Emilien Macchi +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="magnum-api" +OCF_RESKEY_config_default="/etc/magnum/magnum.conf" +OCF_RESKEY_user_default="magnum" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_server_port_default="9511" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_server_port=${OCF_RESKEY_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) +May manage a magnum-api instance or a clone set that +creates a distributed magnum-api cluster. + +Manages the OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) + + + + +Location of the OpenStack Container Orchestration Engine Provisioning API server binary (magnum-api) + +OpenStack Container Orchestration Engine Provisioning API server binary (magnum-api) + + + + + +Location of the OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) configuration file + +OpenStack Container Orchestration Engine Provisioning API (magnum-api) config file + + + + + +User running OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) + +OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) user + + + + + +The pid file to use for this OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) instance + +OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) pid file + + + + + +The listening port number of the magnum-api server. + + +magnum-api listening port + + + + + +Additional parameters to pass on to the OpenStack Container Orchestration Engine Provisioning API Service (magnum-api) + +Additional parameters for magnum-api + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +magnum_api_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +magnum_api_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + magnum_api_check_port $OCF_RESKEY_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +magnum_api_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (magnum-api) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Container Orchestration Engine Provisioning API (magnum-api) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +magnum_api_monitor() { + local rc + local pid + local rc_db + local engine_db_check + + magnum_api_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check the server is listening on the server port + engine_db_check=`netstat -an | grep -s "$OCF_RESKEY_console_port" | grep -qs "LISTEN"` + rc_db=$? + if [ $rc_db -ne 0 ]; then + ocf_log err "magnum-api is not listening on $OCF_RESKEY_console_port: $rc_db" + return $OCF_NOT_RUNNING + fi + + ocf_log debug "OpenStack Container Orchestration Engine Provisioning API (magnum-api) monitor succeeded" + return $OCF_SUCCESS +} + +magnum_api_start() { + local rc + + magnum_api_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (magnum-api) already running" + return $OCF_SUCCESS + fi + + # run the actual magnum-api daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + magnum_api_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Container Orchestration Engine Provisioning API (magnum-api) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (magnum-api) started" + return $OCF_SUCCESS +} + +magnum_api_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +magnum_api_stop() { + local rc + local pid + + magnum_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (magnum-api) already stopped" + magnum_api_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Container Orchestration Engine Provisioning API (magnum-api) couldn't be stopped" + magnum_api_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + magnum_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Container Orchestration Engine Provisioning API (magnum-api) still hasn't stopped yet. Waiting ..." + done + + magnum_api_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (magnum-api) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + magnum_api_confirm_stop + + ocf_log info "OpenStack Container Orchestration Engine Provisioning API (magnum-api) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +magnum_api_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) magnum_api_start;; + stop) magnum_api_stop;; + status) magnum_api_status;; + monitor) magnum_api_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/magnum-conductor b/openstack/stx-ocf-scripts/src/ocf/magnum-conductor new file mode 100644 index 00000000..f98ceb1e --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/magnum-conductor @@ -0,0 +1,358 @@ +#!/bin/sh +# +# +# OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) +# +# Description: Manages an OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) process as an HA resource +# +# Authors: Emilien Macchi +# Mainly inspired by the Nova Scheduler resource agent written by Sebastien Han +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_amqp_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs +. /usr/bin/tsconfig + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="magnum-conductor" +OCF_RESKEY_config_default="/etc/magnum/magnum.conf" +OCF_RESKEY_user_default="magnum" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_amqp_server_port_default="5672" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_amqp_server_port=${OCF_RESKEY_amqp_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) +May manage a magnum-conductor instance or a clone set that +creates a distributed magnum-conductor cluster. + +Manages the OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) + + + + +Location of the OpenStack Container Orchestration Engine Provisioning Conductor server binary (magnum-conductor) + +OpenStack Container Orchestration Engine Provisioning Conductor server binary (magnum-conductor) + + + + + +Location of the OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) configuration file + +OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor registry) config file + + + + + +User running OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) + +OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) user + + + + + +The pid file to use for this OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) instance + +OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) pid file + + + + + +The listening port number of the AMQP server. Use for monitoring purposes + +AMQP listening port + + + + + + +Additional parameters to pass on to the OpenStack Container Orchestration Engine Provisioning Conductor Service (magnum-conductor) + +Additional parameters for magnum-conductor + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +magnum_conductor_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +magnum_conductor_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + magnum_conductor_check_port $OCF_RESKEY_amqp_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +magnum_conductor_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +magnum_conductor_monitor() { + local rc + local pid + local scheduler_amqp_check + + magnum_conductor_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + ocf_log debug "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) monitor succeeded" + return $OCF_SUCCESS +} + +magnum_conductor_start() { + local rc + + magnum_conductor_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) already running" + return $OCF_SUCCESS + fi + + # run the actual magnum-conductor daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + magnum_conductor_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) started" + return $OCF_SUCCESS +} + +magnum_conductor_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +magnum_conductor_stop() { + local rc + local pid + + magnum_conductor_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) already stopped" + magnum_conductor_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) couldn't be stopped" + magnum_conductor_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=2 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + magnum_conductor_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) still hasn't stopped yet. Waiting ..." + done + + magnum_conductor_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + magnum_conductor_confirm_stop + + ocf_log info "OpenStack Container Orchestration Engine Provisioning Conductor (magnum-conductor) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +magnum_conductor_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) magnum_conductor_start;; + stop) magnum_conductor_stop;; + status) magnum_conductor_status;; + monitor) magnum_conductor_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac diff --git a/openstack/stx-ocf-scripts/src/ocf/murano-api b/openstack/stx-ocf-scripts/src/ocf/murano-api new file mode 100644 index 00000000..adad9a1f --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/murano-api @@ -0,0 +1,366 @@ +#!/bin/sh +# +# +# OpenStack Application Catalog API Service (murano-api) +# +# Description: Manages an OpenStack Application Catalog API Service (murano-api) process as an HA resource +# +# Authors: Emilien Macchi +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="murano-api" +OCF_RESKEY_config_default="/etc/murano/murano.conf" +OCF_RESKEY_user_default="murano" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_server_port_default="8082" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_server_port=${OCF_RESKEY_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Application Catalog API Service (murano-api) +May manage a murano-api instance or a clone set that +creates a distributed murano-api cluster. + +Manages the OpenStack Application Catalog API Service (murano-api) + + + + +Location of the OpenStack Application Catalog API server binary (murano-api) + +OpenStack Application Catalog API server binary (murano-api) + + + + + +Location of the OpenStack Application Catalog API Service (murano-api) configuration file + +OpenStack Application Catalog API (murano-api) config file + + + + + +User running OpenStack Application Catalog API Service (murano-api) + +OpenStack Application Catalog API Service (murano-api) user + + + + + +The pid file to use for this OpenStack Application Catalog API Service (murano-api) instance + +OpenStack Application Catalog API Service (murano-api) pid file + + + + + +The listening port number of the murano-api server. + + +murano-api listening port + + + + + +Additional parameters to pass on to the OpenStack Application Catalog API Service (murano-api) + +Additional parameters for murano-api + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +murano_api_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +murano_api_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + murano_api_check_port $OCF_RESKEY_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +murano_api_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Application Catalog API (murano-api) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Application Catalog API (murano-api) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +murano_api_monitor() { + local rc + local pid + local rc_db + local engine_db_check + + murano_api_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check the server is listening on the server port + engine_db_check=`netstat -an | grep -s "$OCF_RESKEY_console_port" | grep -qs "LISTEN"` + rc_db=$? + if [ $rc_db -ne 0 ]; then + ocf_log err "murano-api is not listening on $OCF_RESKEY_console_port: $rc_db" + return $OCF_NOT_RUNNING + fi + + ocf_log debug "OpenStack Application Catalog API (murano-api) monitor succeeded" + return $OCF_SUCCESS +} + +murano_api_start() { + local rc + + murano_api_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Application Catalog API (murano-api) already running" + return $OCF_SUCCESS + fi + + # run the actual murano-api daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + murano_api_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Application Catalog API (murano-api) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Application Catalog API (murano-api) started" + return $OCF_SUCCESS +} + +murano_api_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +murano_api_stop() { + local rc + local pid + + murano_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Application Catalog API (murano-api) already stopped" + murano_api_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Application Catalog API (murano-api) couldn't be stopped" + murano_api_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + murano_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Application Catalog API (murano-api) still hasn't stopped yet. Waiting ..." + done + + murano_api_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Application Catalog API (murano-api) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + murano_api_confirm_stop + + ocf_log info "OpenStack Application Catalog API (murano-api) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +murano_api_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) murano_api_start;; + stop) murano_api_stop;; + status) murano_api_status;; + monitor) murano_api_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/murano-engine b/openstack/stx-ocf-scripts/src/ocf/murano-engine new file mode 100644 index 00000000..2d89267c --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/murano-engine @@ -0,0 +1,358 @@ +#!/bin/sh +# +# +# OpenStack Application Catalog Engine Service (murano-engine) +# +# Description: Manages an OpenStack Application Catalog Engine Service (murano-engine) process as an HA resource +# +# Authors: Emilien Macchi +# Mainly inspired by the Nova Scheduler resource agent written by Sebastien Han +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014-2016 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_amqp_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs +. /usr/bin/tsconfig + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="murano-engine" +OCF_RESKEY_config_default="/etc/murano/murano.conf" +OCF_RESKEY_user_default="murano" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_amqp_server_port_default="5672" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_amqp_server_port=${OCF_RESKEY_amqp_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Application Catalog Engine Service (murano-engine) +May manage a murano-engine instance or a clone set that +creates a distributed murano-engine cluster. + +Manages the OpenStack Application Catalog Engine Service (murano-engine) + + + + +Location of the OpenStack Application Catalog Engine server binary (murano-engine) + +OpenStack Application Catalog Engine server binary (murano-engine) + + + + + +Location of the OpenStack Application Catalog Engine Service (murano-engine) configuration file + +OpenStack Application Catalog Engine (murano-engine registry) config file + + + + + +User running OpenStack Application Catalog Engine Service (murano-engine) + +OpenStack Application Catalog Engine Service (murano-engine) user + + + + + +The pid file to use for this OpenStack Application Catalog Engine Service (murano-engine) instance + +OpenStack Application Catalog Engine Service (murano-engine) pid file + + + + + +The listening port number of the AMQP server. Use for monitoring purposes + +AMQP listening port + + + + + + +Additional parameters to pass on to the OpenStack Application Catalog Engine Service (murano-engine) + +Additional parameters for murano-engine + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +murano_engine_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +murano_engine_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + murano_engine_check_port $OCF_RESKEY_amqp_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +murano_engine_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Application Catalog Engine (murano-engine) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Application Catalog Engine (murano-engine) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +murano_engine_monitor() { + local rc + local pid + local scheduler_amqp_check + + murano_engine_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + ocf_log debug "OpenStack Application Catalog Engine (murano-engine) monitor succeeded" + return $OCF_SUCCESS +} + +murano_engine_start() { + local rc + + murano_engine_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Application Catalog Engine (murano-engine) already running" + return $OCF_SUCCESS + fi + + # run the actual murano-engine daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + murano_engine_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Application Catalog Engine (murano-engine) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Application Catalog Engine (murano-engine) started" + return $OCF_SUCCESS +} + +murano_engine_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +murano_engine_stop() { + local rc + local pid + + murano_engine_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Application Catalog Engine (murano-engine) already stopped" + murano_engine_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Application Catalog Engine (murano-engine) couldn't be stopped" + murano_engine_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=2 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + murano_engine_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Application Catalog Engine (murano-engine) still hasn't stopped yet. Waiting ..." + done + + murano_engine_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Application Catalog Engine (murano-engine) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + murano_engine_confirm_stop + + ocf_log info "OpenStack Application Catalog Engine (murano-engine) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +murano_engine_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) murano_engine_start;; + stop) murano_engine_stop;; + status) murano_engine_status;; + monitor) murano_engine_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac diff --git a/openstack/stx-ocf-scripts/src/ocf/nova-compute b/openstack/stx-ocf-scripts/src/ocf/nova-compute new file mode 100644 index 00000000..c56b0813 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/nova-compute @@ -0,0 +1,359 @@ +#!/bin/sh +# +# +# OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) +# +# Description: Manages an OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) process as an HA resource +# +# Authors: Emilien Macchi +# Mainly inspired by the Nova Scheduler resource agent written by Sebastien Han +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_amqp_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs +. /usr/bin/tsconfig + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="nova-compute" +OCF_RESKEY_config_default="/etc/nova/nova-ironic.conf" +OCF_RESKEY_user_default="nova" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_amqp_server_port_default="5672" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_amqp_server_port=${OCF_RESKEY_amqp_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) +May manage a nova-compute instance or a clone set that +creates a distributed nova-compute cluster. + +Manages the OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) + + + + +Location of the OpenStack Bare Metal Provisioning Service Compute server binary (nova-compute) + +OpenStack Bare Metal Provisioning Service Compute server binary (nova-compute) + + + + + +Location of the OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) configuration file + +OpenStack Bare Metal Provisioning Service Compute (nova-compute registry) config file + + + + + +User running OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) + +OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) user + + + + + +The pid file to use for this OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) instance + +OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) pid file + + + + + +The listening port number of the AMQP server. Use for monitoring purposes + +AMQP listening port + + + + + + +Additional parameters to pass on to the OpenStack Bare Metal Provisioning Service Compute Service (nova-compute) + +Additional parameters for nova-compute + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +nova_compute_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +nova_compute_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + nova_compute_check_port $OCF_RESKEY_amqp_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +nova_compute_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Bare Metal Provisioning Service Compute (nova-compute) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Bare Metal Provisioning Service Compute (nova-compute) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +nova_compute_monitor() { + local rc + local pid + local scheduler_amqp_check + + nova_compute_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + ocf_log debug "OpenStack Bare Metal Provisioning Service Compute (nova-compute) monitor succeeded" + return $OCF_SUCCESS +} + +nova_compute_start() { + local rc + + nova_compute_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Bare Metal Provisioning Service Compute (nova-compute) already running" + return $OCF_SUCCESS + fi + + # run the actual nova-compute daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + nova_compute_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Bare Metal Provisioning Service Compute (nova-compute) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Bare Metal Provisioning Service Compute (nova-compute) started" + return $OCF_SUCCESS +} + +nova_compute_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +nova_compute_stop() { + local rc + local pid + + nova_compute_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Bare Metal Provisioning Service Compute (nova-compute) already stopped" + nova_compute_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Bare Metal Provisioning Service Compute (nova-compute) couldn't be stopped" + nova_compute_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=2 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + nova_compute_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Bare Metal Provisioning Service Compute (nova-compute) still hasn't stopped yet. Waiting ..." + done + + nova_compute_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Bare Metal Provisioning Service Compute (nova-compute) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + nova_compute_confirm_stop + + ocf_log info "OpenStack Bare Metal Provisioning Service Compute (nova-compute) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +nova_compute_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) nova_compute_start;; + stop) nova_compute_stop;; + status) nova_compute_status;; + monitor) nova_compute_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/nova-conductor b/openstack/stx-ocf-scripts/src/ocf/nova-conductor new file mode 100644 index 00000000..0283f2c5 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/nova-conductor @@ -0,0 +1,435 @@ +#!/bin/sh +# +# +# OpenStack Conductor Service (nova-conductor) +# +# Description: Manages an OpenStack Conductor Service (nova-conductor) process as an HA resource +# +# Authors: Sébastien Han +# Mainly inspired by the Glance API resource agent written by Martin Gerhard Loschwitz from Hastexo: http://goo.gl/whLpr +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_database_server_port +# OCF_RESKEY_amqp_server_port +# OCF_RESKEY_zeromq +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="nova-conductor" +OCF_RESKEY_config_default="/etc/nova/nova.conf" +OCF_RESKEY_user_default="nova" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_database_server_port_default="3306" +OCF_RESKEY_amqp_server_port_default="5672" +OCF_RESKEY_zeromq_default="false" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_database_server_port=${OCF_RESKEY_database_server_port_default}} +: ${OCF_RESKEY_amqp_server_port=${OCF_RESKEY_amqp_server_port_default}} +: ${OCF_RESKEY_zeromq=${OCF_RESKEY_zeromq_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Nova Conductor Service (nova-conductor) +May manage a nova-conductor instance or a clone set that +creates a distributed nova-conductor cluster. + +Manages the OpenStack Conductor Service (nova-conductor) + + + + +Location of the OpenStack Nova Conductor server binary (nova-conductor) + +OpenStack Nova Conductor server binary (nova-conductor) + + + + + +Location of the OpenStack Conductor Service (nova-conductor) configuration file + +OpenStack Nova Conductor (nova-conductor) config file + + + + + +User running OpenStack Conductor Service (nova-conductor) + +OpenStack Conductor Service (nova-conductor) user + + + + + +The pid file to use for this OpenStack Conductor Service (nova-conductor) instance + +OpenStack Conductor Service (nova-conductor) pid file + + + + + +The listening port number of the database server. Use for monitoring purposes + +Database listening port + + + + + +The listening port number of the AMQP server. Use for monitoring purposes + +AMQP listening port + + + + + +If zeromq is used, this will disable the connection test to the AMQP server. Use for monitoring purposes + +Zero-MQ usage + + + + + +Additional parameters to pass on to the OpenStack Conductor Service (nova-conductor) + +Additional parameters for nova-conductor + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +nova_conductor_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +nova_conductor_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + nova_conductor_check_port $OCF_RESKEY_database_server_port + nova_conductor_check_port $OCF_RESKEY_amqp_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +nova_conductor_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Nova Conductor (nova-conductor) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Nova Conductor (nova-conductor) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +check_port() { + local port=$1 + local pid=$2 + netstat -punt | grep -s "$port" | grep -s "$pid" | grep -qs "ESTABLISHED" + rc=$? + if [ $rc -eq 0 ]; then + return 0 + else + return 1 + fi +} + +nova_conductor_monitor() { + local rc + local pid + local rc_db + local rc_amqp + local conductor_db_check + local conductor_amqp_check + + nova_conductor_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check the connections according to the PID. + # We are sure to hit the conductor process and not other nova process with the same connection behavior (for example nova-cert) + if ocf_is_true "$OCF_RESKEY_zeromq"; then + pid=`cat $OCF_RESKEY_pid` + rc_db=`check_port $OCF_RESKEY_database_server_port $pid` + if [ $rc_db -ne 0 ]; then + ocf_log err "Nova Conductor is not connected to the database server: $rc_db" + return $OCF_NOT_RUNNING + fi + else + pid=`cat $OCF_RESKEY_pid` + rc_db=`check_port $OCF_RESKEY_database_server_port $pid` + rc_amqp=`check_port $OCF_RESKEY_amqp_server_port $pid` + if [ $rc_amqp -ne 0 ] || [ $rc_db -ne 0 ]; then + # may have multiple workers, in which case $pid is the parent and we want to check the children + # If there are no children or at least one child is not connected to both DB and AMQP then we fail. + KIDPIDS=`pgrep -P $pid -f nova-conductor` + if [ ! -z "$KIDPIDS" ]; then + for pid in $KIDPIDS + do + rc_db=`check_port $OCF_RESKEY_database_server_port $pid` + rc_amqp=`check_port $OCF_RESKEY_amqp_server_port $pid` + if [ $rc_amqp -ne 0 ] || [ $rc_db -ne 0 ]; then + ocf_log err "Nova Conductor pid $pid is not connected to the AMQP server and/or the database server: AMQP connection test returned $rc_amqp and database connection test returned $rc_db" + return $OCF_NOT_RUNNING + fi + done + else + ocf_log err "Nova Conductor pid $pid is not connected to the AMQP server and/or the database server: AMQP connection test returned $rc_amqp and database connection test returned $rc_db" + return $OCF_NOT_RUNNING + fi + fi + fi + + ocf_log debug "OpenStack Nova Conductor (nova-conductor) monitor succeeded" + return $OCF_SUCCESS +} + +nova_conductor_start() { + local rc + + nova_conductor_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Nova Conductor (nova-conductor) already running" + return $OCF_SUCCESS + fi + + # Change the working dir to /, to be sure it's accesible + cd / + + # Run the pre-start hooks. This can be used to trigger a nova database sync, for example. + /usr/bin/nova-controller-runhooks + + # run the actual nova-conductor daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + nova_conductor_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Nova Conductor (nova-conductor) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Nova Conductor (nova-conductor) started" + return $OCF_SUCCESS +} + +nova_conductor_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +nova_conductor_stop() { + local rc + local pid + + nova_conductor_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Nova Conductor (nova-conductor) already stopped" + nova_conductor_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Nova Conductor (nova-conductor) couldn't be stopped" + nova_conductor_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + nova_conductor_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Nova Conductor (nova-conductor) still hasn't stopped yet. Waiting ..." + done + + nova_conductor_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Nova Conductor (nova-conductor) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + nova_conductor_confirm_stop + + ocf_log info "OpenStack Nova Conductor (nova-conductor) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +nova_conductor_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) nova_conductor_start;; + stop) nova_conductor_stop;; + status) nova_conductor_status;; + monitor) nova_conductor_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/nova-placement-api b/openstack/stx-ocf-scripts/src/ocf/nova-placement-api new file mode 100644 index 00000000..0060f063 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/nova-placement-api @@ -0,0 +1,412 @@ +#!/bin/sh +# +# +# OpenStack NovaAPI (nova-placement-api) +# +# Description: Manages an OpenStack Nova Placement API (nova-placement-api) process as an HA resource +# +# Authors: Sébastien Han +# Mainly inspired by the Glance API resource agent written by Martin Gerhard Loschwitz from Hastexo: http://goo.gl/whLpr +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_os_username +# OCF_RESKEY_os_password +# OCF_RESKEY_os_tenant_name +# OCF_RESKEY_keystone_get_token_url +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="nova-placement-api" +OCF_RESKEY_config_default="/etc/nova/nova.conf" +OCF_RESKEY_user_default="nova" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_host_default="127.0.0.1" +OCF_RESKEY_server_port_default="8778" +OCF_RESKEY_url_default="http://127.0.0.1:$OCF_RESKEY_server_port_default/" +OCF_RESKEY_keystone_get_token_url_default="http://127.0.0.1:5000/v2.0/tokens" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_host=${OCF_RESKEY_host_default}} +: ${OCF_RESKEY_server_port=${OCF_RESKEY_server_port_default}} +: ${OCF_RESKEY_url=${OCF_RESKEY_url_default}} +: ${OCF_RESKEY_keystone_get_token_url=${OCF_RESKEY_keystone_get_token_url_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Nova Placement API Service (nova-placement-api) +May manage a nova-placement-api instance or a clone set that +creates a distributed nova-placement-api cluster. + +Manages the OpenStack Nova Placement API (nova-placement-api) + + + + +Location of the OpenStack Nova Placement API server binary (nova-placement-api) + +OpenStack Nova Placement API server binary (nova-placement-api) + + + + + +Location of the OpenStack Nova Placement API (nova-placement-api) configuration file + +OpenStack Nova Placement API (nova-placement-api registry) config file + + + + + +User running OpenStack Nova Placement API (nova-placement-api) + +OpenStack Nova Placement API (nova-placement-api) user + + + + + +The pid file to use for this OpenStack Nova Placement API (nova-placement-api) instance + +OpenStack Nova Placement API (nova-placement-api) pid file + + + + + +The default listening host of nova-placement-api. + +OpenStack Nova Placement API (nova-placement-api) monitor host + + + + + +The default listening port of nova-placement-api. + +OpenStack Nova Placement API (nova-placement-api) monitor port + + + + + +The default URL to use for monitoring this instance (nova-placement-api) via curl. Important note: the monitor function doesn't accept http return code different than 200, for instance redirection code will generate an error. Don't forget the '/' at the end of your url endpoint. For example http://127.0.0.1:8778/v1.1 won't work and http://127.0.0.1:8778/v1.1/ will. + +OpenStack Nova Placement API (nova-placement-api) monitor url + + + + + +The default URL to use to acquire a Nova Placement API (nova-placement-api) token for monitoring this instance +of OpenStack Nova Placement API (nova-placement-api) + +OpenStack Nova Placement API (nova-placement-api) url + + + + + +The username to use when connecting with Nova Placement API (nova-placement-api) for monitoring purposes + +Nova Placement API (nova-placement-api) monitoring login + + + + + +The password to use when connecting Nova Placement API (nova-placement-api) for monitoring purposes + +Nova Placement API (nova-placement-api) monitoring password + + + + + +The tenant to use when connecting Nova Placement API (nova-placement-api) for monitoring purposes + +Nova Placement API (nova-placement-api) monitoring tenant + + + + + +Additional parameters to pass on to the OpenStack Nova Placement API (nova-placement-api) + +Additional parameters for nova-placement-api + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +nova_placement_api_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary curl + check_binary tr + check_binary grep + check_binary cut + check_binary head + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +nova_placement_api_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Nova Placement API (nova-placement-api) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Nova Placement API (nova-placement-api) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +nova_placement_api_monitor() { + local rc + + nova_placement_api_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check detailed information about this specific version of the Placement API. + if [ -n "$OCF_RESKEY_os_username"] && [ -n "$OCF_RESKEY_os_tenant_name" ] && [ -n "$OCF_RESKEY_keystone_get_token_url" ]; then + ./validation $OCF_RESKEY_keystone_get_token_url $OCF_RESKEY_os_username $OCF_RESKEY_os_tenant_name + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "Failed to connect to the OpenStack Nova Placement API (nova-placement-api): $rc" + return $OCF_NOT_RUNNING + fi + fi + + ocf_log debug "OpenStack Nova Placement API (nova-placement-api) monitor succeeded" + return $OCF_SUCCESS +} + +nova_placement_api_start() { + local rc + + nova_placement_api_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Nova Placement API (nova-placement-api) already running" + return $OCF_SUCCESS + fi + + # Change the working dir to /, to be sure it's accesible + cd / + + # Run the pre-start hooks. This can be used to trigger a nova database sync, for example. + /usr/bin/nova-controller-runhooks + + # run the actual nova-placement-api daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} -p ${OCF_RESKEY_server_port} -b ${OCF_RESKEY_host} "' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + # Let the CRM/LRM time us out if required + while true; do + nova_placement_api_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Nova Placement API (nova-placement-api) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Nova Placement API (nova-placement-api) started" + return $OCF_SUCCESS +} + +nova_placement_api_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +nova_placement_api_stop() { + local rc + local pid + + nova_placement_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Nova Placement API (nova-placement-api) already stopped" + nova_placement_api_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Nova Placement API (nova-placement-api) couldn't be stopped" + nova_placement_api_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + nova_placement_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Nova Placement API (nova-placement-api) still hasn't stopped yet. Waiting ..." + done + + nova_placement_api_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Nova Placement API (nova-placement-api) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + nova_placement_api_confirm_stop + + ocf_log info "OpenStack Nova Placement API (nova-placement-api) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +nova_placement_api_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) nova_placement_api_start;; + stop) nova_placement_api_stop;; + status) nova_placement_api_status;; + monitor) nova_placement_api_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/nova-serialproxy b/openstack/stx-ocf-scripts/src/ocf/nova-serialproxy new file mode 100644 index 00000000..3542f5ea --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/nova-serialproxy @@ -0,0 +1,349 @@ +#!/bin/sh +# +# +# OpenStack Nova Serial Console (nova-serialproxy) +# +# Description: Manages an OpenStack Nova Serialproxy (nova-serialproxy) process as an HA resource +# +# Authors: Sébastien Han +# Mainly inspired by the novnc API resource agent written by Martin Gerhard Loschwitz from Hastexo: http://goo.gl/whLpr +# +# Support: openstack@lists.launchpad.net +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_console_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="nova-serialproxy" +OCF_RESKEY_config_default="/etc/nova/nova-ironic.conf" +OCF_RESKEY_user_default="nova" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_console_port_default="6083" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_console_port=${OCF_RESKEY_console_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Nova Serialproxy Service (nova-serialproxy) +May manage a nova-serialproxy instance or a clone set that +creates a distributed nova-serialproxy cluster. + +Manages the OpenStack Nova Serial Console (nova-serialproxy) + + + + +Location of the OpenStack Nova Serial Console server binary (nova-serialproxy) + +OpenStack Nova Serial Console server binary (nova-serialproxy) + + + + + +Location of the OpenStack Nova Serial Console (nova-serialproxy) configuration file + +OpenStack Nova Serial Console (nova-serialproxy registry) config file + + + + + +User running OpenStack Nova Serial proxy (nova-serialproxy) + +OpenStack Nova Serialproxy (nova-serialproxy) user + + + + + +Serial console type running: nova-serialproxy + +OpenStack Nova Serial Console (nova-serialproxy) console type + + + + + +The pid file to use for this OpenStack Nova Serial Console (nova-serialproxy) instance + +OpenStack Nova VNC Console (nova-serialproxy) pid file + + + + + +Additional parameters to pass on to the OpenStack Nova Serialproxy (nova-serialproxy) + +Additional parameters for nova-serialproxy + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +nova_serial_console_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +nova_serial_console_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Nova Serialproxy (nova-serialproxy) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Nova Serialproxy (nova-serialproxy) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +nova_serial_console_monitor() { + local rc + local serial_list_check + + nova_serial_console_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check whether we are supposed to monitor by logging into nova-serialproxy + # and do it if that's the case. + # Adding -n to netstat so that dns delays will not impact this. + serial_list_check=`netstat -an | grep -s "$OCF_RESKEY_console_port" | grep -qs "LISTEN"` + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "Nova Serial Console doesn't seem to listen on his default port: $rc" + return $OCF_NOT_RUNNING + fi + + ocf_log debug "OpenStack Nova Serial Console (nova-serialproxy) monitor succeeded" + return $OCF_SUCCESS +} + +nova_serial_console_start() { + local rc + + nova_serial_console_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Nova Serial Console (nova-serialproxy) already running" + return $OCF_SUCCESS + fi + + # Change the working dir to /, to be sure it's accesible + cd / + + # run the actual nova-serialproxy daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \ + $OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + # Let the CRM/LRM time us out if required + while true; do + nova_serial_console_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Nova Serial Console (nova-serialproxy) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Nova Serial Console (nova-serialproxy) started" + return $OCF_SUCCESS +} + +nova_serial_console_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +nova_serial_console_stop() { + local rc + local pid + + nova_serial_console_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Nova Serial Console (nova-serialproxy) already stopped" + nova_serial_console_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Nova Serial Console (nova-serialproxy) couldn't be stopped" + nova_serial_console_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + nova_serial_console_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Nova Serial Console (nova-serialproxy) still hasn't stopped yet. Waiting ..." + done + + nova_serial_console_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Nova Serial Console (nova-serialproxy) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + nova_serial_console_confirm_stop + + ocf_log info "OpenStack Nova Serial Console (nova-serialproxy) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +nova_serial_console_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) nova_serial_console_start;; + stop) nova_serial_console_stop;; + status) nova_serial_console_status;; + monitor) nova_serial_console_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/panko-api b/openstack/stx-ocf-scripts/src/ocf/panko-api new file mode 100644 index 00000000..4e46365e --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/panko-api @@ -0,0 +1,365 @@ +#!/bin/sh +# +# +# OpenStack Panko API Service (panko-api) +# +# Description: Manages an OpenStack Panko API Service (panko-api) process as an HA resource +# +# License: Apache Software License (ASL) 2.0 +# +# Copyright (c) 2017 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# +# See usage() function below for more details ... +# +# OCF instance parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_config +# OCF_RESKEY_user +# OCF_RESKEY_pid +# OCF_RESKEY_monitor_binary +# OCF_RESKEY_server_port +# OCF_RESKEY_additional_parameters +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +# Fill in some defaults if no values are specified + +OCF_RESKEY_binary_default="panko-api" +OCF_RESKEY_config_default="/etc/panko/panko.conf" +OCF_RESKEY_user_default="root" +OCF_RESKEY_pid_default="$HA_RSCTMP/$OCF_RESOURCE_INSTANCE.pid" +OCF_RESKEY_server_port_default="8977" + +: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} +: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} +: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} +: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} +: ${OCF_RESKEY_server_port=${OCF_RESKEY_server_port_default}} + +####################################################################### + +usage() { + cat < + + +1.0 + + +Resource agent for the OpenStack Panko API Service (panko-api) +May manage a panko-api instance or a clone set that +creates a distributed panko-api cluster. + +Manages the OpenStack Panko API Service (panko-api) + + + + +Location of the OpenStack Panko API server binary (panko-api) + +OpenStack Panko API server binary (panko-api) + + + + + +Location of the OpenStack Panko API Service (panko-api) configuration file + +OpenStack Panko API (panko-api) config file + + + + + +User running OpenStack Panko API Service (panko-api) + +OpenStack Panko API Service (panko-api) user + + + + + +The pid file to use for this OpenStack Panko API Service (panko-api) instance + +OpenStack Panko API Service (panko-api) pid file + + + + + +The listening port number of the panko-api server. + + +panko-api listening port + + + + + +Additional parameters to pass on to the OpenStack Panko API Service (panko-api) + +Additional parameters for panko-api + + + + + + + + + + + + + + +END +} + +####################################################################### +# Functions invoked by resource manager actions + +panko_api_check_port() { +# This function has been taken from the squid RA and improved a bit +# The length of the integer must be 4 +# Examples of valid port: "1080", "0080" +# Examples of invalid port: "1080bad", "0", "0000", "" + + local int + local cnt + + int="$1" + cnt=${#int} + echo $int |egrep -qx '[0-9]+(:[0-9]+)?(,[0-9]+(:[0-9]+)?)*' + + if [ $? -ne 0 ] || [ $cnt -ne 4 ]; then + ocf_log err "Invalid port number: $1" + exit $OCF_ERR_CONFIGURED + fi +} + +panko_api_validate() { + local rc + + check_binary $OCF_RESKEY_binary + check_binary netstat + panko_api_check_port $OCF_RESKEY_server_port + + # A config file on shared storage that is not available + # during probes is OK. + if [ ! -f $OCF_RESKEY_config ]; then + if ! ocf_is_probe; then + ocf_log err "Config $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + + true +} + +panko_api_status() { + local pid + local rc + + if [ ! -f $OCF_RESKEY_pid ]; then + ocf_log info "OpenStack Panko API (panko-api) is not running" + return $OCF_NOT_RUNNING + else + pid=`cat $OCF_RESKEY_pid` + fi + + ocf_run -warn kill -s 0 $pid + rc=$? + if [ $rc -eq 0 ]; then + return $OCF_SUCCESS + else + ocf_log info "Old PID file found, but OpenStack Panko API (panko-api) is not running" + rm -f $OCF_RESKEY_pid + return $OCF_NOT_RUNNING + fi +} + +panko_api_monitor() { + local rc + local pid + local rc_db + local engine_db_check + + panko_api_status + rc=$? + + # If status returned anything but success, return that immediately + if [ $rc -ne $OCF_SUCCESS ]; then + return $rc + fi + + # Check the server is listening on the server port + engine_db_check=`netstat -an | grep -s "$OCF_RESKEY_console_port" | grep -qs "LISTEN"` + rc_db=$? + if [ $rc_db -ne 0 ]; then + ocf_log err "panko-api is not listening on $OCF_RESKEY_console_port: $rc_db" + return $OCF_NOT_RUNNING + fi + + ocf_log debug "OpenStack Panko API (panko-api) monitor succeeded" + return $OCF_SUCCESS +} + +panko_api_start() { + local rc + local host + + panko_api_status + rc=$? + if [ $rc -eq $OCF_SUCCESS ]; then + ocf_log info "OpenStack Panko API (panko-api) already running" + return $OCF_SUCCESS + fi + + # run the actual panko-api daemon. Don't use ocf_run as we're sending the tool's output + # straight to /dev/null anyway and using ocf_run would break stdout-redirection here. + su ${OCF_RESKEY_user} + /bin/python /usr/bin/gunicorn --config /usr/share/panko/panko-api.conf --access-logfile /dev/null \ + --pythonpath /usr/share/panko panko-api >> /var/log/panko/panko-api.log 2>&1 & echo $! > $OCF_RESKEY_pid + + # Spin waiting for the server to come up. + while true; do + panko_api_monitor + rc=$? + [ $rc -eq $OCF_SUCCESS ] && break + if [ $rc -ne $OCF_NOT_RUNNING ]; then + ocf_log err "OpenStack Panko API (panko-api) start failed" + exit $OCF_ERR_GENERIC + fi + sleep 1 + done + + ocf_log info "OpenStack Panko API (panko-api) started" + return $OCF_SUCCESS +} + +panko_api_confirm_stop() { + local my_bin + local my_processes + + my_binary=`which ${OCF_RESKEY_binary}` + my_processes=`pgrep -l -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)"` + + if [ -n "${my_processes}" ] + then + ocf_log info "About to SIGKILL the following: ${my_processes}" + pkill -KILL -f "^(python|/usr/bin/python|/usr/bin/python2) ${my_binary}([^\w-]|$)" + fi +} + +panko_api_stop() { + local rc + local pid + + panko_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + ocf_log info "OpenStack Panko API (panko-api) already stopped" + panko_api_confirm_stop + return $OCF_SUCCESS + fi + + # Try SIGTERM + pid=`cat $OCF_RESKEY_pid` + ocf_run kill -s TERM $pid + rc=$? + if [ $rc -ne 0 ]; then + ocf_log err "OpenStack Panko API (panko-api) couldn't be stopped" + panko_api_confirm_stop + exit $OCF_ERR_GENERIC + fi + + # stop waiting + shutdown_timeout=15 + if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then + shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) + fi + count=0 + while [ $count -lt $shutdown_timeout ]; do + panko_api_status + rc=$? + if [ $rc -eq $OCF_NOT_RUNNING ]; then + break + fi + count=`expr $count + 1` + sleep 1 + ocf_log debug "OpenStack Panko API (panko-api) still hasn't stopped yet. Waiting ..." + done + + panko_api_status + rc=$? + if [ $rc -ne $OCF_NOT_RUNNING ]; then + # SIGTERM didn't help either, try SIGKILL + ocf_log info "OpenStack Panko API (panko-api) failed to stop after ${shutdown_timeout}s \ + using SIGTERM. Trying SIGKILL ..." + ocf_run kill -s KILL $pid + fi + panko_api_confirm_stop + + ocf_log info "OpenStack Panko API (panko-api) stopped" + + rm -f $OCF_RESKEY_pid + + return $OCF_SUCCESS +} + +####################################################################### + +case "$1" in + meta-data) meta_data + exit $OCF_SUCCESS;; + usage|help) usage + exit $OCF_SUCCESS;; +esac + +# Anything except meta-data and help must pass validation +panko_api_validate || exit $? + +# What kind of method was invoked? +case "$1" in + start) panko_api_start;; + stop) panko_api_stop;; + status) panko_api_status;; + monitor) panko_api_monitor;; + validate-all) ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac + diff --git a/openstack/stx-ocf-scripts/src/ocf/validation b/openstack/stx-ocf-scripts/src/ocf/validation new file mode 100644 index 00000000..fc8c3140 --- /dev/null +++ b/openstack/stx-ocf-scripts/src/ocf/validation @@ -0,0 +1,10 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from keystoneclient import probe + +probe.main()