cat brain.log | less

Getting it down on `paper`

Code Deployment Utility

Problem: Code runs on some local machine, but this machine is unreliable. The code MUST run, and it must be run during a certain time frame. Since we cannot trust our single machine to execute the code, we must deploy the code to multiple machines. However, we don’t want to execute the code twice. The code is resource intensive and utilizes a 3rd party API that we must pay per use for. If the code runs on one machine, that’s sufficient and there’s no need to run the backup instance. However, if the primary machine is down, we must execute on the backup. Any output generated by the scripts must be synced to the master once it comes back online.

I didn’t take the time to write this… but if I did, this would be the interface.

Usage:

deploy [-oidC] [-s <config section>] [-c <cron file>] \
       [-f <config file>] <srcdir> [[user@]host[:dstpath]]
 -o: overwrite. Destination is removed before replacement.
 -i: interactive. Confirm before each step.
 -d: delete. Undeploy a specified deployment.
 -s: section title. Use this config section's settings.
 -f: config file. Specify an ini other than config.ini
 -c: cron file. Specify a file other than cron.tab
 -C: do not (un)deploy the cron tab.

// Scan for config, cron files
// Interpolate paths (see examples. eg: ${www})
// Build file manifest, config section -> FQDN of target host
// Generate target config.ini. global block: __deployed__
// *Confirm files will not be overwritten
// *Confirm files exist for delete

—————————————————————-
Use Cases:

$ deploy code example.com:~/dev/code

>> Copy the contents of ./code to server example.com.
>> Current user’s ${HOME} on remote system, ~/dev/code.

Ambiguity:

cp code  ~/dev/code  (remote exists) -> FAIL
cp code  ~/dev/code/ (remote exists) -> ~/dev/code/code/config.ini
cp code  ~/dev/code  (remote DNE)    -> ~/dev/code/config.ini
cp code  ~/dev/code/ (remote DNE)    -> ~/dev/code/config.ini
cp code  ~/dev  (remote exists) -> FAIL
cp code  ~/dev/ (remote exists) -> ~/dev/code/config.ini
cp code  ~/dev  (remote DNE)    -> ~/dev/config.ini
cp code  ~/dev/ (remote DNE)    -> ~/dev/config.ini
$ deploy -o code example.com:~/dev/code
$ deploy -d code example.com:~/dev/code
$ deploy -o -f code/alt.ini code example.com:~/dev/code
$ deploy -c code/alt.cron code example.com:~/dev/code
$ deploy code -s 'dev.example.com' example.com
$ deploy code example.com
$ deploy -d code example.com
$ deploy -C code example.com

—————————————————————-
Example CRON:

0 0 * * * php -q ${www}/script.php >/dev/null
5 * * * * ${bin}/up2date.sh </dev/null >${log}/up2date.log

—————————————————————-
Example INI:

[example.com]
ROOT=/home/example/deployments/ex1
www=/var/www/html/ex1
log=/var/log/ex1
lock=/var/lock/ex1

[dev.example.com]
ROOT=/home/example/dev/ex1
www=/var/www/html/ex1-dev
;log=/var/log/ex1 -> ${ROOT}/log
;lock=/var/lock/ex1 -> ${ROOT}/lock

—————————————————————-
:: deploy_cron.sh <deploy_id> [<cron.tab>] ::

#!/bin/bash

if [[ $# -lt 1 ]]; then
  echo "Usage: $0 <deploy_id> [<cron.tab>]"
  exit
fi
DEPLOY_ID=$1

CRON_FILE=cron.tab
if [[ $# -gt 1 ]]; then
  CRON_FILE=$2
fi

if [[ ! -e "${CRON_FILE}" ]]; then
  echo "File not found: ${CRON_FILE}"
  exit
fi


export CRONTAB_NOHEADER=N
crontab -l | sed 1,+2d > .cron.tab.tmp

echo "##### BEGIN: ${DEPLOY_ID} #####" >> .cron.tab.tmp
cat ${CRON_FILE} >> .cron.tab.tmp
echo "##### END: ${DEPLOY_ID} #####" >> .cron.tab.tmp

crontab .cron.tab.tmp
rm .cron.tab.tmp
unset CRONTAB_NOHEADER

—————————————————————-
:: undeploy_cron.sh <deploy_id> ::

#!/bin/bash

if [[ $# -lt 1 ]]; then
  echo "Usage: $0 <deploy_id>"
  exit
fi
DEPLOY_ID=$1

export CRONTAB_NOHEADER=N
CMD="/^##### BEGIN: ${DEPLOY_ID} #####\$/,/^##### END: ${DEPLOY_ID} #####\$/ d"
crontab -l | sed 1,+2d | sed "${CMD}" > .cron.tab.tmp

crontab .cron.tab.tmp
rm .cron.tab.tmp
unset CRONTAB_NOHEADER
 

Comments

No comments so far.

(comments are closed)