developers have sandboxes with code checked out from svn. they develop code there. once it’s good, they check code in and then update the staging server with that new code. it’s tested there by QA. once QA signs off, then those specific files are pushed out to the production servers by the release manager by running the pshfiles.sh script. the script pushes to one or all servers, emails the dev team, logs the push, checks the servers afterwards for health and clears the zend cache.
[deployer@staging ~]$ cat pshfiles.sh
#!/bin/bash
if [ "$1" == '' ]; then
echo "Usage: pshfiles.sh [file_name_with_files_in_it] [server_name]"
else
SERVER=$2
if [ "$SERVER" == "all" ]; then
SERVERLIST=( web1 web2 web3 )
else
SERVERLIST=( $SERVER )
fi
for SERVER in ${SERVERLIST[@]}
do
while read line; do
echo "psh $line $SERVER"
pshonenocache $line $SERVER
done < $1
done
FILESPUSHED=`cat $1`
sendEmail.pl -s smtp.example.com -f deployer@example.com -m "these files were pushed: \n $FILESPUSHED" -xu deployer@example.com -t devteam@example.com -xp password -u "Code pushed to $2"
echo "Clear Zend cache?"
read ZEND
if [ "$ZEND" == "y" ] || [ "$ZEND" == "Y" ]; then
/usr/bin/clroptcache $2
fi
fi
where pshonenocache is:
[deployer@staging ~]# cat /usr/bin/pshonenocache
#!/bin/bash
TODAY=`date '+%Y-%m-%d %H:%M'`
if [ "$1" == '' ]; then
echo -n "Which File?"
read -e FILENAME
else
FILENAME=$1
fi
if [ "$2" == '' ]; then
echo -n "Which Server? (web1,web2,web3,all) : "
read -e SERVER
else
SERVER=$2
fi
if [ "$SERVER" == "all" ]; then
SERVERLIST=( web1 web2 web3 )
else
SERVERLIST=( $SERVER )
fi
for SERVER in ${SERVERLIST[@]}
do
if [ -e $FILENAME ]; then
echo -e "$TODAY: Company SOURCE Update ONE FILE: \tscp $FILENAME deployer@$SERVER:$FILENAME" | tee -a ~/updateLogs/$SERVER-updates.log
scp $FILENAME deployer@$SERVER:$FILENAME
fi
done
/usr/bin/checkwebservers
where checkwebservers is:
[deployer@staging~]$ cat /usr/bin/checkwebservers
#!/bin/bash
echo -n "Checking Web Servers after PSH: "
SERVERSTATUS=`wget -qO- http://example.com/checkServersStatus.html|grep "All is Well"|wc -l`
DETAILEDSTATUS=`wget -qO- http://example.com/checkServersStatus.html`
if [ "$SERVERSTATUS" != "1" ]; then
echo "CRITICAL - one of the web servers isn't well: $DETAILEDSTATUS"
else
echo "OK - The webservers look good"
fi
and clroptcache is
[deployer@staging ~]# cat /usr/bin/clroptcache
#!/bin/bash
if [ "$1" == '' ]; then
echo -n "Which Server?( web1,web2,web3,all) : "
read -e SERVER
else
SERVER=$1
fi
if [ "$SERVER" == "all" ]; then
SERVERLIST=( web1 web2 web3 )
else
SERVERLIST=( $SERVER )
fi
for SERVER in ${SERVERLIST[@]}
do
echo -e "Clearing Zend Optimizer Cache on $SERVER \n"
if [ "$SERVER" == "web1" ]; then
wget -qO- http://10.10.10.1/cacheclear.php | cat
fi
if [ "$SERVER" == "web2" ]; then
wget -qO- http://10.10.10.2/cacheclear.php | cat
fi
if [ "$SERVER" == "web3" ]; then
wget -qO- http://10.10.10.3/cacheclear.php | cat
fi
done
sometimes (rarely) you might want to push ALL files. then you use the psh script:
[deployer@server ~]# cat /usr/bin/psh
#!/bin/bash
TODAY=`date '+%Y-%m-%d %H:%M'`
if [ "$1" == '' ]; then
echo -n "Which Server? (web1,web2,web3,all) : "
read -e SERVER
else
SERVER=$1
fi
echo "run PHP Lint check first? (on files modified during last X days?)"
read -e LINT
if [ "$LINT" == "y" ] || [ "$LINT" == "Y" ]; then
echo "how many days?"
read DAYS
cd /classes && find -name "*.php" -mtime -$DAYS -exec /usr/local/zend/bin/php -l {} \;
fi
if [ "$SERVER" == "all" ]; then
SERVERLIST=( web1 web2 web3 )
else
SERVERLIST=( $SERVER )
fi
for SERVER in ${SERVERLIST[@]}
do
echo -e "$TODAY: Company SOURCE Update:" | tee -a ~/updateLogs/$SERVER-updates.log
echo "Updating $SERVER..." | tee -a ~/updateLogs/$SERVER-updates.log
echo "Command DRY Run:" | tee -a ~/updateLogs/$SERVER-updates.log
rsync -avczne ssh /classes/ $SERVER:/classes/ --links --exclude-from "/home/deployer/rsync_exclude.txt" | tee -a ~/updateLogs/$SERVER-updates.log
rsync -avczne ssh /var/www/ $SERVER:/var/www/ --links --exclude-from "/home/deployer/rsync_exclude.txt" | tee -a ~/updateLogs/$SERVER-updates.log
echo -n "Press Y to Accept This Change : "
read dec
if [ "$dec" == "Y" ]; then
rsync -avcze ssh /classes/ $SERVER:/classes/ --links --exclude-from "/home/deployer/rsync_exclude.txt" | tee -a ~/updateLogs/$SERVER-updates.log
rsync -avcze ssh /var/www/ $SERVER:/var/www/ --links --exclude-from "/home/deployer/rsync_exclude.txt" | tee -a ~/updateLogs/$SERVER-updates.log
else
echo 'Command NOT Accepted' | tee -a ~/updateLogs/$SERVER-updates.log
fi
echo "Done!" | tee -a ~/updateLogs/$SERVER-updates.log
done
echo "Clear Zend cache?"
read ZEND
if [ "$ZEND" == "y" ] || [ "$ZEND" == "Y" ]; then
/usr/bin/clroptcache $1
fi
/usr/bin/checkwebservers
what’s next? well, it would be nice to be able to revert pushes quickly. so perhaps taking a backup right before would be handy. otherwise, you have to rollback the svn commit and repush.