Last active
September 12, 2017 15:20
-
-
Save mbaldessari/74d696df9b9b5f697e3cab127a6dc24f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# by Damien Ciabrini & Michele Baldessari | |
# This function takes the resource name as a parameter and returns | |
# "clone", "master", "primitive" or exits with 1 | |
function get_resource_type() { | |
local clone_count | |
local master_count | |
local primitive_count | |
local bundle_count | |
local resource_name | |
resource_name=$1 | |
clone_count=$(crm_mon -r --as-xml | xmllint --xpath "count(//resources/clone[@multi_state='false']/resource[@id='$resource_name']/@id)" -) | |
master_count=$(crm_mon -r --as-xml | xmllint --xpath "count(//resources/clone[@multi_state='true']/resource[@id='$resource_name']/@id)" -) | |
primitive_count=$(crm_mon -r --as-xml | xmllint --xpath "count(//resources/resource[@id='$resource_name']/@id)" -) | |
bundle_count=$(crm_mon -r --as-xml | xmllint --xpath "count(//resources/bundle[@id='$resource_name']/@id)" -) | |
if [ $clone_count -gt 0 ]; then | |
echo "clone"; | |
elif [ $master_count -gt 0 ]; then | |
echo "master"; | |
elif [ $primitive_count -gt 0 ]; then | |
echo "primitive"; | |
elif [ $bundle_count -gt 0 ]; then | |
echo "bundle" | |
else | |
echo "unrecognized resource type for $resource (c:$clone_count m:$master_count p:$primitive_count)" | |
exit 1 | |
fi | |
} | |
# This function takes a resource name (the resource must be of master | |
# type) and returns the master-max attribute if present or 1 if the | |
# attribute is not present. It exists 1 in case of errors. | |
function get_master_max() { | |
local resource_name | |
local ret | |
local status | |
resource_name=$1 | |
ret=$(crm_resource -r $resource_name --meta -g master-max 2>/dev/null) | |
status=$? | |
if [ $status -eq 0 ]; then | |
echo $ret | |
elif [ $status -eq 6 ]; then | |
echo 1 | |
else | |
echo "Error fetching master max for $resource" | |
exit 1 | |
fi | |
} | |
# This function takes a resource name which should be of type "clone" | |
# and returns the clone-max attribute if present. If clone-max is not | |
# present it returns the number of nodes which have the property | |
# "$resourcename-role" set to true (composable ha). If that number is | |
# 0 (pre-composable ha), we count the number of nodes in the cluster | |
# We return -1 in case of errors | |
function get_clone_count() { | |
local count | |
local resource_name | |
local ret | |
local rolename | |
local status | |
resource_name=$1 | |
rolename="${resource_name}-role" | |
ret=$(crm_resource -r $resource_name --meta -g clone-max 2>/dev/null) | |
status=$? | |
if [ $status -eq 0 ]; then | |
echo $ret | |
elif [ $status -eq 6 ]; then | |
# if there are no $rolename properties it means we are in pre-composable HA and we need | |
# to use the number of corosync nodes | |
count=$(pcs property | grep -c "$rolename=true") | |
if [ $count = "0" ]; then | |
# FIXME what happens if pacemaker remote is configured | |
count=$(crm_node -l | wc -l) | |
echo $count | |
else | |
echo $count | |
fi | |
else | |
echo -1 | |
fi | |
} | |
function get_bundle_replicas() { | |
cibadmin --query --xpath "//resources/bundle[@id='$1']/docker" | xmllint --xpath "string(/docker/@replicas)" - | |
} | |
function get_bundle_masters() { | |
cibadmin --query --xpath "//resources/bundle[@id='$1']/docker" | xmllint --xpath "string(/docker/@masters)" - | |
} | |
# Returns empty if the bundle has no primitive inside it (e.g. haproxy) | |
function get_bundle_primitive_name() { | |
cibadmin --query --xpath "//resources/bundle[@id='$1']" | xmllint --xpath "string(/bundle/primitive/@id)" - | |
} | |
function resource_active() { | |
echo "$1 is active" | |
exit 0 | |
} | |
function resource_not_active() { | |
echo "$1 is inactive" | |
exit 0 | |
} | |
# Takes the resource name as an argument and does the following: | |
# a) master/slave resources | |
# returns active only if the needed number of masters is set | |
# e.g. galera needs to be master on all nodes where galera is supposed | |
# to run (that is == to the number of controllers in pre-composable ha | |
# and the number of nodes with galera-role=true properties set | |
# in composable ha) | |
# redis will need to have master on only one node | |
# b) cloned resources | |
# returns active if the resource is started on the needed nodes | |
# e.g. same as master/slave resources the needed number of nodes is | |
# equal to the cluster nodes in pre-composable and to the haproxy-role | |
# property count in composable ha | |
# c) primitive resources | |
# returns active if the resource is started on one node | |
# e.g. A/P resources like cinder-volume, VIPs | |
function is_resource_active() { | |
local count | |
local master_max | |
local resource_name | |
local resource_type | |
local to_be_count | |
resource_name=$1 | |
resource_type=$(get_resource_type $resource) | |
if [ $resource_type = "master" ]; then | |
master_max=$(get_master_max $resource) | |
count=$(crm_mon -r --as-xml | xmllint --xpath "count(//resource[@id='$resource_name' and @orphaned='false' and @failed='false' and @active='true' and @role='Master'])" -) | |
if [ $count -eq $master_max ]; then | |
resource_active $resource_name | |
else | |
resource_not_active $resource_name | |
fi | |
elif [ $resource_type = "clone" ]; then | |
to_be_count=$(get_clone_count $resource) | |
count=$(crm_mon -r --as-xml | xmllint --xpath "count(//resource[@id='$resource_name' and @orphaned='false' and @failed='false' and @active='true' and @role='Started'])" -) | |
if [ $to_be_count -eq $count ]; then | |
resource_active $resource_name | |
else | |
resource_not_active $resource_name | |
fi | |
elif [ $resource_type = "primitive" ]; then | |
count=$(crm_mon -r --as-xml | xmllint --xpath "count(//resource[@id='$resource_name' and @orphaned='false' and @failed='false' and @active='true' and @role='Started'])" -) | |
if [ $count -eq 1 ]; then | |
resource_active $resource_name | |
else | |
resource_not_active $resource_name | |
fi | |
elif [ $resource_type = "bundle" ]; then | |
# we check that count of replicas is the active number of bundles of the bundle | |
# if replicas == counted active bundles | |
# fetch the primitive inside the bundle | |
#if $(contains_primitive $resource_name); then | |
primitive_name=$(get_bundle_primitive_name $resource_name) | |
if [ ! -z "$primitive_name" ]; then | |
expected_count=$(get_bundle_masters $resource_name) | |
if [ ! -z "$expected_count" ]; then | |
# master/slave | |
count=$(crm_mon -r --as-xml | xmllint --xpath "count(//resource[@id='$primitive_name' and @orphaned='false' and @failed='false' and @active='true' and @role='Master'])" -) | |
if [ $count -eq $expected_count ]; then | |
resource_active $resource_name | |
else | |
resource_not_active $resource_name | |
fi | |
else | |
# clone | |
expected_count=$(get_bundle_replicas $resource_name) | |
count=$(crm_mon -r --as-xml | xmllint --xpath "count(//resource[@id='$primitive_name' and @orphaned='false' and @failed='false' and @active='true' and @role='Started'])" -) | |
if [ $count -eq $expected_count ]; then | |
resource_active $resource_name | |
else | |
resource_not_active $resource_name | |
fi | |
fi | |
else | |
# no primitive | |
expected_count=$(get_bundle_replicas $resource_name) | |
count=$(crm_mon -r --as-xml | xmllint --xpath "count(//bundle[@id='$resource_name']/replica/resource[@orphaned='false' and @failed='false' and @active='true' and @role='Started'])" -) | |
if [ $count -eq $expected_count ]; then | |
resource_active $resource_name | |
else | |
resource_not_active $resource_name | |
fi | |
fi | |
fi | |
} | |
resource=$1 | |
is_resource_active $resource |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
looks sane to me
you skipped groups, but we don't use them in OSP