[rt18107] added better filtering of production servers
[sitka/sitka-tools.git] / deployment / git-deploy.sh
1 #!/bin/bash
2
3 #TODO decide about sql files and other odd files
4 #TODO make sure access_pathmap.ini is fixed so Open-ILS/xul/staff_client/ files map properly
5
6 PROD_SERVERS=" app1-1 app1-2 app2-1 app2-2 app3-1 app3-2 stanns bibc-prod "
7 REPO='.'
8
9 function usage()
10 {
11     cat <<EOF
12 USAGE:
13 ./git-deploy.sh -g ~/evergreen/.git -r origin -b HEAD host1 [ host2 ... ]
14 ./git-deploy.sh -r origin -b user/lwhalen/rt15288 -P
15
16 This script is currently in testing.  By default it will echo the commands it would run to the screen.
17 If you wan to deploy something you need to use the -d option.
18
19 e.g. ./git-deploy.sh -r origin -b HEAD -d host1
20
21 As well, this script will not deploy to our production servers currently.  It will print out a message
22 saying so if you try to use a production server as a host option or if you use the -P option to deploy
23 to all production servers.
24
25 OPTIONS:
26     -g The location of the git repo
27     -r The remote to deploy from
28     -b The branch on the remote to deploy from
29     -P Deploy to all production servers
30     -d Actually deploy.  While testing this option is needed to force the commands to execute
31 EOF
32 }
33
34 function create_tmp_file() {
35     TMP_DIR=$1
36     FILENAME=$2
37     touch $TMP_DIR/$FILENAME
38     echo "$TMP_DIR/$FILENAME"
39 }
40
41 function find_base_path() {
42     RELATIVE_PATH=$1
43
44     for COMPONENT in `access_pathmap.pl --config $PATH_MAP_FILE`
45     do
46         BASE_PATH=`access_pathmap.pl --config $PATH_MAP_FILE --component $COMPONENT --srcpath $RELATIVE_PATH`
47         if [[ $BASE_PATH ]]
48         then
49             echo $BASE_PATH
50             return
51         fi
52     done
53 }
54
55
56 function get_full_path() {
57     RELATIVE_PATH=$1
58     BASE_PATH=$2
59
60     if [[ $BASE_PATH ]]
61     then
62         #We extract the last directory in the base path so we can
63         #use parameter substitution to remove everything up to the
64         #last directory in the BASE_PATH from the RELATIVE_PATH
65         #this leaves us with the part of the git source tree path
66         #that needs to be appended to the base path in order to locate
67         #the file on the server
68         LAST_DIR_IN_BASE_PATH=`basename $BASE_PATH`
69         RELATIVE_PART=${RELATIVE_PATH/*$LAST_DIR_IN_BASE_PATH/}
70         echo $BASE_PATH$RELATIVE_PART
71         return
72     fi
73 }
74
75 function deployfile() {
76     REMOTE=$1
77     BRANCH=$2
78     BASE_PATH=$3
79     RELATIVE_PATH=$4
80     FILENAME=$5
81     TMP_DIR=$6
82     HOSTS=$7
83
84     PERL_FILE_RE='^.*.pm$'
85     SQL_FILE_RE='^.*.sql$'
86     TT2_FILE_RE='^Open-ILS/src/(templates)/(.*)$'
87     USER='opensrf'
88
89     if [[ $FILENAME =~ $PERL_FILE_RE ]]
90     then
91         USER='root'
92     elif [[ $FILENAME =~ $SQL_FILE_RE ]]
93     then
94         echo 'SQL file -- TAKE THE TIME TO LOAD THIS PROPERLY INTO THE DATABASE.  DO NOT FORGET TO WRAP IT IN BEGIN AND COMMIT'
95         return
96     else
97         USER='opensrf'
98     fi
99
100     FULL_PATH=`get_full_path $RELATIVE_PATH $BASE_PATH`
101
102     TEMPFILE=`create_tmp_file $TMP_DIR $FILENAME`
103     git --git-dir $REPO show $REMOTE/$BRANCH:$RELATIVE_PATH/$FILENAME > $TEMPFILE
104     for HOST in $HOSTS
105     do
106         if [[ $PROD_SERVERS =~ " `echo $HOST | cut -d '.' -f 1` " ]]
107         then
108             echo "Cannot deploy `basename $TEMPFILE` to $HOST while testing.  Please use another server"
109         else 
110             COMMAND="deployfile.sh -f $TEMPFILE -p $FULL_PATH -u $USER -b $HOST"
111             if [[ -z "$DEPLOY" ]]
112             then
113                 echo $COMMAND
114             else 
115                 $COMMAND
116             fi
117
118         fi
119     done
120 }
121
122 while getopts ":g:r:b:c:Pdhs" opt
123 do
124     case $opt in
125         g ) REPO=$OPTARG;;
126         r ) REMOTE=$OPTARG;;
127         b ) BRANCH=$OPTARG;;
128         c ) PATH_MAP_FILE=$OPTARG;;
129         P ) PROD="P";;
130         d ) DEPLOY="d";;
131         s ) SYNC="s";;
132         h ) usage && exit 0;;
133     esac
134 done
135
136 if [[ ! "$REPO" =~ .git$ ]]
137 then
138     REPO=$REPO"/.git"
139 fi
140
141 shift $(($OPTIND - 1))
142
143 if [[ -z "$PROD" ]]
144 then
145     HOST_LIST=$@
146 else
147     HOST_LIST=$@$PROD_SERVERS
148 fi
149
150 if [[ -z $HOST_LIST ]]
151 then
152     echo 'You must specify a host to deploy to in order to use this script'
153     exit 1
154 fi
155
156 if [[ ! -z $SYNC ]]
157 then
158     read -p "Are you SURE you want to sync $HOST_LIST with $BRANCH (Yes/No): " ANSWER
159     if [[ ! "$ANSWER" =~ [Yy]es ]]
160     then
161         echo "Aborting sync"
162         exit 2;
163     fi
164 fi
165
166 TMP_DIR=`mktemp -d`
167
168 if [[ -z "$SYNC" ]]
169 then
170     LIST_BRANCH_FILES=`git --git-dir $REPO show $REMOTE/$BRANCH --name-only --oneline | awk '{if(NR!=1) {print}}'`
171 else
172     BRANCH_NAME=`basename $BRANCH`
173     LIST_BRANCH_FILES=`cd $REPO && git ls-tree -r  --full-name $BRANCH_NAME | tr '\t' ' ' | cut -d ' ' -f 4`
174 fi
175
176 for PATH_AND_FILENAME in $LIST_BRANCH_FILES
177 do
178     FILENAME=`basename $PATH_AND_FILENAME`
179     RELATIVE_PATH=`dirname $PATH_AND_FILENAME`
180     BASE_PATH=`find_base_path $RELATIVE_PATH`
181     if [[ $BASE_PATH ]]
182     then
183         deployfile $REMOTE $BRANCH $BASE_PATH $RELATIVE_PATH $FILENAME $TMP_DIR "$HOST_LIST"
184     fi
185 done