diff --git a/SOURCES/bz1493915-1-support-per-host-per-bundle-attribs.patch b/SOURCES/bz1493915-1-support-per-host-per-bundle-attribs.patch new file mode 100644 index 0000000..aef9b6d --- /dev/null +++ b/SOURCES/bz1493915-1-support-per-host-per-bundle-attribs.patch @@ -0,0 +1,94 @@ +From 708e11c13ac25e1db5a4552db699a652f4e32353 Mon Sep 17 00:00:00 2001 +From: Michele Baldessari +Date: Thu, 7 Sep 2017 18:56:24 +0200 +Subject: [PATCH 1/2] Introduce helper functions for container-attribute-target + +In this change we introduce the ocf_attribute_target() function that helps +RAs decide where to store per-node attributes. The rationale is that +when an OCF resource runs in a bundle (e.g. rabbitmq-bundle-0) the +NODENAME will point to the bundle name and not to the physical node +running the bundle. Since a bundle can run on any cluster node, this +is not ideal in the situations in which an RA wants to remember on which +*host* a bundle was running (this is typically the case when there is no +shared storage) + +The way this new ocf_attribute_target() function works is the following: +A) When the meta-attr 'container-attribute-target' == 'host' and the + function is called without arguments it will return the physical + hostname the resource is running on. +B) When the meta-attr 'container-attribute-target' != 'host' and the + function is called without arguments it will return the NODENAME + (default) +C) When the meta-attr 'container-attribute-target' == 'host' and the + function is called with an argument it will return the physical + hostname on which the corresponding argument is running on. +D) When the meta-attr 'container-attribute-target' != 'host' and the + function is called with an argument it will return the NODENAME + (default) + +The basic idea is that if resources need to store per-host attributes +you will set the meta attribute 'container-attribute-target' equal to +host (the no-shared storage case). If resources need to store attributes +on a per-bundle basis (because they access data from shared-storage) +then no change is needed on meta attributes (this is the default +behaviour). + +Signed-off-by: Andrew Beekhof +Tested-by: Michele Baldessari +Tested-by: Damien Ciabrini +--- + heartbeat/ocf-shellfuncs.in | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in +index 9b6b99f88a56..ddd6854e9487 100644 +--- a/heartbeat/ocf-shellfuncs.in ++++ b/heartbeat/ocf-shellfuncs.in +@@ -989,6 +989,44 @@ ocf_stop_trace() { + set +x + } + ++# Helper functions to map from nodename/bundle-name and physical hostname ++# list_index_for_word "node0 node1 node2 node3 node4 node5" node4 --> 5 ++# list_word_at_index "NA host1 host2 host3 host4 host5" 3 --> host2 ++ ++# list_index_for_word "node1 node2 node3 node4 node5" node7 --> "" ++# list_word_at_index "host1 host2 host3 host4 host5" 8 --> "" ++ ++# attribute_target node1 --> host1 ++list_index_for_word() { ++ echo $1 | tr ' ' '\n' | awk -v x="$2" '$0~x {print NR}' ++} ++ ++list_word_at_index() { ++ echo $1 | tr ' ' '\n' | awk -v n="$2" 'n == NR' ++} ++ ++ocf_attribute_target() { ++ if [ x$1 = x ]; then ++ if [ x$OCF_RESKEY_CRM_meta_container_attribute_target = xhost -a x$OCF_RESKEY_CRM_meta_physical_host != x ]; then ++ echo $OCF_RESKEY_CRM_meta_physical_host ++ else ++ echo $OCF_RESKEY_CRM_meta_on_node ++ fi ++ return ++ elif [ x"$OCF_RESKEY_CRM_meta_notify_all_uname" != x ]; then ++ index=$(list_index_for_word "$OCF_RESKEY_CRM_meta_notify_all_uname" $1) ++ mapping="" ++ if [ x$index != x ]; then ++ mapping=$(list_word_at_index "$OCF_RESKEY_CRM_meta_notify_all_hosts" $index) ++ fi ++ if [ x$mapping != x -a x$mapping != xNA ]; then ++ echo $mapping ++ return ++ fi ++ fi ++ echo $1 ++} ++ + __ocf_set_defaults "$@" + + : ${OCF_TRACE_RA:=$OCF_RESKEY_trace_ra} +-- +2.13.5 + diff --git a/SOURCES/bz1493915-2-support-per-host-per-bundle-attribs.patch b/SOURCES/bz1493915-2-support-per-host-per-bundle-attribs.patch new file mode 100644 index 0000000..fa16395 --- /dev/null +++ b/SOURCES/bz1493915-2-support-per-host-per-bundle-attribs.patch @@ -0,0 +1,146 @@ +From 9bd94137d77f770967d35db5de716590cfaf0435 Mon Sep 17 00:00:00 2001 +From: Michele Baldessari +Date: Thu, 7 Sep 2017 21:07:45 +0200 +Subject: [PATCH 2/2] Make use of ocf_attribute_target in rabbitmq/redis/galera + +Instead of using NODENAME directly use the newly-introduced +ocf_attribute_target function. This allows the operator to decide if an RA +running inside a bundle should use per-host properties or per-bundle +properties in a resource. This can be done by setting the meta-attribute +'container-attribute-target' to 'host' in the former case and leave the +defaults as is in the latter case. + +This change has been tested in the following scenarios (for rabbit/redis +and galera): +1) A deployment without bundles and without the container-attribute-target meta attr set. +2) A deployment with the resources running in bundles without the meta-attr set +3) A deployment with the resources running in bundles with the meta-attr set to 'host' + +Additionally we successfully tested restarting of each resource, banning +of each resource from a node and rebooting a cluster node hosting the +resource. + +Signed-off-by: Andrew Beekhof +Signed-off-by: Michele Baldessari +Signed-off-by: Damien Ciabrini +--- + heartbeat/galera | 16 +++++++++------- + heartbeat/rabbitmq-cluster | 4 ++-- + heartbeat/redis | 5 +++-- + 3 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/heartbeat/galera b/heartbeat/galera +index dc681a47079a..ab121a4be5a4 100755 +--- a/heartbeat/galera ++++ b/heartbeat/galera +@@ -68,6 +68,8 @@ + . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + . ${OCF_FUNCTIONS_DIR}/mysql-common.sh + ++NODENAME=$(ocf_attribute_target) ++ + # It is common for some galera instances to store + # check user that can be used to query status + # in this file +@@ -279,7 +281,7 @@ get_status_variable() + + set_bootstrap_node() + { +- local node=$1 ++ local node=$(ocf_attribute_target $1) + + ${HA_SBIN_DIR}/crm_attribute -N $node -l reboot --name "${INSTANCE_ATTR_NAME}-bootstrap" -v "true" + } +@@ -307,7 +309,7 @@ clear_no_grastate() + + is_no_grastate() + { +- local node=$1 ++ local node=$(ocf_attribute_target $1) + ${HA_SBIN_DIR}/crm_attribute -N $node -l reboot --name "${INSTANCE_ATTR_NAME}-no-grastate" -Q 2>/dev/null + } + +@@ -323,7 +325,7 @@ set_last_commit() + + get_last_commit() + { +- local node=$1 ++ local node=$(ocf_attribute_target $1) + + if [ -z "$node" ]; then + ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-last-committed" -Q 2>/dev/null +@@ -413,7 +415,7 @@ master_exists() + + clear_master_score() + { +- local node=$1 ++ local node=$(ocf_attribute_target $1) + if [ -z "$node" ]; then + $CRM_MASTER -D + else +@@ -423,7 +425,7 @@ clear_master_score() + + set_master_score() + { +- local node=$1 ++ local node=$(ocf_attribute_target $1) + + if [ -z "$node" ]; then + $CRM_MASTER -v 100 +@@ -542,7 +544,7 @@ detect_first_master() + + greater_than_equal_long "$last_commit" "$best_commit" + if [ $? -eq 0 ]; then +- best_node=$node ++ best_node=$(ocf_attribute_target $node) + best_commit=$last_commit + fi + +diff --git a/heartbeat/rabbitmq-cluster b/heartbeat/rabbitmq-cluster +index 1e78d9ecab98..362556d3f644 100755 +--- a/heartbeat/rabbitmq-cluster ++++ b/heartbeat/rabbitmq-cluster +@@ -37,7 +37,7 @@ RMQ_DATA_DIR="/var/lib/rabbitmq/mnesia" + RMQ_PID_DIR="/var/run/rabbitmq" + RMQ_PID_FILE="/var/run/rabbitmq/rmq.pid" + RMQ_LOG_DIR="/var/log/rabbitmq" +-NODENAME=$(ocf_local_nodename) ++NODENAME=$(ocf_attribute_target) + + # this attr represents the current active local rmq node name. + # when rmq stops or the node is fenced, this attr disappears +@@ -340,7 +340,7 @@ rmq_notify() { + + # forget each stopped rmq instance in the provided pcmk node in the list. + for node in $(echo "$node_list"); do +- local rmq_node="$(${HA_SBIN_DIR}/crm_attribute -N $node -l forever --query --name $RMQ_CRM_ATTR_COOKIE_LAST_KNOWN -q)" ++ local rmq_node="$(${HA_SBIN_DIR}/crm_attribute -N $(ocf_attribute_target $node) -l forever --query --name $RMQ_CRM_ATTR_COOKIE_LAST_KNOWN -q)" + if [ -z "$rmq_node" ]; then + ocf_log warn "Unable to map pcmk node $node to a known rmq node." + continue +diff --git a/heartbeat/redis b/heartbeat/redis +index 708ce84e6184..bc97f14096a6 100755 +--- a/heartbeat/redis ++++ b/heartbeat/redis +@@ -188,7 +188,8 @@ function last_known_master() + } + + function crm_master_reboot() { +- "${HA_SBIN_DIR}/crm_master" -l reboot "$@" ++ local node=$(ocf_attribute_target) ++ "${HA_SBIN_DIR}/crm_master" -N $node -l reboot "$@" + } + + function calculate_score() +@@ -545,7 +546,7 @@ function validate() { + fi + } + +-NODENAME=$(ocf_local_nodename) ++NODENAME=$(ocf_attribute_target) + if [ -f "$REDIS_CONFIG" ]; then + clientpasswd="$(cat $REDIS_CONFIG | sed -n -e 's/^\s*requirepass\s*\(.*\)\s*$/\1/p' | tail -n 1)" + fi +-- +2.13.5 + diff --git a/SOURCES/bz1497076-NovaEvacuate-Instance-HA-OSP12.patch b/SOURCES/bz1497076-NovaEvacuate-Instance-HA-OSP12.patch new file mode 100644 index 0000000..7d0c08a --- /dev/null +++ b/SOURCES/bz1497076-NovaEvacuate-Instance-HA-OSP12.patch @@ -0,0 +1,183 @@ +diff -uNr a/heartbeat/NovaEvacuate b/heartbeat/NovaEvacuate +--- a/heartbeat/NovaEvacuate 2017-09-27 11:59:28.430326918 +0200 ++++ b/heartbeat/NovaEvacuate 2017-09-27 12:04:21.599608299 +0200 +@@ -77,6 +77,24 @@ + + + ++ ++ ++Region name for connecting to nova. ++ ++Region name ++ ++ ++ ++ ++ ++Explicitly allow client to perform "insecure" TLS (https) requests. ++The server's certificate will not be verified against any certificate authorities. ++This option should be used with caution. ++ ++Allow insecure TLS requests ++ ++ ++ + + + Disable shared storage recovery for instances. Use at your own risk! +@@ -85,6 +103,14 @@ + + + ++ ++ ++Enable extra logging from the evacuation process ++ ++Enable debug logging ++ ++ ++ + + + +@@ -143,16 +169,20 @@ + need_evacuate=0 + + case $state in +- "") ;; +- no) ocf_log debug "$node is either fine or already handled";; +- yes) need_evacuate=1;; ++ "") ++ ;; ++ no) ++ ocf_log debug "$node is either fine or already handled" ++ ;; ++ yes) need_evacuate=1 ++ ;; + *@*) + where=$(echo $state | awk -F@ '{print $1}') + when=$(echo $state | awk -F@ '{print $2}') + now=$(date +%s) + + if [ $(($now - $when)) -gt 60 ]; then +- ocf_log info "Processing partial evacuation of $node by $where at $when" ++ ocf_log info "Processing partial evacuation of $node by $where at $when" + need_evacuate=1 + else + # Give some time for any in-flight evacuations to either complete or fail +@@ -163,9 +193,15 @@ + esac + + if [ $need_evacuate = 1 ]; then +- ocf_log notice "Initiating evacuation of $node" ++ fence_agent="fence_compute" ++ ++ if have_binary fence_evacuate ++ then ++ fence_agent="fence_evacuate" ++ fi + +- fence_compute ${fence_options} -o status -n ${node} ++ ocf_log notice "Initiating evacuation of $node with $fence_agent" ++ $fence_agent ${fence_options} -o status -n ${node} + if [ $? = 1 ]; then + ocf_log info "Nova does not know about ${node}" + # Dont mark as no because perhaps nova is unavailable right now +@@ -177,7 +213,7 @@ + return $OCF_SUCCESS + fi + +- fence_compute ${fence_options} -o off -n $node ++ $fence_agent ${fence_options} -o off -n $node + rc=$? + + if [ $rc = 0 ]; then +@@ -211,7 +247,10 @@ + rc=$OCF_SUCCESS + fence_options="" + +- check_binary fence_compute ++ ++ if ! have_binary fence_evacuate; then ++ check_binary fence_compute ++ fi + + # Is the state directory writable? + state_dir=$(dirname $statefile) +@@ -250,12 +289,29 @@ + + fence_options="${fence_options} -t ${OCF_RESKEY_tenant_name}" + ++ if [ -n "${OCF_RESKEY_region_name}" ]; then ++ fence_options="${fence_options} \ ++ --region-name ${OCF_RESKEY_region_name}" ++ fi ++ ++ if [ -n "${OCF_RESKEY_insecure}" ]; then ++ if ocf_is_true "${OCF_RESKEY_insecure}"; then ++ fence_options="${fence_options} --insecure" ++ fi ++ fi ++ + if [ -n "${OCF_RESKEY_no_shared_storage}" ]; then + if ocf_is_true "${OCF_RESKEY_no_shared_storage}"; then + fence_options="${fence_options} --no-shared-storage" + fi + fi + ++ if [ -n "${OCF_RESKEY_verbose}" ]; then ++ if ocf_is_true "${OCF_RESKEY_verbose}"; then ++ fence_options="${fence_options} --verbose" ++ fi ++ fi ++ + if [ -n "${OCF_RESKEY_endpoint_type}" ]; then + case ${OCF_RESKEY_endpoint_type} in + adminURL|publicURL|internalURL) ;; +@@ -276,19 +332,32 @@ + statefile="${HA_RSCTMP}/${OCF_RESOURCE_INSTANCE}.active" + + case $__OCF_ACTION in +-start) evacuate_validate; evacuate_start;; +-stop) evacuate_stop;; +-monitor) evacuate_validate; evacuate_monitor;; +-meta-data) meta_data +- exit $OCF_SUCCESS +- ;; +-usage|help) evacuate_usage +- exit $OCF_SUCCESS +- ;; +-validate-all) exit $OCF_SUCCESS;; +-*) evacuate_usage +- exit $OCF_ERR_UNIMPLEMENTED +- ;; ++ start) ++ evacuate_validate ++ evacuate_start ++ ;; ++ stop) ++ evacuate_stop ++ ;; ++ monitor) ++ evacuate_validate ++ evacuate_monitor ++ ;; ++ meta-data) ++ meta_data ++ exit $OCF_SUCCESS ++ ;; ++ usage|help) ++ evacuate_usage ++ exit $OCF_SUCCESS ++ ;; ++ validate-all) ++ exit $OCF_SUCCESS ++ ;; ++ *) ++ evacuate_usage ++ exit $OCF_ERR_UNIMPLEMENTED ++ ;; + esac + rc=$? + ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" diff --git a/SPECS/resource-agents.spec b/SPECS/resource-agents.spec index db6b69c..e7b499a 100644 --- a/SPECS/resource-agents.spec +++ b/SPECS/resource-agents.spec @@ -48,7 +48,7 @@ Name: resource-agents Summary: Open Source HA Reusable Cluster Resource Scripts Version: 3.9.5 -Release: 105%{?dist} +Release: 105%{?dist}.2 License: GPLv2+, LGPLv2+ and ASL 2.0 URL: https://github.com/ClusterLabs/resource-agents %if 0%{?fedora} || 0%{?centos_version} || 0%{?rhel} @@ -235,6 +235,9 @@ Patch174: bz1451933-LVM-warn-when-cache-mode-not-writethrough.patch Patch175: bz1449681-2-saphana-saphanatopology-update-0.152.21.patch Patch176: bz1342376-2-rabbitmq-cluster-backup-and-restore-users-policies.patch Patch177: bz1342376-3-rabbitmq-cluster-backup-and-restore-users-policies.patch +Patch178: bz1493915-1-support-per-host-per-bundle-attribs.patch +Patch179: bz1493915-2-support-per-host-per-bundle-attribs.patch +Patch180: bz1497076-NovaEvacuate-Instance-HA-OSP12.patch Obsoletes: heartbeat-resources <= %{version} Provides: heartbeat-resources = %{version} @@ -527,6 +530,9 @@ exit 1 %patch175 -p1 %patch176 -p1 %patch177 -p1 +%patch178 -p1 +%patch179 -p1 -F2 +%patch180 -p1 %build if [ ! -f configure ]; then @@ -790,6 +796,16 @@ ccs_update_schema > /dev/null 2>&1 ||: %endif %changelog +* Fri Sep 29 2017 Oyvind Albrigtsen - 3.9.5-105.2 +- NovaEvacuate: changes to support Instance HA on OSP12 + + Resolves: rhbz#1497076 + +* Thu Sep 21 2017 Oyvind Albrigtsen - 3.9.5-105.1 +- support per-host and per-bundle attributes + + Resolves: rhbz#1493915 + * Fri Jun 23 2017 Oyvind Albrigtsen - 3.9.5-105 - rabbitmq-cluster: fix to keep expiration policy