install-osrf.sh: set ejabberd host correctly during registration on prod
[sitka/sitka-tools.git] / deployment / git-deploy.sh
1 #!/bin/bash
2
3 #TODO decide about sql files and other odd files
4
5 PROD_SERVERS=" app1-1 app1-2 app2-1 app2-2 app3-1 app3-2 stanns bibc-prod "
6 REPO='.'
7 PATHMAP_FILE='pathmap.ini'
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     -c The config file with the path mapping between the repo and the server
30     -P Deploy to all production servers
31     -d Actually deploy.  While testing this option is needed to force the commands to execute
32     -s Sync the entire branch (as much as possible tt2, pm, js, maybe others?) with the server(s)
33     -h This help information
34 EOF
35 }
36
37 function get_hostname() {
38     HOST=$1
39     echo `echo $HOST | sed -e 's/^\([^.]*\).*$/\1/'`
40 }
41
42 function create_tmp_file() {
43     TMP_DIR=$1
44     FILENAME=$2
45     touch $TMP_DIR/$FILENAME
46     echo "$TMP_DIR/$FILENAME"
47 }
48
49 function does_file_exist() {
50     FILE=$1;
51     if [ `ls $FILE 2> /dev/null | wc -l` -eq 1 ]
52     then
53         return 0
54     else
55         return 1
56     fi
57 }
58     
59 function find_base_path() {
60     RELATIVE_PATH=$1
61     HOST=$2
62     HOST=`get_hostname $HOST` 
63
64     if does_file_exist ${HOST}'_'$PATHMAP_FILE
65     then
66         LOCAL_PATHMAP_FILE=${HOST}'_'$PATHMAP_FILE
67     elif does_file_exist $PATHMAP_FILE 
68     then
69         LOCAL_PATHMAP_FILE=$PATHMAP_FILE
70     else
71         echo "$PATHMAP file could not be found!" >&2
72         exit 4
73     fi
74
75     for COMPONENT in `$ACCESS_PATHMAP --config $LOCAL_PATHMAP_FILE`
76     do
77         BASE_PATH=`$ACCESS_PATHMAP --config $LOCAL_PATHMAP_FILE --component $COMPONENT --srcpath $RELATIVE_PATH`
78         if [[ $BASE_PATH ]]
79         then
80             echo $BASE_PATH
81             return
82         fi
83     done
84 }
85
86 function get_full_path() {
87     RELATIVE_PATH=$1
88     BASE_PATH=$2
89
90     if [[ $BASE_PATH ]]
91     then
92         #We extract the last directory in the base path so we can
93         #use parameter substitution to remove everything up to the
94         #last directory in the BASE_PATH from the RELATIVE_PATH
95         #this leaves us with the part of the git source tree path
96         #that needs to be appended to the base path in order to locate
97         #the file on the server
98         LAST_DIR_IN_BASE_PATH=`basename $BASE_PATH`
99         RELATIVE_PART=${RELATIVE_PATH/*$LAST_DIR_IN_BASE_PATH/}
100         echo $BASE_PATH$RELATIVE_PART
101         return
102     fi
103 }
104
105 function deployfile() {
106     REMOTE=$1
107     BRANCH=$2
108     BASE_PATH=$3
109     RELATIVE_PATH=$4
110     FILENAME=$5
111     TMP_DIR=$6
112     HOST=$7
113
114     PERL_FILE_RE='^.*.pm$'
115     SQL_FILE_RE='^.*.sql$'
116     TT2_FILE_RE='^Open-ILS/src/(templates)/(.*)$'
117     USER='opensrf'
118
119     if [[ $FILENAME =~ $PERL_FILE_RE ]]
120     then
121         USER='root'
122     elif [[ $FILENAME =~ $SQL_FILE_RE ]]
123     then
124         echo 'SQL file -- TAKE THE TIME TO LOAD THIS PROPERLY INTO THE DATABASE.  DO NOT FORGET TO WRAP IT IN BEGIN AND COMMIT'
125         return
126     else
127         USER='opensrf'
128     fi
129
130     FULL_PATH=`get_full_path $RELATIVE_PATH $BASE_PATH`
131
132     TEMPFILE=`create_tmp_file $TMP_DIR $FILENAME`
133     git --git-dir $REPO show $REMOTE/$BRANCH:$RELATIVE_PATH/$FILENAME > $TEMPFILE
134     echo  "git --git-dir $REPO show $REMOTE/$BRANCH:$RELATIVE_PATH/$FILENAME > $TEMPFILE"
135     if [[ $PROD_SERVERS =~ " `echo $HOST | cut -d '.' -f 1` " ]]
136     then
137         echo "Cannot deploy `basename $TEMPFILE` to $HOST while testing.  Please use another server"
138     else 
139         COMMAND="deployfile.sh -f $TEMPFILE -p $FULL_PATH -u $USER -b $HOST"
140         if [[ -z "$DEPLOY" ]]
141         then
142             echo $COMMAND
143         else 
144             $COMMAND
145         fi
146     fi
147 }
148
149 while getopts ":g:r:b:c:Pdsh" opt
150 do
151     case $opt in
152         g ) REPO=$OPTARG;;
153         r ) REMOTE=$OPTARG;;
154         b ) BRANCH=$OPTARG;;
155         c ) PATHMAP_FILE=$OPTARG;;
156         P ) PROD="P";;
157         d ) DEPLOY="d";;
158         s ) SYNC="s";;
159         h ) usage && exit 0;;
160     esac
161 done
162
163 if [[ ! "$REPO" =~ .git$ ]]
164 then
165     REPO=$REPO"/.git"
166 fi
167
168 shift $(($OPTIND - 1))
169
170 if [[ -z "$PROD" ]]
171 then
172     HOST_LIST=$@
173 else
174     HOST_LIST=$@$PROD_SERVERS
175 fi
176
177 if [[ -z $HOST_LIST ]]
178 then
179     echo 'You must specify a host to deploy to in order to use this script' >&2
180     exit 1
181 fi
182
183 if [[ ! -z $SYNC ]]
184 then
185     read -p "Are you SURE you want to sync $HOST_LIST with $BRANCH (Yes/No): " ANSWER 2>&1
186     if [[ ! "$ANSWER" =~ [Yy]es ]]
187     then
188         echo "Aborting sync" >&2
189         exit 2;
190     fi
191 fi
192
193 #This line takes the host list and separates it into individual lines, then sorts it. Next it removes anything following the hostname with get_hostname
194 #(hopefully the domain name), then makes it a single line again with _ instead of ' '.
195 #It then uses parameter substitution to remove the last character from the string, which is a _ because sort places a newline at the end of the
196 #last server that gets translated into an unwanted _.  We need to sort the servers, so that they are used in a consistent manner for tracking
197 #deployment
198 HOST_LIST_FOR_DIR_NAME=`echo $HOST_LIST | tr ' ' '\n' | sort | while read SORTED_HOST_LIST ; do get_hostname $SORTED_HOST_LIST ; done | tr '\n' '_' | { read SORTED_HOST_LIST; echo ${SORTED_HOST_LIST%?}; }`
199
200 #do a git fetch on the repo
201 echo "Fetching $REMOTE from the $REPO"
202 git --git-dir $REPO fetch $REMOTE
203
204 if [[ -z "$SYNC" ]]
205 then
206     LIST_BRANCH_FILES=`git --git-dir $REPO show $REMOTE/$BRANCH --name-only --oneline | awk '{if(NR!=1) {print}}'`
207 else
208     LIST_BRANCH_FILES=`cd $REPO && git ls-tree -r  --full-name $REMOTE/$BRANCH | cut -f 2`
209 fi
210
211 #Find access_pathmap.pl and if not found assume it is in current direcotry
212 ACCESS_PATHMAP=`which access_pathmap.pl`
213
214 if [[ -z $ACCESS_PATHMAP ]]
215 then
216     if does_file_exist access_pathmap.pl
217     then
218         ACCESS_PATHMAP='./access_pathmap.pl'
219     else
220         echo 'Could not locate access_pathmap.pl.  Either add access_pathmap.pl to your PATH or place it in the directory you are working in.' >&2
221         exit 3
222     fi
223 fi
224
225 for PATH_AND_FILENAME in $LIST_BRANCH_FILES
226 do
227     FILENAME=`basename $PATH_AND_FILENAME`
228     RELATIVE_PATH=`dirname $PATH_AND_FILENAME`
229     for DEPLOY_HOST in $HOST_LIST
230     do
231         BASE_PATH=`find_base_path $RELATIVE_PATH $DEPLOY_HOST`
232         if [[ $BASE_PATH ]]
233         then
234             TMP_DIR='/tmp/'$BRANCH'/'$HOST_LIST_FOR_DIR_NAME'/'`date +%Y_%m_%d_%H_%M_%S`'/'$RELATIVE_PATH
235             mkdir -p $TMP_DIR
236             deployfile $REMOTE $BRANCH $BASE_PATH $RELATIVE_PATH $FILENAME $TMP_DIR $DEPLOY_HOST
237         else
238             echo "Could not deploy $FILENAME to $DEPLOY_HOST because no mapping could be found in $PATHMAP_FILE or any host specific pathmap files" >&2
239         fi
240     done
241 done