[Pacemaker] how to determin crm version / features from within a RA
Lars Ellenberg
lars.ellenberg at linbit.com
Thu Jun 11 13:57:44 UTC 2009
attaching revised generic shell level version compare scriptlet
plus cib/crm detection logic.
hopefully it is more less instransparent what is going on now,
and clear why the eval for the cibadmin -Ql | sed thingy is ok.
the shell version compare may be useful for inclusion into the
"ocf" shell function library -- if it turns out to even work on
non-linux shell, sed and sort ;)
whatever it is good for.
--
: Lars Ellenberg
: LINBIT | Your Way to High Availability
: DRBD/HA support and consulting http://www.linbit.com
DRBD® and LINBIT® are registered trademarks of LINBIT, Austria.
-------------- next part --------------
#!/bin/sh
# two parameters
# version1 version2
# return value:
# 0: version1 = version2 by string compare
# 1: version1 < version2 by "version compare"
# 2: version1 > version2 by "version compare"
# 3: something in that funny little tr + sed + sort construct went wrong
version_cmp()
{
# make both version parameters start non-numeric
local v1="$1" v2="$2" result l sed_script sort_keys
# short cut
if [ "x$v1" = "x$v2" ]; then
return 0
fi
# strip leading and trailing spaces.
# all embeded spaces to underscores.
# versions should not contain spaces!
# insert spaces separators around numeric values
sed_script="s/^ *//; s/ *$//;s/ /_/g; s/[0-9]\+/ & /g"
# tr to strip newlines in arguments, even though you should not call
# this function with embeded newlines in arguments!
v1=$(echo "$v1" | tr '\n' ' ' | sed -e "$sed_script")
v2=$(echo "$v2" | tr '\n' ' ' | sed -e "$sed_script")
set -- $v1 x
l=$#
set -- $v2 x
if [ $l -lt $# ] ; then l=$#; fi
# $v1 and $v2 contain space separated alternating non-numeric and
# numeric parts, starting with a non-numeric one, which possibly
# is empty; therefore the extra 'x' on the set -- lines above.
# $l now contains the maximum "column" number.
# generate that many sort key arguments:
# -k1,1 -k2,2n -k3,3 -k4,4n -k5,5 ...
sort_keys=$(seq $l | sed -e 's/.*/ -k&,&/;2~2 s/$/n/')
# capture which value sort places in the first line.
# the -s is "stabilize", and should actually not be neccessary
result=$( ( echo "$v1" ; echo "$v2" ) |
LANG=C LC_ALL=C sort -t " " -s $sort_keys |
head -n1)
case "$result" in
"$v1")
return 1;; # v1 < v2
"$v2")
return 2;; # v2 < v1
*)
return 3;; # oops, what happened here?
esac
}
# for those that rather have a boolean result
# three parameters
# compare_version $v1 $op $v2
# where op is one of lt|le|eq|ge|gt
# return value:
# 0: requested relation evaluates to true
# 1: requested relation evaluates to false
# anything else: problem evaluating expression
compare_versions()
{
local v1="$1" op="$2" v2="$3" rc
case "$op" in
lt|le|eq|ge|gt)
:;;
*)
echo >&2 "bad relation '$op'"
return 2
;;
esac
version_cmp "$v1" "$v2"
rc=$?
case $rc in
0)
case "$op" in
eq|[lg]e)
return 0;;
*)
return 1;;
esac;;
1)
case "$op" in
l[te])
return 0;;
*)
return 1;;
esac ;;
2)
case "$op" in
g[te])
return 0;;
*)
return 1;;
esac ;;
*)
return $rc ;;
esac
}
#### excercise it:
# version_cmp "$1" "$2"
# case $? in
# 0) echo "'$1' = '$2'" ;;
# 1) echo "'$1' < '$2'" ;;
# 2) echo "'$1' > '$2'" ;;
# *) echo "something went wrong: '$1' =?= '$2'" ;;
# esac
################# version compare ends
# now use it.
# does not yet evaluate _CIB_VALIDATE_WITH, but we could trigger on it.
#
_DC_VERSION=""
_CIB_VALIDATE_WITH=""
eval $(cibadmin -Ql |
sed -n -e '/^<cib/ {
# capture the value of the validate-with attribute of the cib tag.
s/^.*\bvalidate-with="\([^"]*\)".*$/\1/;
# shell-escape it
s/[^-%+.\/0-9:=@A-Z_a-z]/\\&/g;
# prepend the variable name, and print
s/^/_CIB_VALIDATE_WITH=/;p;}' \
-e '
# delete everything but the cluster_property_set
# to avoid possible uninteressting nvpairs with name="dc-version"
1,/<cluster_property_set\b/d;
/<\/cluster_property_set>/q;' \
-e '
# find the right nvpair,
# capture the first part of its value into a variable assignment
# no need to quote [0-9.:]
/^[[:space:]]*<nvpair .*\bname="dc-version"/ s/^.*\bvalue="\([0-9.:]*\).*$/_DC_VERSION=\1/p'
)
# add some "epoch" prefix (only if not present already)
case $_DC_VERSION in
"")
echo >&2 "problem reading cib :("
exit 1;;
2.*) _DC_VERSION=0:$_DC_VERSION;;
1.*) _DC_VERSION=1:$_DC_VERSION;;
esac
required_crm_version=0:2.1.3
if compare_versions $_DC_VERSION lt $required_crm_version ; then
echo "sorry, I need a $required_crm_version crm"
exit 1
else
echo "fine, $_DC_VERSION is newer than required $required_crm_version crm version"
fi
More information about the Pacemaker
mailing list