#!/bin/bashgit
#####################################################################github
# Description: Automation Deployment Script vim
# Netkiller series utilitiesbash
# Author: Neo<netkiller@msn.com>dom
# Homepage: http://netkiller.github.com/ssh
# http://netkiller.sourceforge.net/ide
# GIT URL: https://github.com/netkiller/deployment.gitsvn
# $Id$url
#####################################################################.net
# :set tabstop=4
# :set shiftwidth=4
# :set expandtab
if [ -z $DEPLOY_HOME ]; then
echo 'Example: export DEPLOY_HOME=/srv/deploy'
exit
fi
if [ -f $DEPLOY_HOME/conf/default.conf ];then
. $DEPLOY_HOME/conf/default.conf
fi
if [ -f $DEPLOY_HOME/conf/stage.conf ];then
. $DEPLOY_HOME/conf/stage.conf
fi
#================================================================================
LOGFILE="deploy.$(date -d "today" +"%Y-%m-%d").log"
TMPDIR=$(mktemp -d --suffix=.tmp -p /tmp deploy.XXXXXX)
SVN=/usr/bin/svn
GIT=/usr/bin/git
BACKUPDIR=/backup
RSYNC="rsync"
UPLOAD_DIR=$TMPDIR
REVISION=''
DEBUG='yes'
# development production testing
if [ -z $STAGE ]; then
echo 'Example: touch conf/stage.conf'
echo "STAGE='development' or STAGE='testing' or STAGE='production'"
exit
fi
#================================================================================
if [ ! -d ${TMPDIR} ]; then
mkdir ${TMPDIR}
fi
#chmod 700 -R ${SRCDIR}/*
umask 0077
#pkgname=${project}-${version}-${datetime}.pkg
#tar jcvf ${pkgname} /tmp/${project} --remove-files >> deploy.log
#####################################################################
function logging(){
local logfile="$LOGDIR/$LOGFILE"
local timepoint=$(date -d "today" +"%Y-%m-%d %H:%M:%S")
local status=$1
local message=$2
echo "[$timepoint] [${status}] ${message}" >> $logfile
}
function debug(){
if [ ${DEBUG} = 'yes' ]; then
local logfile="$LOGDIR/debug.log"
local timepoint=$(date -d "today" +"%Y-%m-%d %H:%M:%S")
local status=$1
local message=$2
echo "[$timepoint] [${status}] ${message}" >> $logfile
fi
}
#logging 'OK' 'This is test msg!!!'
#debug 'OK' 'This is debug msg!!!'
function conf(){
local cmd=$2
local prj=$3
case $cmd in
list)
ls $SYSCONFDIR/*/*
;;
new)
mkdir -p $SYSCONFDIR
#if [ ! -d ${BACKUPDIR} ]; then
# mkdir -p $BACKUPDIR
#fi
read -p "Project directory: " prjdir
if [ -z $prjdir ]; then
exit
fi
if [ -f $SYSCONFDIR/$prjdir.conf ]; then
echo "cannot create config $prjdir.conf': File exists"
exit 1
fi
read -p "subversion url: $REPOSITORIES/: " svnurl
if [ -z $svnurl ]; then
svnurl=$REPOSITORIES
fi
read -p "hostname: " host
if [ -z $host ]; then
host="localhost"
echo "default hostname 'localhost'"
fi
read -p "upload mode ftp/scp/sftp/rsync: " mode
if [ -z $mode ]; then
mode=ftp
else
case $mode in
ftp)
mode="ftpdeploy"
;;
scp)
mode="scpdeploy"
;;
sftp)
mode="sftpdeploy"
;;
rsync)
mode="rsync"
;;
esac
fi
read -p "Create $prjdir config? [y/n]" -n 1 key
echo
if [ $key = 'y' ]; then
echo -ne "REPOSITORIES=$REPOSITORIES/$svnurl
COMMAND=$mode
HOSTNAME=$host
" >> $SYSCONFDIR/$prjdir.conf
fi
;;
remove)
if [ -f $SYSCONFDIR/$prj ]; then
rm -rf $SYSCONFDIR/$prj
fi
;;
show)
cat $SYSCONFDIR/$prj
;;
edit)
vim $SYSCONFDIR/$prj
;;
*)
ls $SYSCONFDIR/*/*
;;
esac
}
#####################################################################
function config {
local cfg=$1
exclude_from=$PREFIX/exclude/${cfg}.lst
include_from=$PREFIX/include/${cfg}.lst
if [ -f $SYSCONFDIR/${STAGE}/${cfg}.conf ];then
. $SYSCONFDIR/${STAGE}/${cfg}.conf
else
echo "Please provide the config($SYSCONFDIR/${STAGE}/${cfg}.conf) to deploy!"
exit
fi
if [ -z "$cfg" ]; then
echo "Please provide the path for deploy!"
exit
fi
if [ ! -f $exclude_from ]; then
echo "Please provide a list of excluded in the $exclude_from."
touch $exclude_from
exit
fi
if [ ! -f $include_from ]; then
echo "Please provide a list of included in the $include_from."
touch $include_from
exit
fi
# case ${STAGE} in
# development)
# SUBVERSION='development'
# ;;
# testing)
# SUBVERSION=''
# ;;
# production)
# ;;
# *)
# SUBVERSION='current'
# ;;
# esac
}
function deploy() {
local domain=$2
local host=$3
local commit=$4
local logfile=${LOGDIR}/${host}.${domain}.log
local backupdir=${BACKUPDIR}/${host}.${domain}/$(date '+%Y-%m-%d/%H:%M:%S')
local message=${STAGE}/${domain}/${host}.${domain}
if [ $# -lt 3 ]; then
usage
fi
if [ ${STAGE} = 'production' ]; then
read -p "Are you sure you want to continue deploying? [y/n]" -n 1 key
echo
if [ $key != 'y' ]; then
exit
fi
fi
if [ $host = 'all' ]; then
for h in $(ls -1 $SYSCONFDIR/${STAGE}/$domain/ | cut -d. -f1)
do
/bin/sh $BINDIR/deploy.git ${STAGE} $domain $h
done
exit
fi
#if [ ! -z $revision ]; then
# REVISION="-r ${revision}"
#fi
config ${domain}/${host}
project=$SRCDIR/${STAGE}/${domain}/${host}.${domain}
GIT_OPTS=${REVISION}
echo '================================================================================'
if [ -d ${project} ]; then
cd $project
#$GIT stash
#$GIT pull --progress
#$GIT stash clear
#$GIT checkout .
$GIT reset HEAD --hard >> $logfile
echo -n " Repository: ${REPOSITORY} "
$GIT pull --progress
if [ ! -z $commit ]; then
$GIT checkout $commit .
echo " Commit: $commit"
logging 'checkout' "commit:$commit ${project} "
else
logging 'update' ${project}
fi
else
mkdir -p ${project}
$GIT clone ${REPOSITORY} ${project} >> $logfile
logging 'checkout' ${project}
fi
echo '================================================================================'
RSYNC_OPTS=" -azv --backup --backup-dir=${backupdir} --exclude=.git --log-file=${logfile} --exclude-from=$exclude_from --include-from=$include_from"
if [ -d ${SHAREDIR}/${STAGE}/${domain}/${host}/ ]; then
cp -a ${SHAREDIR}/${STAGE}/${domain}/${host}/* ${project}/
fi
echo '- share:' >> ${logfile}
echo ' Share [ OK ]'
if [ -f ${LIBEXECDIR}/${domain}/${host}/before ];then
/bin/sh ${LIBEXECDIR}/${domain}/${host}/before >> ${logfile}
fi
echo '- libexec:' >> ${logfile}
echo ' Libexec [ OK ]'
find $SRCDIR/* -type f -name "Thumbs.db" -exec rm -rf {} \;
echo '================================================================================'
for addr in ${REMOTE}
do
echo " Deploy [${message}] ${addr}"
echo '================================================================================'
case ${MODE} in
FTP)
ftpdeploy
;;
SCP)
scp -ar ${project}/* ${addr}:${DESTINATION}
;;
SFTP)
sftpdeploy
;;
RSYNC)
$RSYNC $RSYNC_OPTS $OPTION ${project}/* ${addr}::${DESTINATION}
debug 'rsync' "$RSYNC $RSYNC_OPTS $OPTION ${project}/* ${addr}::${DESTINATION}"
;;
"RSYNC+SSH")
$RSYNC $RSYNC_OPTS ${project}/* ${addr}:${DESTINATION}
;;
esac
if [ -z "${REVISION}" ]; then
logging 'deploy' "${message} => ${addr}:${DESTINATION}"
else
logging 'revert' "${message} => ${addr}:${DESTINATION}"
fi
echo '--------------------------------------------------' >> ${logfile}
done
if [ -f ${LIBEXECDIR}/${domain}/${host}/after ];then
#ssh ${scp} < ${LIBEXECDIR}/${domain}/${host}/after
exit
fi
}
function revert() {
#if [ $STAGE = 'testing' -o $STAGE = 'development' -o $STAGE = 'production' ]; then
local domain=$3
local host=$4
local commit=$5
# else
# local domain=$1
# local host=$2
# local revision=$3
#fi
deploy $STAGE $domain $host $commit
}
function timepoint {
TIMEPOINT=`date '+%Y-%m-%d.%H-%M-%S'`
echo $TIMEPOINT >> timepoint.log
}
function unstable {
local edition=$(basename $unstable)
svn export ${unstable} ${src}/$edition
for ignore in $( cat excluded.lst ); do
rm -rf ${src}/$edition/$ignore
done
$RSYNC ${src}/$edition ${destination}
ssh ${remote} < script/unstable
}
function clean() {
local stage=$2
local domain=$3
local host=$4
local project=$SRCDIR/${stage}/${domain}/$host.${domain}
if [ $# -lt 3 ]; then
usage
fi
rm -rf ${project}
}
function list {
local domain=$2
local host=$3
local dir=$4
if [ -z $domain ]; then
ls $SRCDIR/*
exit
fi
if [ -z $host ]; then
usage
fi
#config ${domain}/${host}
ls $SRCDIR/*/${domain}/${host}.${domain}
#git ls ${REPOSITORIES}/$dir #| awk -F '/' '{print $1}'
}
function backup() {
local domain=$2
local host=$3
local dir=$4
local logfile=${LOGDIR}/${host}.${domain}.log
if [ -z $domain ]; then
usage
fi
if [ -z $host ]; then
usage
fi
config ${domain}/${host}
if [ -z $dir ]; then
dir=$TMPDIR
fi
for addr in ${REMOTE}
do
dir=$dir/${addr}
if [ ! -d ${dir} ]; then
mkdir -p $dir
fi
RSYNC_OPTS=" -azv "
${RSYNC} ${RSYNC_OPTS} ${OPTION} ${addr}::${DESTINATION} $dir >> ${logfile}
logging 'backup' "rsync://${addr}::${DESTINATION} to ${dir}"
echo 'Backup Directory:' $dir
exit
done
}
function cron(){
local fun=$2
case ${fun} in
show)
crontab -l
;;
setup)
cat $PREFIX/cron.d/crontab | crontab
;;
edit)
vim $PREFIX/cron.d/crontab
cat $PREFIX/cron.d/crontab | crontab
;;
*)
usage
;;
esac
}
function release() {
local domain=$2
local host=$3
local ver=$4
local message=$5
if [ $# -lt 4 ]; then
usage
fi
if [ -z $message ]; then
echo -n "Message: "
read message
fi
config ${domain}/${host}
local logfile=${LOGDIR}/${host}.${domain}.log
project=$SRCDIR/${STAGE}/${domain}/${host}.${domain}
cd $project
$GIT tag ${ver} >> $logfile
logging 'release' "{GIT} tag ${ver} - ${message}"
}
function stage(){
case $1 in
development)
STAGE='development'
;;
testing)
STAGE='testing'
;;
production)
STAGE='production'
;;
*)
echo "STAGE ERROR"
exit
;;
esac
echo $"STAGE=$STAGE" > $SYSCONFDIR/stage.conf && echo $STAGE
logging 'stage' "${STAGE}"
}
function branch(){
local stage=$2
local domain=$3
local host=$4
local branchname=$5
cd $SRCDIR/${stage}/${domain}/$host.${domain}
if [ -z $branchname ]; then
git branch
else
git reset HEAD --hard
git pull
git checkout -fb $branchname origin/$branchname || { git checkout -f $branchname; git pull; }
#git checkout $branchname
fi
}
function usage(){
echo $"Usage: $0 [OPTION] <server-id> <directory/timepoint>"
echo -ne "
OPTION:
development <domain> <host>
testing <domain> <host>
production <domain> <host>
branch {development|testing|production} <domain> <host> <branchname>
revert {development|testing|production} <domain> <host> <revision>
backup <domain> <host> <directory>
release <domain> <host> <tags> <message>
list
list <domain> <host>
clean {development|testing|production} <domain> <host>
log <project> <line>
conf list
cron show
cron setup
cron edit
"
# stage {development|testing|production}
# deploy <domain> <host>
# revert <domain> <host> <revision>
# conf new <project>
# conf remove <project>
# conf show <project>
# conf edit <project>
exit
}
case "$1" in
stage)
stage $2
;;
development)
STAGE='development'
deploy $@
;;
testing)
STAGE='testing'
deploy $@
;;
production)
STAGE='production'
deploy $@
;;
branch)
branch $@
;;
revert)
STAGE=$2
revert $@
;;
backup)
backup $@
;;
branch)
branch $@
;;
cron)
cron $@
;;
release)
release $@
;;
clean)
clean $@
;;
list)
list $@
;;
log)
ls -1 $LOGDIR/*
;;
conf)
conf $@
;;
*)
usage
exit 1
esac