Revision $Id: webjob-run-periodic.base,v 1.11 2007/10/11 20:53:13 klm Exp $ Purpose This recipe demonstrates a simple script-based scheme that can be used within a WebJob framework to schedule/manage periodic administrative tasks. Motivation The motivation for this recipe was to create a simple scheme that can be used to centrally manage and automate common administrative tasks. In large, complex production environments, ad hoc administrative practices tend to increase the amount of variance between similarly configured systems. As variance increases, the amount of time spent doing ad hoc administration also tends to increase. To combat this degenerative cycle, administrators should replace ad hoc techniques in favor of programmatic or mechanized techniques. This practice will also help to reduce the amount of oversights, errors, and duplicated effort. 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 Each client must be running UNIX and have basic system utilities and WebJob (1.7.0 or higher) installed. The server must be running UNIX and have basic system utilities, PaD utilities, and WebJob installed. 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 periodically download and run the hourly, daily, weekly, and monthly scripts. The following steps describe how to implement this solution. 1. Set WEBJOB_CLIENT and WEBJOB_COMMANDS as appropriate for your server. Next, extract the hourly, daily, weekly, monthly scripts at the bottom of this recipe, and install them to the appropriate commands directory. If you want these scripts to be bound to a particular client, set WEBJOB_CLIENT as appropriate before running the following commands. Once the files are in place, set their ownership and permissions to 0:0 and mode 644, respectively. # WEBJOB_CLIENT=common # WEBJOB_COMMANDS=/webjob/profiles/${WEBJOB_CLIENT}/commands # sed -e '1,/^--- hourly ---$/d; /^--- hourly ---$/,$d' webjob-run-periodic.txt > hourly # sed -e '1,/^--- daily ---$/d; /^--- daily ---$/,$d' webjob-run-periodic.txt > daily # sed -e '1,/^--- weekly ---$/d; /^--- weekly ---$/,$d' webjob-run-periodic.txt > weekly # sed -e '1,/^--- monthly ---$/d; /^--- monthly ---$/,$d' webjob-run-periodic.txt > monthly # TARGETS="hourly daily weekly monthly" # for TARGET in ${TARGETS} ; do cp ${TARGET} ${WEBJOB_COMMANDS}/ && chmod 644 ${WEBJOB_COMMANDS}/${TARGET} && chown 0:0 ${WEBJOB_COMMANDS}/${TARGET} ; done 2. Extract s_hlc_any, s_cat_any, s_tar_any from this recipe, and install them in the commands directory. Then create symbolic links to s_hlc_any for any standard commands you intend to use. Some commonly used examples include: as s_hlc_hostname, s_hlc_ifconfig, s_hlc_netstat, s_hlc_ps, s_hlc_uname, and s_hlc_uptime. # WEBJOB_CLIENT=common # WEBJOB_COMMANDS=/webjob/profiles/${WEBJOB_CLIENT}/commands # sed -e '1,/^--- s_hlc_any ---$/d; /^--- s_hlc_any ---$/,$d' webjob-run-periodic.txt > s_hlc_any # sed -e '1,/^--- s_cat_any ---$/d; /^--- s_cat_any ---$/,$d' webjob-run-periodic.txt > s_cat_any # sed -e '1,/^--- s_tar_any ---$/d; /^--- s_tar_any ---$/,$d' webjob-run-periodic.txt > s_tar_any # TARGETS="s_hlc_any s_cat_any s_tar_any" # for TARGET in ${TARGETS} ; do cp ${TARGET} ${WEBJOB_COMMANDS}/ && chmod 644 ${WEBJOB_COMMANDS}/${TARGET} && chown 0:0 ${WEBJOB_COMMANDS}/${TARGET} ; done # TARGETS="s_hlc_hostname s_hlc_ifconfig s_hlc_netstat s_hlc_ps s_hlc_uname s_hlc_uptime" # for TARGET in ${TARGETS} ; do ln -s s_hlc_any ${WEBJOB_COMMANDS}/${TARGET} && chmod 644 ${WEBJOB_COMMANDS}/${TARGET} && chown 0:0 ${WEBJOB_COMMANDS}/${TARGET} ; done Essentially, s_hlc_any is a wrapper script that allows client's to run local copies of the target command. The target command is calculated by removing the s_hlc_ prefix. Incidentally, the s_hlc_ prefix is short for 'standard harvest local command'. The purpose of the s_hlc_any script is to provide a vehicle for transmitting harvested data to the WebJob server. Sometimes, it's not practical (e.g., bandwidth limitations) to download a binary from the WebJob server each time you want to harvest a particular type of data. In these cases, you may want to use a standard or custom (c_hlc_) wrapper script to execute locally installed utilities. 3. Create crontab entries on each client that execute the periodic scripts. Be sure to substitute the correct path for WEBJOB_HOME prior to committing the new crontab. 0 * * * * ${WEBJOB_HOME=/usr/local/webjob}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg hourly 0 0 * * * ${WEBJOB_HOME=/usr/local/webjob}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg daily 0 0 * * 1 ${WEBJOB_HOME=/usr/local/webjob}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg weekly 0 0 1 * * ${WEBJOB_HOME=/usr/local/webjob}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg monthly 4. At this point, you will be able to perform several basic tasks or functions: heartbeat, deploy/update files, update WebJob, regular jobs, and oneshot jobs. Additionally, you'll be able to take advantage of the group feature for regular and oneshot jobs. Heartbeat: By default, the periodic scripts do nothing except check in at the appointed time. This activity can be monitored and used like a heartbeat. If the heartbeat stops or becomes irregular, you may want to generate an alarm or take action. Deploy/Update Files: Sometimes, it's more convenient or practical to keep certain utilities on the client. In other cases, you may want to ensure that a given file is deployed and current. For these cases, you can use the DeployFile() and UpdateFile() routines. To ensure that a given file is always deployed, simply add an entry to DeployAll(). The following example shows how to ensure that ftimes is deployed on the local host. If ftimes gets deleted for any reason, this routine will automatically reinstall it at the next hourly invocation. DeployFile "${WEBJOB_HOME}/etc/upload.cfg" "ftimes.pad" "${WEBJOB_HOME}/bin/ftimes" "755" "root" "wheel" DeployFile() has the following usage: DeployFile "" "" "" "" "" "" To ensure that a given file is always up to date, simply add an entry to UpdateAll(). The following example shows how to ensure that ftimes stays current on the local host. If ftimes gets modified for any reason, this routine will automatically reinstall it at the next hourly invocation. UpdateFile "${WEBJOB_HOME}/etc/upload.cfg" "ftimes.pad" "${WEBJOB_HOME}/bin/ftimes" "755" "root" "wheel" "f4cce61ead9945813abb686ae5b19fad" "md5" UpdateFile() has the following usage: UpdateFile "" "" "" "" "" "" "" "" There are two things to note here: 1) is the full path and filename of the target file and 2) is the hash algorithm (i.e., MD5 or SHA1). Update WebJob: Updating WebJob via WebJob on some platforms (like Solaris) requires a shuffle maneuver to prevent a resource conflict. The script webjob-update-client was specifically developed to handle this situation, but it can also be used to update WebJob on other platforms such as FreeBSD, Linux, and MacOS. This script is available here: http://webjob.cvs.sourceforge.net/webjob/webjob/tools/webjob-update-client To ensure that WebJob file is always up to date, simply add an UpdateWebJob() entry to UpdateAll(). UpdateWebJob() has the following usage: UpdateWebJob "" "" "" "" "" "" "" Regular Jobs: The hourly script provides 1, 2, 3, 4, 6, 8, and 12 hour job routines, and the daily, weekly, and monthly scripts provide daily, weekly, and monthly job routines. As you come up with periodic administrative tasks, simply drop them in the appropriate Run{XXHour,Daily,Weekly,Monthly}Jobs() routine as their own WebJob. The following example shows how to harvest uptime data every hour using the client's local copy of uptime. ${WEBJOB_HOME}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg s_hlc_uptime Oneshot Jobs: Suppose that you need a mechanism to perform remote diagnostics during an emergency, incident, or investigation. Under normal conditions, the periodic scripts would do nothing, just as in the heartbeat case. However, during a crisis, you may be required to run a series of diagnostic tests. Since the periodic scripts are already in place, all you'd need to do is modify the appropriate RunOneShotJobs() routine and set the target time value(s) so they'll become active at the next scheduled run time. The following example shows how you'd configure the RunOneShotJobs() routine in the hourly script to run lsof and check_vitals.sh on January 1st, 2004 between 1200 and 1300 hours. MY_TARGET_DATE="2004-01-01" MY_TARGET_HOUR="12" if [ "${MY_DATE}"X = "${MY_TARGET_DATE}"X -a "${MY_HOUR}"X = "${MY_TARGET_HOUR}"X ] ; then ${WEBJOB_HOME}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg check_vitals.sh ${WEBJOB_HOME}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg lsof -Di -n -P -itcp -iudp fi Groups: Each periodic script supports multiple user-specified groups. These groups are based on hostnames -- short names not fully qualified names. Suppose you want to run a custom job, but you only want a select set of clients to execute it. To set that up, you'd add the hostnames of the selected clients to one of the predefined groups (e.g., MY_GROUP1) in GetHostGroups(). For example, if you had three hosts, host[123], you would add them (space delimited) to MY_GROUP1 as follows: MY_GROUP1="host1 host2 host3" Then, you'd be ready to insert custom jobs in the appropriate case statement(s) -- either in a regular or oneshot routine. Here's an example of how a typical case statement would look after you have inserted your custom jobs: for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ${WEBJOB_HOME}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg custom_job1 ${WEBJOB_HOME}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg custom_job2 ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done You may also define new groups in each of the periodic scripts. Suppose you want to create a group called MY_AUDIT1 and associate your selected clients with it instead of one of the default groups (e.g., MY_GROUP[12]). In that case, you'd need to create a new variable called MY_AUDIT1 and update the MY_GROUPS variable like so: MY_AUDIT1="host1 host2 host3" MY_GROUPS="MY_GROUP1 MY_GROUP2 MY_AUDIT1" After that, you'd need to modify some or all of the case statements (all is recommended) to recognize the newly defined group. Continuing with the previous example, the case statement from above would be modified so that it looks like this: for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_AUDIT1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ${WEBJOB_HOME}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg custom_job1 ${WEBJOB_HOME}/bin/webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg custom_job2 ;; MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done Closing Remarks One problem with this approach is that you must edit the scripts manually -- that practice is inherently error prone. Over time, the problem gets worse because the scripts tend to build up cruft from old jobs, quick fixes, and experimentation. A better approach would be to dynamically build the requested script based on a task list and set of predefined (but fully tested) routines. Credits This recipe was brought to you by Klayton Monroe. Appendix 1 --- hourly --- #!/bin/sh ###################################################################### # # $Id: hourly,v 1.9 2007/10/03 21:46:46 klm Exp $ # ###################################################################### # # Copyright 2003-2007 The WebJob Project, All Rights Reserved. # ###################################################################### # # Purpose: Periodically (hourly) run common administrative tasks. # ###################################################################### IFS=' ' PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin PROGRAM=`basename $0` HOSTNAME=`hostname | awk -F. '{print $1}'` ###################################################################### # # GetHostGroups # ###################################################################### GetHostGroups() { #################################################################### # # To associate a client with a particular group, add it's hostname # to the appropriate list. If you want to add a new group, then # make sure you update MY_GROUPS. Note: fully qualified hostnames # aren't supported by this implementation. # #################################################################### MY_GROUP1="" MY_GROUP2="" MY_GROUPS="MY_GROUP1 MY_GROUP2" #################################################################### # # Figure out which groups this host belongs to. # #################################################################### MY_HOST=`hostname | awk -F. '{print $1}'` MY_LIST="" for GROUP in ${MY_GROUPS} ; do eval HOSTS=\$${GROUP} for HOST in ${HOSTS} ; do if [ "${HOST}"X = "${MY_HOST}"X ] ; then MY_LIST="${MY_LIST} ${GROUP}" fi done done echo ${MY_LIST} } ###################################################################### # # RunRegularJobs "" "" # ###################################################################### RunRegularJobs() { MY_DATE=$1 MY_HOUR=$2 #################################################################### # # This is a wrapper routine. Don't put jobs here. Instead, put # them in one of the subordinate routines. # #################################################################### case "${MY_HOUR}" in 00) Run01HourJobs ; Run02HourJobs ; Run03HourJobs ; Run04HourJobs ; Run06HourJobs ; Run08HourJobs ; Run12HourJobs ;; 01) Run01HourJobs ;; 02) Run01HourJobs ; Run02HourJobs ;; 03) Run01HourJobs ; Run03HourJobs ;; 04) Run01HourJobs ; Run02HourJobs ; Run04HourJobs ;; 05) Run01HourJobs ;; 06) Run01HourJobs ; Run02HourJobs ; Run03HourJobs ; Run06HourJobs ;; 07) Run01HourJobs ;; 08) Run01HourJobs ; Run02HourJobs ; Run04HourJobs ; Run08HourJobs ;; 09) Run01HourJobs ; Run03HourJobs ;; 10) Run01HourJobs ; Run02HourJobs ;; 11) Run01HourJobs ;; 12) Run01HourJobs ; Run02HourJobs ; Run03HourJobs ; Run04HourJobs ; Run06HourJobs ; Run12HourJobs ;; 13) Run01HourJobs ;; 14) Run01HourJobs ; Run02HourJobs ;; 15) Run01HourJobs ; Run03HourJobs ;; 16) Run01HourJobs ; Run02HourJobs ; Run04HourJobs ; Run08HourJobs ;; 17) Run01HourJobs ;; 18) Run01HourJobs ; Run02HourJobs ; Run03HourJobs ; Run06HourJobs ;; 19) Run01HourJobs ;; 20) Run01HourJobs ; Run02HourJobs ; Run04HourJobs ;; 21) Run01HourJobs ; Run03HourJobs ;; 22) Run01HourJobs ; Run02HourJobs ;; 23) Run01HourJobs ;; *) ;; esac } ###################################################################### # # Run01HourJobs # ###################################################################### Run01HourJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # Run02HourJobs # ###################################################################### Run02HourJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # Run03HourJobs # ###################################################################### Run03HourJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # Run04HourJobs # ###################################################################### Run04HourJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # Run06HourJobs # ###################################################################### Run06HourJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # Run08HourJobs # ###################################################################### Run08HourJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # Run12HourJobs # ###################################################################### Run12HourJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # RunOneShotJobs "" "" # ###################################################################### RunOneShotJobs() { MY_DATE=$1 MY_HOUR=$2 #################################################################### # # If it's our time, execute the jobs specified below. # #################################################################### MY_TARGET_DATE="YYYY-MM-DD" # REPLACE WITH THE TARGET DATE MY_TARGET_HOUR="HH" # REPLACE WITH THE TARGET HOUR if [ "${MY_DATE}"X = "${MY_TARGET_DATE}"X -a "${MY_HOUR}"X = "${MY_TARGET_HOUR}"X ] ; then ################################################################## # # Common jobs. # ################################################################## : # REPLACE WITH ONE OR MORE COMMON JOBS ################################################################## # # Custom jobs. # ################################################################## for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done fi } ###################################################################### # # DeployFile # ###################################################################### DeployFile() { MY_CFG_FILE=$1 MY_PAD_FILE=$2 MY_TARGET_PATH=$3 # Full path including filename. MY_TARGET_MODE=$4 MY_TARGET_OWNER=$5 MY_TARGET_GROUP=$6 MY_CP_CMD="{ cp %payload ${MY_TARGET_PATH} ; }" MY_CHMOD_CMD="{ chmod ${MY_TARGET_MODE} ${MY_TARGET_PATH} ; }" MY_CHOWN_CMD="{ chown ${MY_TARGET_OWNER}:${MY_TARGET_GROUP} ${MY_TARGET_PATH} ; }" MY_RM_CMD="{ rm -f %payload ; }" MY_ID=`id | sed 's/^uid=\([0-9]\{1,5\}\)(.*$/\1/;'` if [ "${MY_ID}"X = "0"X ] ; then MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} && ${MY_CHOWN_CMD} } ; ${MY_RM_CMD}" else MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} } ; ${MY_RM_CMD}" fi if [ ! -f ${MY_TARGET_PATH} ] ; then webjob -e -f ${MY_CFG_FILE} ${MY_PAD_FILE} ${MY_PAD_CMD} fi } ###################################################################### # # DeployAll # ###################################################################### DeployAll() { #################################################################### # # Deployment jobs. This area is for jobs that deploy files to the # client (e.g., programs and config files). All jobs specified # here should call DeployFile() with the appropriate arguments. # #################################################################### : # REPLACE WITH ONE OR MORE DEPLOY JOBS } ###################################################################### # # UpdateFile # ###################################################################### UpdateFile() { MY_CFG_FILE=$1 MY_PAD_FILE=$2 MY_TARGET_PATH=$3 # Full path including filename. MY_TARGET_MODE=$4 MY_TARGET_OWNER=$5 MY_TARGET_GROUP=$6 MY_TARGET_HASH=$7 MY_DIGEST_TYPE=$8 # (MD5|SHA1) MY_CP_CMD="{ cp -f %payload ${MY_TARGET_PATH} ; }" MY_CHMOD_CMD="{ chmod ${MY_TARGET_MODE} ${MY_TARGET_PATH} ; }" MY_CHOWN_CMD="{ chown ${MY_TARGET_OWNER}:${MY_TARGET_GROUP} ${MY_TARGET_PATH} ; }" MY_RM_CMD="{ rm -f %payload ; }" MY_ID=`id | sed 's/^uid=\([0-9]\{1,5\}\)(.*$/\1/;'` if [ "${MY_ID}"X = "0"X ] ; then MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} && ${MY_CHOWN_CMD} } ; ${MY_RM_CMD}" else MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} } ; ${MY_RM_CMD}" fi if [ -f ${MY_TARGET_PATH} ] ; then MY_ACTUAL_HASH=`webjob -h -t ${MY_DIGEST_TYPE} ${MY_TARGET_PATH}` if [ "${MY_ACTUAL_HASH}" != "${MY_TARGET_HASH}" ] ; then webjob -e -f ${MY_CFG_FILE} ${MY_PAD_FILE} ${MY_PAD_CMD} fi fi } ###################################################################### # # UpdateAll # ###################################################################### UpdateAll() { #################################################################### # # Update jobs. This area is for jobs that update files that already # exist on the client (e.g., programs and config files). All jobs # specified here should call UpdateFile() with the appropriate # arguments. # #################################################################### : # REPLACE WITH ONE OR MORE UPDATE JOBS #################################################################### # # To update webjob using webjob, uncomment the following line, and # set the arguments as necessary. The webjob-update-client script, # must be deployed on the WebJob server for UpdateWebJob() to work # as intended. # #################################################################### # UpdateWebJob "${WEBJOB_HOME}" "755" "root" "wheel" "X.X.X" "00000000000000000000000000000000" "md5" } ###################################################################### # # UpdateWebJob # ###################################################################### UpdateWebJob() { MY_TARGET_HOME=$1 MY_TARGET_MODE=$2 MY_TARGET_OWNER=$3 MY_TARGET_GROUP=$4 MY_TARGET_VERSION=$5 MY_TARGET_HASH=$6 MY_DIGEST_TYPE=$7 # (MD5|SHA1) MY_TARGET_PATH=${MY_TARGET_HOME}/bin/webjob if [ -f ${MY_TARGET_PATH} ] ; then MY_ACTUAL_HASH=`webjob -h -t ${MY_DIGEST_TYPE} ${MY_TARGET_PATH}` if [ "${MY_ACTUAL_HASH}" != "${MY_TARGET_HASH}" ] ; then webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg webjob-update-client -H ${MY_TARGET_HOME} -m ${MY_TARGET_MODE} -u ${MY_TARGET_OWNER} -g ${MY_TARGET_GROUP} -v ${MY_TARGET_VERSION} fi fi } ###################################################################### # # Usage # ###################################################################### Usage() { echo 1>&2 echo "Usage: ${PROGRAM} [-H webjob-home]" 1>&2 echo 1>&2 exit 1 } ###################################################################### # # Main # ###################################################################### while getopts "H:" OPTION ; do case "${OPTION}" in H) WEBJOB_HOME="${OPTARG}" ;; *) Usage ;; esac done if [ ${OPTIND} -le $# ] ; then Usage fi PATH=${PATH}:${WEBJOB_HOME=/usr/local/webjob}/bin DATE=`date "+%Y-%m-%d"` HOUR=`date "+%H"` PROCESSOR=`uname -p` DeployAll UpdateAll RunRegularJobs "${DATE}" "${HOUR}" RunOneShotJobs "${DATE}" "${HOUR}" --- hourly --- Appendix 2 --- daily --- #!/bin/sh ###################################################################### # # $Id: daily,v 1.9 2007/10/03 21:46:46 klm Exp $ # ###################################################################### # # Copyright 2003-2007 The WebJob Project, All Rights Reserved. # ###################################################################### # # Purpose: Periodically (daily) run common administrative tasks. # ###################################################################### IFS=' ' PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin PROGRAM=`basename $0` HOSTNAME=`hostname | awk -F. '{print $1}'` ###################################################################### # # GetHostGroups # ###################################################################### GetHostGroups() { #################################################################### # # To associate a client with a particular group, add it's hostname # to the appropriate list. If you want to add a new group, then # make sure you update MY_GROUPS. Note: fully qualified hostnames # aren't supported by this implementation. # #################################################################### MY_GROUP1="" MY_GROUP2="" MY_GROUPS="MY_GROUP1 MY_GROUP2" #################################################################### # # Figure out which groups this host belongs to. # #################################################################### MY_HOST=`hostname | awk -F. '{print $1}'` MY_LIST="" for GROUP in ${MY_GROUPS} ; do eval HOSTS=\$${GROUP} for HOST in ${HOSTS} ; do if [ "${HOST}"X = "${MY_HOST}"X ] ; then MY_LIST="${MY_LIST} ${GROUP}" fi done done echo ${MY_LIST} } ###################################################################### # # RunRegularJobs "" # ###################################################################### RunRegularJobs() { MY_DATE=$1 #################################################################### # # This is a wrapper routine. Don't put jobs here. Instead, put # them in one of the subordinate routines. # #################################################################### RunDailyJobs } ###################################################################### # # RunDailyJobs # ###################################################################### RunDailyJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # RunOneShotJobs "" # ###################################################################### RunOneShotJobs() { MY_DATE=$1 #################################################################### # # If it's our time, execute the jobs specified below. # #################################################################### MY_TARGET_DATE="YYYY-MM-DD" # REPLACE WITH THE TARGET DATE if [ "${MY_DATE}"X = "${MY_TARGET_DATE}"X ] ; then ################################################################## # # Common jobs. # ################################################################## : # REPLACE WITH ONE OR MORE COMMON JOBS ################################################################## # # Custom jobs. # ################################################################## for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done fi } ###################################################################### # # DeployFile # ###################################################################### DeployFile() { MY_CFG_FILE=$1 MY_PAD_FILE=$2 MY_TARGET_PATH=$3 # Full path including filename. MY_TARGET_MODE=$4 MY_TARGET_OWNER=$5 MY_TARGET_GROUP=$6 MY_CP_CMD="{ cp %payload ${MY_TARGET_PATH} ; }" MY_CHMOD_CMD="{ chmod ${MY_TARGET_MODE} ${MY_TARGET_PATH} ; }" MY_CHOWN_CMD="{ chown ${MY_TARGET_OWNER}:${MY_TARGET_GROUP} ${MY_TARGET_PATH} ; }" MY_RM_CMD="{ rm -f %payload ; }" MY_ID=`id | sed 's/^uid=\([0-9]\{1,5\}\)(.*$/\1/;'` if [ "${MY_ID}"X = "0"X ] ; then MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} && ${MY_CHOWN_CMD} } ; ${MY_RM_CMD}" else MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} } ; ${MY_RM_CMD}" fi if [ ! -f ${MY_TARGET_PATH} ] ; then webjob -e -f ${MY_CFG_FILE} ${MY_PAD_FILE} ${MY_PAD_CMD} fi } ###################################################################### # # DeployAll # ###################################################################### DeployAll() { #################################################################### # # Deployment jobs. This area is for jobs that deploy files to the # client (e.g., programs and config files). All jobs specified # here should call DeployFile() with the appropriate arguments. # #################################################################### : # REPLACE WITH ONE OR MORE DEPLOY JOBS } ###################################################################### # # UpdateFile # ###################################################################### UpdateFile() { MY_CFG_FILE=$1 MY_PAD_FILE=$2 MY_TARGET_PATH=$3 # Full path including filename. MY_TARGET_MODE=$4 MY_TARGET_OWNER=$5 MY_TARGET_GROUP=$6 MY_TARGET_HASH=$7 MY_DIGEST_TYPE=$8 # (MD5|SHA1) MY_CP_CMD="{ cp -f %payload ${MY_TARGET_PATH} ; }" MY_CHMOD_CMD="{ chmod ${MY_TARGET_MODE} ${MY_TARGET_PATH} ; }" MY_CHOWN_CMD="{ chown ${MY_TARGET_OWNER}:${MY_TARGET_GROUP} ${MY_TARGET_PATH} ; }" MY_RM_CMD="{ rm -f %payload ; }" MY_ID=`id | sed 's/^uid=\([0-9]\{1,5\}\)(.*$/\1/;'` if [ "${MY_ID}"X = "0"X ] ; then MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} && ${MY_CHOWN_CMD} } ; ${MY_RM_CMD}" else MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} } ; ${MY_RM_CMD}" fi if [ -f ${MY_TARGET_PATH} ] ; then MY_ACTUAL_HASH=`webjob -h -t ${MY_DIGEST_TYPE} ${MY_TARGET_PATH}` if [ "${MY_ACTUAL_HASH}" != "${MY_TARGET_HASH}" ] ; then webjob -e -f ${MY_CFG_FILE} ${MY_PAD_FILE} ${MY_PAD_CMD} fi fi } ###################################################################### # # UpdateAll # ###################################################################### UpdateAll() { #################################################################### # # Update jobs. This area is for jobs that update files that already # exist on the client (e.g., programs and config files). All jobs # specified here should call UpdateFile() with the appropriate # arguments. # #################################################################### : # REPLACE WITH ONE OR MORE UPDATE JOBS #################################################################### # # To update webjob using webjob, uncomment the following line, and # set the arguments as necessary. The webjob-update-client script, # must be deployed on the WebJob server for UpdateWebJob() to work # as intended. # #################################################################### # UpdateWebJob "${WEBJOB_HOME}" "755" "root" "wheel" "X.X.X" "00000000000000000000000000000000" "md5" } ###################################################################### # # UpdateWebJob # ###################################################################### UpdateWebJob() { MY_TARGET_HOME=$1 MY_TARGET_MODE=$2 MY_TARGET_OWNER=$3 MY_TARGET_GROUP=$4 MY_TARGET_VERSION=$5 MY_TARGET_HASH=$6 MY_DIGEST_TYPE=$7 # (MD5|SHA1) MY_TARGET_PATH=${MY_TARGET_HOME}/bin/webjob if [ -f ${MY_TARGET_PATH} ] ; then MY_ACTUAL_HASH=`webjob -h -t ${MY_DIGEST_TYPE} ${MY_TARGET_PATH}` if [ "${MY_ACTUAL_HASH}" != "${MY_TARGET_HASH}" ] ; then webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg webjob-update-client -H ${MY_TARGET_HOME} -m ${MY_TARGET_MODE} -u ${MY_TARGET_OWNER} -g ${MY_TARGET_GROUP} -v ${MY_TARGET_VERSION} fi fi } ###################################################################### # # Usage # ###################################################################### Usage() { echo 1>&2 echo "Usage: ${PROGRAM} [-H webjob-home]" 1>&2 echo 1>&2 exit 1 } ###################################################################### # # Main # ###################################################################### while getopts "H:" OPTION ; do case "${OPTION}" in H) WEBJOB_HOME="${OPTARG}" ;; *) Usage ;; esac done if [ ${OPTIND} -le $# ] ; then Usage fi PATH=${PATH}:${WEBJOB_HOME=/usr/local/webjob}/bin DATE=`date "+%Y-%m-%d"` PROCESSOR=`uname -p` DeployAll UpdateAll RunRegularJobs "${DATE}" RunOneShotJobs "${DATE}" --- daily --- Appendix 3 --- weekly --- #!/bin/sh ###################################################################### # # $Id: weekly,v 1.8 2007/10/03 21:46:46 klm Exp $ # ###################################################################### # # Copyright 2003-2007 The WebJob Project, All Rights Reserved. # ###################################################################### # # Purpose: Periodically (weekly) run common administrative tasks. # ###################################################################### IFS=' ' PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin PROGRAM=`basename $0` HOSTNAME=`hostname | awk -F. '{print $1}'` ###################################################################### # # GetHostGroups # ###################################################################### GetHostGroups() { #################################################################### # # To associate a client with a particular group, add it's hostname # to the appropriate list. If you want to add a new group, then # make sure you update MY_GROUPS. Note: fully qualified hostnames # aren't supported by this implementation. # #################################################################### MY_GROUP1="" MY_GROUP2="" MY_GROUPS="MY_GROUP1 MY_GROUP2" #################################################################### # # Figure out which groups this host belongs to. # #################################################################### MY_HOST=`hostname | awk -F. '{print $1}'` MY_LIST="" for GROUP in ${MY_GROUPS} ; do eval HOSTS=\$${GROUP} for HOST in ${HOSTS} ; do if [ "${HOST}"X = "${MY_HOST}"X ] ; then MY_LIST="${MY_LIST} ${GROUP}" fi done done echo ${MY_LIST} } ###################################################################### # # RunRegularJobs "" # ###################################################################### RunRegularJobs() { MY_WEEK=$1 #################################################################### # # This is a wrapper routine. Don't put jobs here. Instead, put # them in one of the subordinate routines. # #################################################################### RunWeeklyJobs } ###################################################################### # # RunWeeklyJobs # ###################################################################### RunWeeklyJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # RunOneShotJobs "" # ###################################################################### RunOneShotJobs() { MY_WEEK=$1 #################################################################### # # If it's our time, execute the jobs specified below. # #################################################################### MY_TARGET_WEEK="WW" # REPLACE WITH THE TARGET WEEK (00-53) if [ "${MY_WEEK}"X = "${MY_TARGET_WEEK}"X ] ; then ################################################################## # # Common jobs. # ################################################################## : # REPLACE WITH ONE OR MORE COMMON JOBS ################################################################## # # Custom jobs. # ################################################################## for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done fi } ###################################################################### # # DeployFile # ###################################################################### DeployFile() { MY_CFG_FILE=$1 MY_PAD_FILE=$2 MY_TARGET_PATH=$3 # Full path including filename. MY_TARGET_MODE=$4 MY_TARGET_OWNER=$5 MY_TARGET_GROUP=$6 MY_CP_CMD="{ cp %payload ${MY_TARGET_PATH} ; }" MY_CHMOD_CMD="{ chmod ${MY_TARGET_MODE} ${MY_TARGET_PATH} ; }" MY_CHOWN_CMD="{ chown ${MY_TARGET_OWNER}:${MY_TARGET_GROUP} ${MY_TARGET_PATH} ; }" MY_RM_CMD="{ rm -f %payload ; }" MY_ID=`id | sed 's/^uid=\([0-9]\{1,5\}\)(.*$/\1/;'` if [ "${MY_ID}"X = "0"X ] ; then MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} && ${MY_CHOWN_CMD} } ; ${MY_RM_CMD}" else MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} } ; ${MY_RM_CMD}" fi if [ ! -f ${MY_TARGET_PATH} ] ; then webjob -e -f ${MY_CFG_FILE} ${MY_PAD_FILE} ${MY_PAD_CMD} fi } ###################################################################### # # DeployAll # ###################################################################### DeployAll() { #################################################################### # # Deployment jobs. This area is for jobs that deploy files to the # client (e.g., programs and config files). All jobs specified # here should call DeployFile() with the appropriate arguments. # #################################################################### : # REPLACE WITH ONE OR MORE DEPLOY JOBS } ###################################################################### # # UpdateFile # ###################################################################### UpdateFile() { MY_CFG_FILE=$1 MY_PAD_FILE=$2 MY_TARGET_PATH=$3 # Full path including filename. MY_TARGET_MODE=$4 MY_TARGET_OWNER=$5 MY_TARGET_GROUP=$6 MY_TARGET_HASH=$7 MY_DIGEST_TYPE=$8 # (MD5|SHA1) MY_CP_CMD="{ cp -f %payload ${MY_TARGET_PATH} ; }" MY_CHMOD_CMD="{ chmod ${MY_TARGET_MODE} ${MY_TARGET_PATH} ; }" MY_CHOWN_CMD="{ chown ${MY_TARGET_OWNER}:${MY_TARGET_GROUP} ${MY_TARGET_PATH} ; }" MY_RM_CMD="{ rm -f %payload ; }" MY_ID=`id | sed 's/^uid=\([0-9]\{1,5\}\)(.*$/\1/;'` if [ "${MY_ID}"X = "0"X ] ; then MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} && ${MY_CHOWN_CMD} } ; ${MY_RM_CMD}" else MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} } ; ${MY_RM_CMD}" fi if [ -f ${MY_TARGET_PATH} ] ; then MY_ACTUAL_HASH=`webjob -h -t ${MY_DIGEST_TYPE} ${MY_TARGET_PATH}` if [ "${MY_ACTUAL_HASH}" != "${MY_TARGET_HASH}" ] ; then webjob -e -f ${MY_CFG_FILE} ${MY_PAD_FILE} ${MY_PAD_CMD} fi fi } ###################################################################### # # UpdateAll # ###################################################################### UpdateAll() { #################################################################### # # Update jobs. This area is for jobs that update files that already # exist on the client (e.g., programs and config files). All jobs # specified here should call UpdateFile() with the appropriate # arguments. # #################################################################### : # REPLACE WITH ONE OR MORE UPDATE JOBS #################################################################### # # To update webjob using webjob, uncomment the following line, and # set the arguments as necessary. The webjob-update-client script, # must be deployed on the WebJob server for UpdateWebJob() to work # as intended. # #################################################################### # UpdateWebJob "${WEBJOB_HOME}" "755" "root" "wheel" "X.X.X" "00000000000000000000000000000000" "md5" } ###################################################################### # # UpdateWebJob # ###################################################################### UpdateWebJob() { MY_TARGET_HOME=$1 MY_TARGET_MODE=$2 MY_TARGET_OWNER=$3 MY_TARGET_GROUP=$4 MY_TARGET_VERSION=$5 MY_TARGET_HASH=$6 MY_DIGEST_TYPE=$7 # (MD5|SHA1) MY_TARGET_PATH=${MY_TARGET_HOME}/bin/webjob if [ -f ${MY_TARGET_PATH} ] ; then MY_ACTUAL_HASH=`webjob -h -t ${MY_DIGEST_TYPE} ${MY_TARGET_PATH}` if [ "${MY_ACTUAL_HASH}" != "${MY_TARGET_HASH}" ] ; then webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg webjob-update-client -H ${MY_TARGET_HOME} -m ${MY_TARGET_MODE} -u ${MY_TARGET_OWNER} -g ${MY_TARGET_GROUP} -v ${MY_TARGET_VERSION} fi fi } ###################################################################### # # Usage # ###################################################################### Usage() { echo 1>&2 echo "Usage: ${PROGRAM} [-H webjob-home]" 1>&2 echo 1>&2 exit 1 } ###################################################################### # # Main # ###################################################################### while getopts "H:" OPTION ; do case "${OPTION}" in H) WEBJOB_HOME="${OPTARG}" ;; *) Usage ;; esac done if [ ${OPTIND} -le $# ] ; then Usage fi PATH=${PATH}:${WEBJOB_HOME=/usr/local/webjob}/bin WEEK=`date "+%U"` PROCESSOR=`uname -p` DeployAll UpdateAll RunRegularJobs "${WEEK}" RunOneShotJobs "${WEEK}" --- weekly --- Appendix 4 --- monthly --- #!/bin/sh ###################################################################### # # $Id: monthly,v 1.8 2007/10/03 21:46:46 klm Exp $ # ###################################################################### # # Copyright 2003-2007 The WebJob Project, All Rights Reserved. # ###################################################################### # # Purpose: Periodically (monthly) run common administrative tasks. # ###################################################################### IFS=' ' PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin PROGRAM=`basename $0` HOSTNAME=`hostname | awk -F. '{print $1}'` ###################################################################### # # GetHostGroups # ###################################################################### GetHostGroups() { #################################################################### # # To associate a client with a particular group, add it's hostname # to the appropriate list. If you want to add a new group, then # make sure you update MY_GROUPS. Note: fully qualified hostnames # aren't supported by this implementation. # #################################################################### MY_GROUP1="" MY_GROUP2="" MY_GROUPS="MY_GROUP1 MY_GROUP2" #################################################################### # # Figure out which groups this host belongs to. # #################################################################### MY_HOST=`hostname | awk -F. '{print $1}'` MY_LIST="" for GROUP in ${MY_GROUPS} ; do eval HOSTS=\$${GROUP} for HOST in ${HOSTS} ; do if [ "${HOST}"X = "${MY_HOST}"X ] ; then MY_LIST="${MY_LIST} ${GROUP}" fi done done echo ${MY_LIST} } ###################################################################### # # RunRegularJobs "" # ###################################################################### RunRegularJobs() { MY_MONTH=$1 #################################################################### # # This is a wrapper routine. Don't put jobs here. Instead, put # them in one of the subordinate routines. # #################################################################### RunMonthlyJobs } ###################################################################### # # RunMonthlyJobs # ###################################################################### RunMonthlyJobs() { #################################################################### # # Common jobs. This area is for jobs that should be executed by all # clients. # #################################################################### : # REPLACE WITH ONE OR MORE COMMON JOBS #################################################################### # # Custom jobs. This area is for jobs that should be executed by all # clients belonging to one of the pre-defined groups. Group members # are listed by hostname. # #################################################################### for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done } ###################################################################### # # RunOneShotJobs "" # ###################################################################### RunOneShotJobs() { MY_MONTH=$1 #################################################################### # # If it's our time, execute the jobs specified below. # #################################################################### MY_TARGET_MONTH="MM" # REPLACE WITH THE TARGET MONTH (01-12) if [ "${MY_MONTH}"X = "${MY_TARGET_MONTH}"X ] ; then ################################################################## # # Common jobs. # ################################################################## : # REPLACE WITH ONE OR MORE COMMON JOBS ################################################################## # # Custom jobs. # ################################################################## for GROUP in `GetHostGroups` ; do case "${GROUP}" in MY_GROUP1) : # REPLACE WITH ONE OR MORE MY_GROUP1 JOBS ;; MY_GROUP2) : # REPLACE WITH ONE OR MORE MY_GROUP2 JOBS ;; esac done fi } ###################################################################### # # DeployFile # ###################################################################### DeployFile() { MY_CFG_FILE=$1 MY_PAD_FILE=$2 MY_TARGET_PATH=$3 # Full path including filename. MY_TARGET_MODE=$4 MY_TARGET_OWNER=$5 MY_TARGET_GROUP=$6 MY_CP_CMD="{ cp %payload ${MY_TARGET_PATH} ; }" MY_CHMOD_CMD="{ chmod ${MY_TARGET_MODE} ${MY_TARGET_PATH} ; }" MY_CHOWN_CMD="{ chown ${MY_TARGET_OWNER}:${MY_TARGET_GROUP} ${MY_TARGET_PATH} ; }" MY_RM_CMD="{ rm -f %payload ; }" MY_ID=`id | sed 's/^uid=\([0-9]\{1,5\}\)(.*$/\1/;'` if [ "${MY_ID}"X = "0"X ] ; then MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} && ${MY_CHOWN_CMD} } ; ${MY_RM_CMD}" else MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} } ; ${MY_RM_CMD}" fi if [ ! -f ${MY_TARGET_PATH} ] ; then webjob -e -f ${MY_CFG_FILE} ${MY_PAD_FILE} ${MY_PAD_CMD} fi } ###################################################################### # # DeployAll # ###################################################################### DeployAll() { #################################################################### # # Deployment jobs. This area is for jobs that deploy files to the # client (e.g., programs and config files). All jobs specified # here should call DeployFile() with the appropriate arguments. # #################################################################### : # REPLACE WITH ONE OR MORE DEPLOY JOBS } ###################################################################### # # UpdateFile # ###################################################################### UpdateFile() { MY_CFG_FILE=$1 MY_PAD_FILE=$2 MY_TARGET_PATH=$3 # Full path including filename. MY_TARGET_MODE=$4 MY_TARGET_OWNER=$5 MY_TARGET_GROUP=$6 MY_TARGET_HASH=$7 MY_DIGEST_TYPE=$8 # (MD5|SHA1) MY_CP_CMD="{ cp -f %payload ${MY_TARGET_PATH} ; }" MY_CHMOD_CMD="{ chmod ${MY_TARGET_MODE} ${MY_TARGET_PATH} ; }" MY_CHOWN_CMD="{ chown ${MY_TARGET_OWNER}:${MY_TARGET_GROUP} ${MY_TARGET_PATH} ; }" MY_RM_CMD="{ rm -f %payload ; }" MY_ID=`id | sed 's/^uid=\([0-9]\{1,5\}\)(.*$/\1/;'` if [ "${MY_ID}"X = "0"X ] ; then MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} && ${MY_CHOWN_CMD} } ; ${MY_RM_CMD}" else MY_PAD_CMD="{ ${MY_CP_CMD} && ${MY_CHMOD_CMD} } ; ${MY_RM_CMD}" fi if [ -f ${MY_TARGET_PATH} ] ; then MY_ACTUAL_HASH=`webjob -h -t ${MY_DIGEST_TYPE} ${MY_TARGET_PATH}` if [ "${MY_ACTUAL_HASH}" != "${MY_TARGET_HASH}" ] ; then webjob -e -f ${MY_CFG_FILE} ${MY_PAD_FILE} ${MY_PAD_CMD} fi fi } ###################################################################### # # UpdateAll # ###################################################################### UpdateAll() { #################################################################### # # Update jobs. This area is for jobs that update files that already # exist on the client (e.g., programs and config files). All jobs # specified here should call UpdateFile() with the appropriate # arguments. # #################################################################### : # REPLACE WITH ONE OR MORE UPDATE JOBS #################################################################### # # To update webjob using webjob, uncomment the following line, and # set the arguments as necessary. The webjob-update-client script, # must be deployed on the WebJob server for UpdateWebJob() to work # as intended. # #################################################################### # UpdateWebJob "${WEBJOB_HOME}" "755" "root" "wheel" "X.X.X" "00000000000000000000000000000000" "md5" } ###################################################################### # # UpdateWebJob # ###################################################################### UpdateWebJob() { MY_TARGET_HOME=$1 MY_TARGET_MODE=$2 MY_TARGET_OWNER=$3 MY_TARGET_GROUP=$4 MY_TARGET_VERSION=$5 MY_TARGET_HASH=$6 MY_DIGEST_TYPE=$7 # (MD5|SHA1) MY_TARGET_PATH=${MY_TARGET_HOME}/bin/webjob if [ -f ${MY_TARGET_PATH} ] ; then MY_ACTUAL_HASH=`webjob -h -t ${MY_DIGEST_TYPE} ${MY_TARGET_PATH}` if [ "${MY_ACTUAL_HASH}" != "${MY_TARGET_HASH}" ] ; then webjob -e -f ${WEBJOB_HOME}/etc/upload.cfg webjob-update-client -H ${MY_TARGET_HOME} -m ${MY_TARGET_MODE} -u ${MY_TARGET_OWNER} -g ${MY_TARGET_GROUP} -v ${MY_TARGET_VERSION} fi fi } ###################################################################### # # Usage # ###################################################################### Usage() { echo 1>&2 echo "Usage: ${PROGRAM} [-H webjob-home]" 1>&2 echo 1>&2 exit 1 } ###################################################################### # # Main # ###################################################################### while getopts "H:" OPTION ; do case "${OPTION}" in H) WEBJOB_HOME="${OPTARG}" ;; *) Usage ;; esac done if [ ${OPTIND} -le $# ] ; then Usage fi PATH=${PATH}:${WEBJOB_HOME=/usr/local/webjob}/bin MONTH=`date "+%m"` PROCESSOR=`uname -p` DeployAll UpdateAll RunRegularJobs "${MONTH}" RunOneShotJobs "${MONTH}" --- monthly --- Appendix 5 --- s_hlc_any --- #!/bin/sh ###################################################################### # # $Id: s_hlc_any,v 1.2 2008/02/20 04:49:14 klm Exp $ # ###################################################################### # # Copyright 2003-2004 The WebJob Project, All Rights Reserved. # ###################################################################### # # Purpose: Strip s_hlc_ prefix and run the resulting command. # ###################################################################### IFS=' ' PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin ORIGINAL_COMMAND=`basename $0` QTAG_REGEX="[ps][0-9][0-9][0-9]*_[0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9]_[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]" MODIFIED_COMMAND=`echo ${ORIGINAL_COMMAND} | sed "s/^s_hlc_//; s/^${QTAG_REGEX}_s_hlc_//;"` if [ -z "${MODIFIED_COMMAND}" -o "${MODIFIED_COMMAND}" = "${ORIGINAL_COMMAND}" ] ; then echo "${ORIGINAL_COMMAND}: Command substitution failed. Make sure the script's name prefix is 's_hlc_'." 1>&2 exit 2 fi if [ "${NOEXEC}" = "1" ] ; then if [ -z "$*" ] ; then echo "Command='${MODIFIED_COMMAND}'" else echo "Command='${MODIFIED_COMMAND} $*'" fi exit 0 fi exec ${MODIFIED_COMMAND} $* # The exec ensures that the pid stays the same. --- s_hlc_any --- Appendix 6 --- s_cat_any --- #!/bin/sh ###################################################################### # # $Id: s_cat_any,v 1.2 2008/02/20 04:49:14 klm Exp $ # ###################################################################### # # Copyright 2003-2004 The WebJob Project, All Rights Reserved. # ###################################################################### # # Purpose: Strip s_cat_ prefix, convert name to a relative path, and # cat the resulting file. # ###################################################################### IFS=' ' PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin ORIGINAL_FILENAME=`basename $0` QTAG_REGEX="[ps][0-9][0-9][0-9]*_[0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9]_[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]" MODIFIED_FILENAME=`echo ${ORIGINAL_FILENAME} | sed "s,^s_cat_,,; s,^${QTAG_REGEX}_s_cat_,,; s,___,/,g;"` if [ -z "${MODIFIED_FILENAME}" ] ; then echo "${ORIGINAL_FILENAME}: Filename substitution failed." 1>&2 exit 2 fi if [ "${MODIFIED_FILENAME}" = "any" ] ; then cat $* else cd ${PREFIX-/} && cat ${MODIFIED_FILENAME} fi --- s_cat_any --- Appendix 7 --- s_tar_any --- #!/bin/sh ###################################################################### # # $Id: s_tar_any,v 1.2 2008/02/20 04:49:14 klm Exp $ # ###################################################################### # # Copyright 2003-2007 The WebJob Project, All Rights Reserved. # ###################################################################### # # Purpose: Strip s_tar_ prefix, convert name to a relative path, and # tar up resulting file/directory. # ###################################################################### IFS=' ' PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin ORIGINAL_FILENAME=`basename $0` QTAG_REGEX="[ps][0-9][0-9][0-9]*_[0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9]_[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]" MODIFIED_FILENAME=`echo ${ORIGINAL_FILENAME} | sed "s,^s_tar_,,; s,^${QTAG_REGEX}_s_tar_,,; s,___,/,g;"` if [ -z "${MODIFIED_FILENAME}" ] ; then echo "${ORIGINAL_FILENAME}: Filename substitution failed." 1>&2 exit 2 fi if [ "${MODIFIED_FILENAME}" = "any" ] ; then tar -cf - $* else cd ${PREFIX-/} && tar -cf - ${MODIFIED_FILENAME} fi --- s_tar_any ---