Sindbad~EG File Manager
#!/bin/sh
# -----------------------------------------------------------------------------
#
# DELL COMPUTER CORPORATION PROPRIETARY INFORMATION
#
# This software is supplied under the terms of a license agreement or
# nondisclosure agreement with Dell Computer Corporation and may not
# be copied or disclosed except in accordance with the terms of that
# agreement.
#
# Copyright (c) 2007 Dell Computer Corporation. All Rights Reserved.
#
# Script Name: vm6deploy.sh
#
# Purpose: sample script to illustrate OS/patch deployment via Virtual Media.
# NOTE: the boot image supplied to this script performs the deployment.
# [ie. the boot image determines what/how deployment is done]
# -----------------------------------------------------------------------------
SCRIPT=${0##*/} #This is similar to: SCRIPT=$(basename $0).
RC=0
PASS=0 # count successes/failures, report later.
FAIL=0
DBUG=0
VMDELAY=10 # expected max. Virtual Media connect time (seconds).
PID=$$
DATETIME=$(date +%Y%m%d.%H%M%S.%N)
LOGPATH=$(mktemp -d /tmp/.${SCRIPT%.sh}-XXXXXX) #Create a temporary folder and set its path in LOGPATH.
EXITING=0
NOKILL=0
CONN=0
CLEANUP="$LOGPATH/.$PID-CLEANUP" # to track things needing cleanup.
DEVICE=0x20
# This function print and log anything given as argument.
function printcon {
echo -e "$@"
[ -n "$CONLOG" ] && echo -e "$@" >>$CONLOG
}
# This function is used to print error messages. It will update the variable FAIL.
function error {
FAIL=$((FAIL + 1))
printcon "\aerror($FAIL): $@"
}
# This function is meant to be called before this script exit in order to print informations
# about the number of tasks that has succeeded or failed and other miscaleneous informations.
function print_results_and_exit {
NOKILL=1
EXITING=1
printcon "\n$PASS deployment tasks started successfully."
printcon "$FAIL deployment tasks failed."
if [ $FAIL -gt 0 -a -d "$LOGPATH" ]; then
printcon "\nNote: the failed RAC IPs are in file '$LOGPATH/failed-hosts'"
printcon " Check the individual process logfiles for more information"
printcon " (for IP=XX, it's logfile is '$LOGPATH/log.XX')"
fi
[ -n "$CONLOG" ] && printcon "\nThe console log was saved as '$CONLOG'."
exit 0
}
# This function is to be used as a trap termination handler.
function quit {
if [ $EXITING -eq 0 ]; then
EXITING=1
RC=99
[ $# -ge 1 ] && printcon "\a\n$@\n"
fi
# -------------------------------------------------------------------------
# if this script is interrupted, any running tasks it spawned are terminated.
# to change this default behavior, set NOKILL=1 at the top of this script.
# then, any work started prior to the interruption is allowed to complete.
# -------------------------------------------------------------------------
if [ -e $CLEANUP -a $NOKILL -eq 0 ]; then
printcon "Cleaning up, please wait.."
while read INPUT_READ
do # we're dying unexpectedly..
if [ -e "$INPUT_READ" ]; then
rm -f $INPUT_READ # cleanup: delete log file
else
kill $INPUT_READ && sleep 3 # cleanup: kill process
fi
done <$CLEANUP
rm -f $CLEANUP
fi
exit $RC
}
# Trap for unplanned termination.
trap "quit \"$SCRIPT interrupted!!\"" EXIT
# Parsing of the command arguments.
if [ $# -gt 0 ]; then
TEMP=$(getopt -o r:u:p:f:c:d -- "$@")
RC=$?
if [ $RC -eq 0 ]; then
eval set -- "$TEMP"
while true
do
case "$1" in
-d) set -x; DBUG=1; VMOPTS="-v"; shift 1
;;
-f) [ -n "$TYPE" ] && TYPE="?" || TYPE="-f"; DEVICE="0x1c"; FILE=$2; shift 2
;;
-c) [ -n "$TYPE" ] && TYPE="?" || TYPE="-c"; FILE=$2; shift 2
;;
-p) RACP=$2; shift 2
;;
-u) RACU=$2; shift 2
;;
-r) LIST=$2; shift 2
;;
--) shift; break
;;
*) RC=8; break
;;
esac
done
fi
fi
# We validate command arguments.
[ $RC -gt 0 ] && error "invalid options found"
[ -z "$LIST" ] && error "<RAC-IP> missing"
[ -z "$RACU" ] && error "<RAC-userid> missing"
[ -z "$RACP" ] && error "<RAC-password> missing"
[ ".$TYPE" = ".?" ] && error "use [<floppy-image> | FDDrive] or [<ISO9660-image> | CDDrive], not both"
#if [ -z "$FILE" ]; then
# error "an image file is required"
#elif [ ! -e "$FILE" ]; then
# error "no such image file: '$FILE'"
#elif [ ! -f "$FILE" ]; then
# error "the image file must be a regular file"
#fi
# We ensure that RAC utilities are available.
if [ -z "$(which ipmitool 2>/dev/null)" ]; then
error "ipmitool doesn't appear to be installed"
print_results_and_exit
fi
if [ -z "$(which vmcli 2>/dev/null)" ]; then
error "vmcli doesn't appear to be installed"
print_results_and_exit
fi
# If there is any error, we print the usage of this script.
[ $FAIL -gt 0 ] && {
printcon "\nusage: $SCRIPT -r <RAC-IP> -u <RAC-userid> -p <RAC-password>"
printcon " [ -f <floppy-image | FDDrive> | -c <ISO9660-image | CDDrive> ]"
printcon "where:"
printcon " <ISO9660-image> and <floppy-image> are bootable image files"
printcon " <FDDrive> and <CDDrive> are Floppy and CD devices respectively"
printcon " <RAC-userid> = RAC user id, with 'virtual media' privilege"
printcon " <RAC-password> = RAC user password"
printcon " <RAC-IP> is either:"
printcon " - a string of the form: 'RAC-IP'"
printcon " - a file containing lines matching that form"
printcon " In the latter case, the boot image is setup and booted"
printcon " for each host/RAC IP contained in the file.\n"
printcon "*Note: your boot image determines what is deployed, and how.\n"
EXITING=1
exit $RC
}
# We check for writable floppy image.
if [ ".$TYPE" = ".-f" -a -w $FILE ]; then
printcon "\n**warning: <floppy-image> appears to be writable."
printcon " Enter 'q' now to quit, any other key to continue.."
read RESP
if [ ".$RESP" = ".q" -o ".$RESP" = ".Q" ]; then
printcon "\nOK, quitting.. (good choice)"
EXITING=1
exit 0
fi
fi
# OK, "let's roll".
CONLOG=$LOGPATH/console.log # setup the console log file.
if [ ! -e "$LIST" ]; then # single RAC IP provided..
tmpfile="$LOGPATH/.iplist" # ..create a temp file
echo "$LIST" >$tmpfile # ..add the single RAC IP
echo "$tmpfile" >>$CLEANUP # ..mark it for cleanup
LIST=$tmpfile
fi
# RAC 'boot once' property.
BOPROP="raw 0x00 0x08 0x05 0x80 $DEVICE 0x00 0x00 0x00"
while read INPUT_READ #for each RAC IP/hostname:
do
IP=${INPUT_READ%%[[:space:]]*}
# TODO: If there is a space before '#', the test below will not work.
[ -z "$IP" -o -z "${IP##\#*}" ] && continue # (skip blank/comment lines)
printcon "\nIP = $IP"
tmpfile="$LOGPATH/log.$IP" # VM process logfile name (includes RAC IP)
# ideally, at this point we would check for the appropriate boot device
# at top of boot list for the target server (or set it thus).
# currently, we cannot :(
# Boot once
echo -e "\n\nChanging the boot order temporarily to boot from the media to be redirected.\n"
echo -e "ipmitool -I lanplus -H $IP -U $RACU -P $RACP $BOPROP\n"
ipmitool -v -I lanplus -H $IP -U $RACU -P $RACP $BOPROP >ipmitool_log 2>&1
cat ipmitool_log
#if [ "`grep \"RAW RSP (0 bytes)\" ipmitool_log`" != "RAW RSP (0 bytes)" ]
grep "RAW RSP (0 bytes)" ipmitool_log
if [ "$?" != 0 ]
then
FAIL=$((FAIL + 1))
echo -e "\n\nERROR: Failed to change the boot order. Please ensure that iDRAC IPMI over LAN is enabled.\n"
killall -9 libvmcli6.so >/dev/null 2>&1
continue
fi
sleep 1
rm -Rf ipmitool_log
# fire off a virtual media process for the target server
echo -e "\n\nRedirecting Virtual Media.\n"
echo "vmcli -r $IP -u $RACU -p $RACP ${TYPE} ${FILE} $VMOPTS"
vmcli -r $IP -u $RACU -p $RACP ${TYPE} ${FILE} $VMOPTS > vmcli_log &
VMPID=$!
printcon "\tVM PID = $VMPID"
sleep 20
cat vmcli_log
#if [ "$(grep \"Mapping\" vmcli_log)" == "" ]
grep "Mapping" vmcli_log
if [ "$?" != 0 ]
then
FAIL=$((FAIL + 1))
echo -e "\n\nERROR: Media redirection error. Please ensure that iDRAC Virtual Media is in Attached or Auto-attached state and Virtual Media session is not already in use."
killall -9 libvmcli6.so >/dev/null 2>&1
continue
fi
#Power cycle the server
ipmitool -I lanplus -H $IP -U $RACU -P $RACP chassis power cycle >ipmitool_log 2>&1
sleep 7
#if [ "$(grep \"not supported\" ipmitool_log)" != "not supported" ]
grep "not supported" ipmitool_log
if [ "$?" != 0 ]
then
echo -e "\n\nPower cycling the server.\n"
echo -e "ipmitool -I lanplus -H $IP -U $RACU -P $RACP chassis power cycle\n"
cat ipmitool_log
rm -Rf ipmitool_log
CONN=1
else
sleep 7
echo -e "\n\nPowering up the server.\n"
ipmitool -I lanplus -H $IP -U $RACU -P $RACP chassis power up
CONN=1
fi
if [ $CONN -eq 1 ]; then # deployment is underway / host booting up
echo "$VMPID" >>$CLEANUP # ..mark the VM process ID for cleanup
echo $tmpfile >>$CLEANUP # ..ditto for the VM process logfile
PASS=$((PASS + 1))
printcon "\tOK."
else
# ----------------------------------------------------------------------
# deployment failed, for this RAC host:
# - kill the Virtual Media process
# - save the RAC IP in the 'failed-hosts' file
# NOTE: we never clean up logs for failed hosts -- must be done manually
# ----------------------------------------------------------------------
kill $VMPID >/dev/null 2>&1
echo "$IP" >>$LOGPATH/failed-hosts
FAIL=$((FAIL + 1))
printcon "\tFAILED -- see '$tmpfile'"
fi
done < $LIST
# --- normal completion: if we get here, don't terminate any work we started.
# (all files in the LOGPATH directory are left alone, for admin perusal)
print_results_and_exit
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists