Article
ENVIRONMENT:
Open Enterprise Server SP1
ZENworks Desktop Management 7 SP1
Novell Cluster Services
PROBLEM: By default ZENworks Desktop Management 7 utilizes only one cluster node at a time with all configured services running on it (no load balancing at all).
Here's how to load-balance ZENworks Desktop Management 7 components across an NCS on Linux cluster with multiple nodes in such a way that services such as PXE, Imaging, etc., may be moved from one node to another independently, taking advantage of the processing power of multiple cluster nodes.
SOLUTION: Look at the modified script in the Example, modified sections have the *CLUSTER* in the comment.
We left out the Middle Tier services because we don't use them.
After that modification you can create different cluster resources for each ZENworks service and start and stop them using the following syntax :
Usage: ZDMstart <cmd> <service>
where <cmd> is one of:
- start = start specified service
- stop = stop specified service
- status = show status of the specified service
- help = display this message
and <service> is one of:
- awsi = ZENworks Auto Workstation Import/Removal Service
- img = ZENworks Imaging Service
- pxe = ZENworks PXE Services
- rm = ZENworks Remote Management Service
- inv = ZENworks Inventory Service
EXAMPLE:
#!/bin/bash
# Copyright (c) 2005 Novell, Inc. All rights reserved.
unset IFS
PATH=/bin:/usr/bin
PROG=${0##*/}
GETTEXT=/usr/bin/gettext
[ -x $GETTEXT ] || GETTEXT=echo
#-----------------------------------------------------------------------------
# *CLUSTER* Modified to show how to control single ZENworks services
# Display usage message
#
USAGE()
{
if [[ $ACTION != *help ]] ;then
UNKNOWN=$($GETTEXT "unknown action: '%s'")
printf "$UNKNOWN\n" $ACTION
fi
USAGE=$($GETTEXT 'Usage: %s <cmd> <service>')
WHERE=$($GETTEXT 'where <cmd> is one of:')
STRT_MSG=$($GETTEXT 'start specified service')
STOP_MSG=$($GETTEXT 'stop specified service')
STAT_MSG=$($GETTEXT 'show status of the specified service')
HELP_MSG=$($GETTEXT 'display this message')
printf "\n$USAGE\n" $PROG
printf " $WHERE\n"
printf " start = $STRT_MSG\n"
printf " stop = $STOP_MSG\n"
printf " status = $STAT_MSG\n"
printf " help = $HELP_MSG\n"
printf "\n"
WHERE=$($GETTEXT 'and <service> is one of:')
AWSI_MSG=$($GETTEXT 'ZENworks Auto Workstation Import/Removal Service')
PXE_MSG=$($GETTEXT 'ZENworks PXE Services')
RM_MSG=$($GETTEXT 'ZENworks Remote Management Service')
IMG_MSG=$($GETTEXT 'ZENworks Imaging Service')
INV_MSG=$($GETTEXT 'ZENworks Inventory Service')
printf " $WHERE\n"
printf " awsi = $AWSI_MSG\n"
printf " img = $IMG_MSG\n"
printf " pxe = $PXE_MSG\n"
printf " rm = $RM_MSG\n"
printf " inv = $INV_MSG\n"
printf "\n"
exit $1
}
#-----------------------------------------------------------------------------
# Allow actions to be specified, or determined by program name...
#
ACTION=""
OPT_CLUSTER=""
OPT_COLD=""
OPT_SERVICE=""
while [ $# -gt 0 ] ;do
case $1 in
*cluster)
OPT_CLUSTER="true"
shift
;;
*cold)
OPT_COLD="true"
shift
;;
# *CLUSTER* Allow additional command line parameters specifing the service
*awsi)
ZDM_DAEMON_NAMES=( \
"$($GETTEXT 'ZENworks Auto Workstation Import/Removal')" \
)
ZDM_DAEMON_SCRIPTS=( \
"novell-zdm-awsi" \
)
shift
;;
# *CLUSTER* Allow additional command line parameters specifing the service
*pxe)
ZDM_DAEMON_NAMES=( \
"$($GETTEXT 'ZENworks PXE Services')" \
)
ZDM_DAEMON_SCRIPTS=( \
"novell-proxydhcp novell-tftp novell-zmgprebootpolicy" \
)
shift
;;
# *CLUSTER* Allow additional command line parameters specifing the service
*img)
ZDM_DAEMON_NAMES=( \
"$($GETTEXT 'ZENworks Imaging Service')" \
)
ZDM_DAEMON_SCRIPTS=( \
"novell-zmgserv" \
)
shift
;;
# *CLUSTER* Allow additional command line parameters specifing the service
*rm)
ZDM_DAEMON_NAMES=( \
"$($GETTEXT 'ZENworks Remote Management')" \
)
ZDM_DAEMON_SCRIPTS=( \
"novell-zdm-wol" \
)
shift
;;
# *CLUSTER* Allow additional command line parameters specifing the service
*inv)
ZDM_DAEMON_NAMES=( \
"$($GETTEXT 'ZENworks Inventory Service')" \
)
ZDM_DAEMON_SCRIPTS=( \
"novell-zdm-sybase novell-zfs novell-zdm-inv" \
)
shift
;;
*)
ACTION="$1"
shift
;;
esac
done
[ -z "$ACTION" ] && ACTION=$PROG
MYUID=$(id -u)
COLS=$((15 - ${COLUMNS-80}))
case $ACTION in
*restart)
FMT="$($GETTEXT 'Restarting component %s')"
FAILURE="$($GETTEXT 'Failed to restart %s')"
CMD=restart
;;
*stop)
FMT="$($GETTEXT 'Shutting down component %s')"
FAILURE="$($GETTEXT 'Failed to stop %s')"
CMD=stop
;;
*start)
FMT="$($GETTEXT 'Starting %s')"
FAILURE="$($GETTEXT 'Failed to start %s')"
CMD=start
;;
*status)
MYUID=0
CMD=status
;;
*help)
USAGE 0
;;
*)
USAGE 1
;;
esac
#-----------------------------------------------------------------------------
# Messages
#
FAILED=$($GETTEXT 'failed')
DONE=$($GETTEXT 'done')
NOT_INSTALLED=$($GETTEXT 'Component %s is not Installed')
RUNNING=$($GETTEXT 'Component %s is Running')
STOPPED=$($GETTEXT 'Component %s is Stopped')
ALREADY_RUNNING=$($GETTEXT 'Component %s is already Running')
ALREADY_STOPPED=$($GETTEXT 'Component %s is already Stopped')
ROOT_REQUIRED=$($GETTEXT 'You must be root to execute %s')
[ $MYUID -ne 0 ] && printf "$ROOT_REQUIRED\n" $PROG && exit 1
#-----------------------------------------------------------------------------
# *CLUSTER* ZDM_DAEMON_NAMES and ZDM_DAEMON_SCRIPTS are commented out because
# they are already defined above.
# Service / Component configuration...
#
#
#ZDM_DAEMON_NAMES=( \
# "$($GETTEXT 'ZENworks Auto Workstation Import/Removal')" \
# "$($GETTEXT 'ZENworks PXE Services')" \
# "$($GETTEXT 'ZENworks Imaging Service')" \
# "$($GETTEXT 'ZENworks Remote Mangement')" \
# "$($GETTEXT 'ZENworks Middle Tier Server')" \
# "$($GETTEXT 'ZENworks Inventory Service')" \
#)
#ZDM_DAEMON_SCRIPTS=( \
# "novell-zdm-awsi" \
# "novell-proxydhcp novell-tftp novell-zmgprebootpolicy" \
# "novell-zmgserv" \
# "novell-zdm-wol" \
# "+_novell-tomcat4 +apache2 novell-xregd novell-xsrvd" \
# "+novell-zdm-sybase novell-zfs novell-zdm-inv"
#)
#if [ -n "$OPT_CLUSTER" ] ;then
#ZDM_DAEMON_SCRIPTS=( \
# "novell-zdm-awsi" \
# "novell-proxydhcp novell-tftp novell-zmgprebootpolicy" \
# "novell-zmgserv" \
# "novell-zdm-wol" \
# "+_novell-tomcat4 +apache2 novell-xregd novell-xsrvd" \
# "novell-zdm-sybase novell-zfs novell-zdm-inv"
#)
#fi
#-----------------------------------------------------------------------------
# Main
#
MAIN()
{
I=0
while [ -n "${ZDM_DAEMON_NAMES[$I]}" ]
do
echo ${ZDM_DAEMON_NAMES[$I]}
echo ${ZDM_DAEMON_SCRIPTS[$I]}
SCRIPTS=( ${ZDM_DAEMON_SCRIPTS[$I]} )
#
# Setup indeces for loop-- start in order, stop in reverse order...
#
MAX=0
for SCRIPT in ${SCRIPTS[@]}
do
MAX=$(($MAX + 1))
done
if [ $CMD == stop ] ;then
BEG=$(($MAX - 1))
END=-1
INC=-1
else
BEG=0
END=$MAX
INC=1
fi
#
# Process each script for this service...
#
J=$BEG
while [ $J -ne $END ]
do
SCRIPT=${SCRIPTS[$J]}
J=$(($J + $INC))
#
# SCRIPTS beginning w/ '+' should be started,
# but never stopped... unless OPT_COLD specified...
#
if [[ $SCRIPT == \+* ]] ;then
[ $CMD == start -o $CMD == status -o -n "$OPT_COLD" ] || continue
SCRIPT=${SCRIPT#\+}
fi
#
# Is this component even installed??
#
INSTALL_STATUS=""
case $SCRIPT in
_*)
INSTALL_STATUS=$($SCRIPT IS_INSTALLED ; echo $?)
;;
*/*)
;;
*)
SCRIPT="/etc/init.d/$SCRIPT"
;;
esac
[ -z "$INSTALL_STATUS" ] && INSTALL_STATUS=$([ -x $SCRIPT ] ; echo $?)
if [ "$INSTALL_STATUS" -ne 0 ] ;then
printf "\t$NOT_INSTALLED\n" ${SCRIPT##*/}
continue
fi
#
# Is this component running?
#
$SCRIPT status >&/dev/null; STATUS=$?
if [ $CMD == status ] ;then
if [ $STATUS -eq 0 ] ;then
printf "\t$RUNNING\n" ${SCRIPT##*/}
else
printf "\t$STOPPED\n" ${SCRIPT##*/}
fi
continue
fi
[ $STATUS -eq 0 -a $CMD == start ] &&
printf "\t$ALREADY_RUNNING\n" ${SCRIPT##*/} &&
continue
[ $STATUS -ne 0 -a $CMD == stop ] &&
printf "\t$ALREADY_STOPPED\n" ${SCRIPT##*/} &&
continue
#
# Execute command
#
LABEL=$(printf "$FMT" ${SCRIPT##*/})
printf "\t%${COLS}s" "$LABEL"
$SCRIPT $CMD >&/dev/null
if [ $? -ne 0 ] ;then
printf "$FAILED\n"
printf "** $FAILURE **\n" "${ZDM_DAEMON_NAMES[$I]}"
break
fi
printf "$DONE\n"
done
I=$(($I + 1))
done
}
#-----------------------------------------------------------------------------
# _novell-zimgserv pseudo script for imaging services... (loads in eDir...)
#
_novell-zimgserv()
{
NDSTRACE=/usr/bin/ndstrace
[ -x ${NDSTRACE} ] || NDSTRACE=/opt/novell/eDirectory/bin/ndstrace
[ -x ${NDSTRACE} ] || NDSTRACE=ndstrace
case $1 in
IS_INSTALLED)
([ -x /etc/init.d/ndsd ] &&
${NDSTRACE} -c modules | grep -qi zimgserv) >&/dev/null
;;
stop)
(${NDSTRACE} -c modules | grep -qi zimgserv.*not.loaded ||
${NDSTRACE} -c "unload zimgserv") >&/dev/null
;;
start)
(/etc/init.d/ndsd status || /etc/init.d/ndsd start) >&/dev/null
if [ $? -eq 0 ] ;then
(${NDSTRACE} -c modules | grep -qi zimgserv.*running ||
${NDSTRACE} -c "load zimgserv") >&/dev/null
else
false
fi
;;
restart)
_novell-zimgserv stop && _novell-zimgserv start
;;
status)
(/etc/init.d/ndsd status >&/dev/null &&
${NDSTRACE} -c modules | grep -qi zimgserv.*running) >&/dev/null
;;
esac
}
#-----------------------------------------------------------------------------
# _novell-tomcat4 pseudo script for midtier services... (no status in orig...)
#
_novell-tomcat4()
{
case $1 in
IS_INSTALLED)
[ -x /etc/init.d/novell-tomcat4 ]
;;
status)
#
# this is a modified detection algorithm
# originally taken from /etc/init.d/novell-tomcat4
#
if [ -f /var/run/novell-tomcat4.pid ] ;then
CAT_PID=$(cat /var/run/novell-tomcat4.pid)
[ -f /proc/$CAT_PID/cmdline ] &&
grep -ic catalina /proc/$CAT_PID/cmdline && return
fi
false
;;
*)
/etc/init.d/novell-tomcat4 $1
;;
esac
}
MAIN
If you have any questions you may contact Giovanni at Giovanni.Coa@edp4you.it
Disclaimer: As with everything else at Cool Solutions, this content is definitely not supported by Novell (so don't even think of calling Support if you try something and it blows up).
It was contributed by a community member and is published "as is." It seems to have worked for at least one person, and might work for you. But please be sure to test, test, test before you do anything drastic with it.
Related Articles
User Comments
- Be the first to comment! To leave a comment you need to Login or Register
- 3445 reads


0