#!/bin/bash
#####################################################################
# description: automation deployment script
# netkiller series utilities
# $id$
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
if [ -f $deploy_home/conf/stage.conf ];then
. $deploy_home/conf/stage.conf
#================================================================================
logfile="deploy.$(date -d "today" +"%y-%m-%d").log"
tmpdir=$(mktemp -d --suffix=.tmp -p /tmp deploy.xxxxxx)
svn=/usr/bin/svn
timepoint=`date '+%y-%m-%d.%h-%m-%s'`
backupdir=/backup/${timepoint}
rsync="rsync"
upload_dir=$tmpdir
revision=''
# development production testing
if [ -z $stage ]; then
echo 'example: touch conf/stage.conf'
echo "stage='development' or stage='testing' or stage='production'"
subversion=''
if [ ! -d ${tmpdir} ]; then
mkdir ${tmpdir}
chmod 700 -r ${srcdir}/*
#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
}
#logging 'ok' 'this is test msg!!!'
function conf(){
local cmd=$2
local prj=$3
case $cmd in
list)
ls -1 $sysconfdir/*
;;
new)
mkdir -p $sysconfdir
#if [ ! -d ${backupdir} ]; then
# mkdir -p $backupdir
#fi
read -p "project directory: " prjdir
if [ -z $prjdir ]; then
if [ -f $sysconfdir/$prjdir.conf ]; then
echo "cannot create config $prjdir.conf': file exists"
exit 1
read -p "subversion url: $repositories/: " svnurl
if [ -z $svnurl ]; then
svnurl=$repositories
read -p "hostname: " host
if [ -z $host ]; then
host="localhost"
echo "default hostname 'localhost'"
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
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
remove)
if [ -f $sysconfdir/$prj ]; then
rm -rf $sysconfdir/$prj
show)
cat $sysconfdir/$prj
edit)
vim $sysconfdir/$prj
*)
usage
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
echo "please provide the config($sysconfdir/${stage}/${cfg}.conf) to deploy!"
if [ -z "$cfg" ]; then
echo "please provide the path for deploy!"
if [ ! -f $exclude_from ]; then
echo "please provide a list of excluded in the $exclude_from."
touch $exclude_from
if [ ! -f $include_from ]; then
echo "please provide a list of included in the $include_from."
touch $include_from
# case ${stage} in
# development)
# subversion='development'
# ;;
# testing)
# subversion=''
# production)
# *)
# subversion='current'
# esac
function deploy() {
local domain=$2
local host=$3
local logfile=${logdir}/${host}.${domain}.log
if [ $# -lt 3 ]; then
if [ $host = 'all' ]; then
for h in $(ls -1 $sysconfdir/${stage}/$domain/ | cut -d. -f1)
do
/bin/sh $bindir/deploy deploy $domain $h
done
local revision=$4
if [ ! -z $revision ]; then
revision="-r ${revision}"
config ${domain}/${host}
project=$srcdir/${stage}/${domain}/$host.${domain}
git_opts=${revision}
if [ -d ${project} ]; then
cd $project
$git pull ${git_opts}
cd -
# >> $logfile
logging 'update' ${project}
mkdir -p ${project}
$git clone ${repository} ${project}
#>> $logfile
logging 'checkout' ${project}
# $bindir/$command deploy $hostname $upload_dir/$ver/
rsync_opts=" -azvp --backup --backup-dir=${backupdir} --exclude=.git --log-file=${logfile} --exclude-from=$exclude_from --include-from=$include_from"
if [ -f ${libexecdir}/${domain}/${host}/before ];then
/bin/sh ${libexecdir}/${domain}/${host}/before
if [ -d ${sharedir}/${stage}/${domain}/${host}/ ]; then
cp -a ${sharedir}/${stage}/${domain}/${host}/* ${project}/
find $srcdir/* -type f -name "thumbs.db" -exec rm -rf {} \;
for addr in ${remote}
echo ${addr}
case ${mode} in
ftpdeploy
scp -ar ${project}/* ${addr}:${destination}
sftpdeploy
$rsync $rsync_opts $option ${project}/* ${addr}::${destination}
#echo "$rsync $rsync_opts $option ${project}/* ${addr}::${destination}"
"rsync+ssh")
$rsync $rsync_opts ${project}/* ${addr}:${destination}
if [ -z "${revision}" ]; then
logging 'deploy' "${project} => ${addr}:${destination}"
logging 'revert' "${project} => ${addr}:${destination}"
if [ -f ${libexecdir}/${domain}/${host}/after ];then
#ssh ${scp} < ${libexecdir}/${domain}/${host}/after
function revert() {
if [ -z $domain ]; then
if [ -z $revision ]; then
#echo $domain , $host, $dir; exit
deploy $@
function import(){
local dir=$4
if [ -z $dir ]; then
$git import $dir ${repository} >> $logfile
function svnexport(){
$ export --force ${repository} ${dir} >> $logfile
logging 'export' "${trunk} to ${dir}"
function timepoint {
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
$rsync ${src}/$edition ${destination}
ssh ${remote} < script/unstable
function clean() {
local project=$srcdir/${domain}/$host.${domain}
rm -rf ${project}
function list {
ls $srcdir/*
svn ls ${repositories}/$dir #| awk -f '/' '{print $1}'
function backup() {
dir=$tmpdir
for addr in ${remote}
dir=$dir/${addr}
if [ ! -d ${dir} ]; then
mkdir -p $dir
$rsync -auzvp $option ${addr}::${destination} $dir >> ${logfile}
logging 'backup' "rsync://${addr}::${destination} to ${dir}"
echo 'backup directory:' $dir
function cron(){
local fun=$2
case ${fun} in
crontab -l
setup)
cat $prefix/cron.d/crontab | crontab
vim $prefix/cron.d/crontab
function files {
local project_dir=$1
local project=$2
if [ -z "$2" ]; then
echo "please provide the project name for deploy!"
config ${project}
exclude_from=exclude/${project}.lst
include_from=include/${project}.lst
$rsync --exclude-from=$exclude_from --include-from=$include_from ${project_dir} ${remote}
ssh ${scp} < script/${project}
timepoint
function release() {
local ver=$4
local message=$5
if [ $# -lt 4 ]; then
# if [ -z $host ]; then
# usage
# fi
#
if [ -z $message ]; then
echo -n "message: "
read message
$git copy -m "$message" ${trunk} ${tags}/${ver} >> $logfile
logging 'release' "copy ${trunk} to ${tags}/${ver}"
function stage(){
case $1 in
development)
stage='development'
testing)
stage='testing'
production)
stage='production'
echo "stage error"
echo $"stage=$stage" > $sysconfdir/stage.conf && echo $stage
logging 'stage' "${stage}"
function usage(){
echo $"usage: $0 [option] <server-id> <directory/timepoint>"
echo -ne "
option:
stage {development|testing|production}
deploy <domain> <host>
revert <domain> <host> <revision>
backup <domain> <host> <directory>
release <domain> <host> <tags> <message>
list
list <domain> <host>
import <domain> <host> <dir>
export <domain> <host> <dir>
clean <domain> <host>
log <project> <line>
conf list
conf new <project>
conf remove <project>
conf show <project>
conf edit <project>
cron show
cron setup
cron edit
"
case "$1" in
stage)
stage $2
deploy)
revert)
revert $@
;;
import)
import $@
export)
svnexport $@
backup)
backup $@
# switch)
# switch $2
cron)
cron $@
release)
release $@
clean)
clean $@
list $@
log)
ls -1 $logdir/*
conf)
conf $@