Cybersecurity
DevOps Cloud
IT Operations Cloud
By Hamish Speirs
Using Art Flores work as a basis (Run Bash Scripts from the PXE Menu), I was looking at how to create a menu system using ZEN 7 SP1. Although very informative, some of Art's methods no longer work with ZEN 7SP1, For Example IMGCMD="runScript.s somescript.s" no longer work. Also, the Menu Editor is no longer directly available from the CD, it's in a jar file, see here for details on how to extract it.
Additionally, I wanted a little more flexibility in accessing the custom scripts. For example, not having to rebuild the initrd or root boot files every time I added or modified a script.
To accomplish this, I modified the /bin/imaging.s script to support executing either a script within the linux file system, or downloading and executing a script from the TFTP server. The imaging script assumes that the script to be downloaded resides in the directory CMDS under the root of the TFTP structure (so, generally: sys:tftp/cmds). I additionally created a new directory /scripts in the initrd file structure that can be used to store scripts that you always want available without having to download.
The modified imaging.s script is as follows:
#!/bin/bash
# imaging.s
. /bin/config.s auto
mountFloppyifLS120
#check for environment variable with command to run
if [ "a0" = "a"${#IMGCMD} ] ; then
/bin/img a
#Return codes for img:
#0SUCCESSFUL, but no changes on hard drive(s)
#1SUCCESSFUL, new image placed on hard drive(s)
#2SUCCESSFUL, proxy had no work to be done
#4SUCCESSFUL, advanced script brought down to be run
else
if test -x "$IMGCMD" ; then
# Script is executable - we don't need to modify it
$IMGCMD
elif test -f "$IMGCMD" ; then
# if the file is a regular file, assume it is a script and in unix format
/usr/bin/dos2unix $IMGCMD
chmod x $IMGCMD
$IMGCMD
else
# We've been passed a script name, download and execute it
cd /scripts
tftp $TFTPIP -c get cmds/$IMGCMD
chmod x $IMGCMD
./$IMGCMD
fi
fi
RESULT=$?
if [ $RESULT"a" = "0a" ] || [ $RESULT"a" = "1a" ] || [ $RESULT"a" = "2a" ] ; then
export IMGSUCCESS=1
elif [ $RESULT"a" = "4a" ] ; then
crlf.s /bin/zenAdvancedScript
chmod x /bin/zenAdvancedScript
. /bin/zenAdvancedScript
else
echo ZENworks imaging failed with error:$RESULT.
fi
/bin/lilo.s auto
To install this script into the initrd file structure, do the following:
With the new imaging script in place, the .cmd files called can now be used to run custom scripts from the /tftp/cmds directory by using, for example:
KERNEL boot/linux
APPEND initrd=boot/initrd vga=0x314 install=tftp://$TFTPIP/boot rootimage=/root PROXYADDR=$PROXYADDR TFTPIP=$TFTPIP splash=silent PXEBOOT=YES mode=2 IMGCMD=gx280-4.s
This will PXE boot the workstation into imaging mode, download the gx280-4.s script and execute it. The actual gx280-4.s script contains:
#!/bin/bash
NC='\e[0m'
RED='\e[0;31m'
WHITe='\e[1;37m'
YELLOW='\e[1;33m'
setterm -clear
echo
echo -e " ${YELLOW} Installing Dell GX-280/620 NetWare Client 4.91 SP4 Image ......."
img restorep $TFTPIP //$TFTPIP/vol1/backups/gx280-4.zmg
IResult=$?
setterm -clear
if [$IResult = 0] ; then
echo -e " ${WHITE} no changes Made ${NC}\a\n\c"
sleep 10
elif [$IResult = 1] ; then
echo -e " ${WHITE} Image successfully installed ${NC}\a\n\c"
sleep 10
elif [$IResult = 2] ; then
echo -e " ${WHITE} No work to do ${NC}\a\n\c"
sleep 10
elif [$IResult = 4] ; then
echo -e " ${WHITE} Advanced Script executed ${NC}\a\n\c"
sleep 10
else
echo -e " ${RED} Multicast Image receive Failed!! ${GREEN} Error Code: $IResult ${NC}\a\n\c"
fi
echo
read -s -n1 -p "Press any key to reboot ......"
reboot -f
In addition, to update the root file system with any scripts I do want in the image, the following script allows the easy installation of scripts, avoiding the need to manually create directories, TFTP the files up and down, etc.
It assumes that the scripts you're installing are coming from /TFTP/CMDS and will be installed into /scripts on the root image ? these directories can be modified if desired. Use the same procedure as for updating imaging.s to copy this into /bin of the root image.
Usage is: supdate.s file1 [file2 file3 file4 . . . . . . . . . . . . .]
#!/bin/bash
# User defined directory names
TEMPDIR="/haitch"
WORKDIR="work"
SCRIPTDIR="scripts"
SOURCEDIR="cmds"
# Error Return Codes
BAD_TEMPDIR=1
NO_ROOT=2
BAD_MOVE=3
BROKEN_ROOT=4
BAD_WORKDIR=5
BAD_MOUNT=6
BAD_SCRIPTDIR=7
BAD_UMOUNT=8
BAD_REZIP=9
BAD_UPLOAD=10
BAD_SYNTAx=11
# some Colorization
NC='\e[0m'
RED='\e[0;31m'
WHITe='\e[1;37m'
YELLOW='\e[1;33m'
GREEN='\e[0;32m'
# Assorted procedures to make life easier
Message () {
echo -e "${WHITE}$1${NC}"
}
Caution () {
echo -e "${YELLOW}$1${NC}"
}
Error () {
echo -e "${RED}Error: $1${NC}"
exit $2
}
#check the result passed in $1, and if non zero, error with the message in $2
Check () {
if [ $1 != 0 ] ; then
Error "$2" $3
fi
}
# function MakeDir
# Creates our working directories - first check to see if the dir exists,
# If it exists, verify it is a directory - error if not a directory, otherwise re-use existing
# directory.
# If it doesn't exist, create it
MakeDir () {
if [ -a $1 ] ; then
if [ -d $1 ] ; then
Caution "Note: $1 already exists"
else
Error "$1 exists, but is not a directory!" $2
fi
else
mkdir $1 > /dev/null
Check $? "Could not create $1!" $2
fi
}
# Function tftpcheck
# The tftp module does NOT return an error code when it has a problem, only an error
# message to stdout. soooo ... we jump through a couple of hoops to check for an error.
# the tftp command output is piped to the file tftptemp, we then check to see if there is any
# text in tftptemp - if there is, an error occured.
tftpcheck () {
TEMPVAL=1
if [ -z "$(cat tftptemp)" ] ; then
TEMPVAL=0
fi
rm tftptemp
return $TEMPVAL
}
## Main Script starts here.
# check they provided at least one file to add
if [ -z "$1" ] ; then
Caution "Usage: `basename $0` file1 [file2 file3 ..... fileN]"
exit BAD_SYNTAX
fi
# Create the top level working directory
MakeDir $TEMPDIR $BAD_TEMP
cd $TEMPDIR
# Download the current root file system
Message "Getting the current root image ......"
tftp $TFTPIP -m binary -c get boot/root > tftptemp
tftpcheck
Check $? "Failed downloading root file system archive" $NO_ROOT
mv root root.gz
Check $? "Failed moving root to root.gz" $BAD_MOVe
Message "Extracting root file system ......"
gunzip root.gz
Check $? "Failed extracting root file system" $BROKEN_ROOT
# Mount the compressed image onto the working directory
Message "Mounting root file system ......"
MakeDir $WORKDIR $BAD_WORKDIR
mount -o loop root work
Check $? "Failed mounting root file system to $TEMPDIR/$WORKDIR" $BAD_MOUNT
cd $WORKDIR
# Create the script directory if required
MakeDir $SCRIPTDIR $BAD_SCRIPTDIR
cd $SCRIPTDIR
# Now process each file name
until [ -z "$1" ] ; do
echo -e "${WHITE}Getting script file: ${GREEN}$1${NC}"
tftp $TFTPIP -c get $SOURCEDIR/$1 > tftptemp
tftpcheck
if [ $? != 0 ] ; then
Caution "Could not download: $1"
else
chmod x $1
cp $1 /$SCRIPTDIR
fi
shift
done
# Close down the fs image
Message "umounting root file system ......"
cd ../..
umount work
Check $? "Could not umount root file system" $BAD_UMOUNT
#Cleanup the working Dir
rmdir $WORKDIR
Message "Compressing root file system ......"
gzip -v9c root > root.gz
Check $? "Failed re-compressing root file sytem" $BAD_REZIP
# and try to upload our new root fs
Message "Uploading new root file system as root.new"
mv root.gz root.new
tftp $TFTPIP -m binary -c put boot/root.new > tftptemp
tftpcheck
Check $? "Failed uploading new root image" $BAD_UPLOAD
rm root.new
echo -e "${GREEN}New root filesystem created and uploaded${NC}"
exit 0
If you have any questions you may contact Hamish at hamish@haitch.net
By James Denton
PROBLEM: The process described in this article did not work for me with ZENworks 7 SP1 IR1. For whatever reason his instructions did not transcribe well on the web, where carriage returns were lost and '-' were changed to '?'. In addition to that, the 'initrd' file is now a cpio file and cannot be mounted. I have modified his instructions and have included them below.
FWIW, I'm very pleased with the results of his article and am happy that we can save even more time with ZENworks now!
SOLUTION:
If you have any questions you may contact James at james.denton@TAKETHISOUTgonzales.txed.net