Problem This recipe demonstrates how to deploy and verify the installation of a Solaris package using WebJob and PaD technology. The main motivation for this recipe was the desire/need to create a reliable, hands-off approach to deploying packages. In particular, the authors wanted to construct an automated solution having feedback properties that could be used to determine success or failure. Requirements Cooking with this recipe requires an operational WebJob server. If you do not have one of those, refer to the instructions provided in the README.INSTALL file that comes with the source distribution. The latest source distribution is available here: http://sourceforge.net/project/showfiles.php?group_id=40788 Also, if you're not familiar with PaD technology, then you should read the background material found here: http://webjob.sourceforge.net/WebJob/PayloadAndDelivery.shtml Each client system must be running Solaris and have at least the following utilities: basename, cut, gunzip, pkgadd, pkgchk, pkginfo, pkgrm, rm, sh, and webjob (1.4.0 or higher). The commands presented throughout this recipe were designed to be executed within a Bourne shell (i.e. sh or bash). Solution The solution is to use deploy-solaris-pkg.sh (see Appendix 1). The purpose of this script is to construct a PaD delivery command and execute it with WebJob. The delivery command unpacks a gzip'd package and surveys the system to determine if that particular package is installed. If it is not, the downloaded package is deployed. However, if deployment fails, the delivery command will attempt to revert to the previous state by removing the package. Once the package is deployed, its installation is verified. The delivery command finishes by removing any temporary files. This logic, in script form, is presented here: ${UNPACK} && ${SURVEY} || { { ${DEPLOY} || ${REVERT} } && ${VERIFY} } ; ${FINISH} Each of these variables can be thought of as a macro that implements one particular operation. As such, each variable can contain one or more commands and associated shell logic. The following steps describe how to implement this solution. 1. Download, acquire, or build the Solaris package you wish to deploy. This recipe uses the gdb (GNU debugger) package as the target package. $ fetch ftp://ftp.sunfreeware.com/pub/freeware/sparc/8/gdb-4.18-sol8-sparc-local.gz 2. Before proceeding, you need to define the following variables: PKG_FILE, PKG_BASE, PKG_NAME, and PAD_FILE. These variables are referenced at various points in the remaining steps. $ PKG_FILE=gdb-4.18-sol8-sparc-local.gz $ echo ${PKG_FILE} gdb-4.18-sol8-sparc-local.gz $ PKG_BASE=`basename ${PKG_FILE} .gz` $ echo ${PKG_BASE} gdb-4.18-sol8-sparc-local To define PKG_NAME, you need to determine the package's name. On Solaris systems this can be done with pkginfo. Note, however, that pkginfo expects an uncompressed package as input, so you'll need to uncompress and recompress the package as necessary. $ gunzip ${PKG_FILE} $ PKG_NAME=`pkginfo -d ${PKG_BASE} | head -1 | awk '{print $2}'` $ echo ${PKG_NAME} SMCgdb $ gzip ${PKG_BASE} If that approach doesn't work, try extracting the package name as follows: $ PKG_NAME=`gunzip -c ${PKG_FILE} | strings | grep PKG= | head -1 | awk -F\= '{print $2}'` $ echo ${PKG_NAME} SMCgdb The final variable, PAD_FILE, is defined as follows: $ PAD_FILE=${PKG_NAME}.${PKG_FILE}.pad $ echo ${PAD_FILE} SMCgdb.gdb-4.18-sol8-sparc-local.gz.pad 3. Construct a PaD script from the package file. $ pad-make-script --create ${PKG_FILE} > ${PAD_FILE} 4. Determine where to place the PaD script on the WebJob server. Typically, it would go in the client's commands directory. However, if multiple clients will be involved, it should go in a common commands directory. The permissions on this script should be set to mode 0644. The following commands show how this could be done using scp as the file transfer agent. $ LOCATION=/integrity/profiles/client_0001/commands/ or $ LOCATION=/integrity/profiles/common/commands/ $ chmod 644 ${PAD_FILE} $ scp -p ${PAD_FILE} you@your.webjob.server.net:${LOCATION} 5. Extract deploy-solaris-pkg.sh from Appendix 1, and install it in a suitable location on each client system. Use the following command to extract the script: $ sed -e '1,/^--- deploy-solaris-pkg.sh ---$/d; /^--- deploy-solaris-pkg.sh ---$/,$d' webjob-pad-deploy-solaris-pkg.txt > deploy-solaris-pkg.sh Note: It may be necessary to modify the PATH variable, which is explicitly set inside the script, to suit your particular environment. Install the script on each client. $ chmod 755 deploy-solaris-pkg.sh $ scp -p deploy-solaris-pkg.sh root@your.webjob.client.net:/usr/local/bin 6. Test deployment on one client by running deploy-solaris-pkg.sh. You'll need to be root at this point. $ ssh root@your.webjob.client.net # deploy-solaris-pkg.sh -f SMCgdb.gdb-4.18-sol8-sparc-local.gz.pad Closing Remarks To benefit from this recipe, you really need a way to deploy packages without having to log onto each client system. To that end, you may want to consider using this recipe in conjunction with the one called "Manage root's crontab". Installing deploy-solaris-pkg.sh on each client is not absolutely necessary because it could be kept on the server. However, it is convenient because you may want to log in and run it manually from time to time. Credits This recipe was brought to you by Andy Bair and Klayton Monroe. Appendix 1 --- deploy-solaris-pkg.sh --- #!/bin/sh IFS=' ' PROGRAM=`basename "$0"` Usage() { echo 1>&2 echo "Usage: ${PROGRAM} [-c webjob-conf] [-h webjob-home] -f pad-file" 1>&2 echo 1>&2 exit 1 } while getopts "c:f:h:" OPTION; do case ${OPTION} in c) WEBJOB_CONF="${OPTARG}" ;; f) PAD_FILE="${OPTARG}" ;; h) WEBJOB_HOME="${OPTARG}" ;; *) Usage ;; esac done if [ -z "${PAD_FILE}" ]; then Usage else PKG_NAME=`echo ${PAD_FILE} | cut -d '.' -f 1` PKG_BASE=`basename "${PAD_FILE}" .gz.pad` fi PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:${WEBJOB_HOME=/usr/local/integrity}/bin export PATH UNPACK=" { echo 'Unpacking...' 1>&2 ; gunzip %payload ; }" SURVEY=" { echo 'Surveying...' 1>&2 ; pkginfo -i ${PKG_NAME} ; }" DEPLOY=" { echo 'Deploying...' 1>&2 ; pkgadd -n -d ${PKG_BASE} ${PKG_NAME} ; }" VERIFY=" { echo 'Verifying...' 1>&2 ; pkgchk -l ${PKG_NAME} ; }" REVERT=" { echo 'Reverting...' 1>&2 ; pkgrm -n ${PKG_NAME} ; false ; }" FINISH=" { echo 'Finishing...' 1>&2 ; rm -f %payload ${PKG_BASE}; }" PAD_COMMAND=" { ${UNPACK} && ${SURVEY} || { { ${DEPLOY} || ${REVERT} } && ${VERIFY} } ; ${FINISH} }" webjob -e -f ${WEBJOB_CONF-${WEBJOB_HOME}/etc/webjob.cfg} ${PAD_FILE} ${PAD_COMMAND} --- deploy-solaris-pkg.sh ---