(sitka) [RT18017] Fixed sync using local instead of remote branch
[sitka/sitka-tools.git] / deployment / git-deploy.sh
CommitLineData
2385238b
LW
1#!/bin/bash
2
3#TODO decide about sql files and other odd files
2385238b
LW
4
5PROD_SERVERS=" app1-1 app1-2 app2-1 app2-2 app3-1 app3-2 stanns bibc-prod "
6REPO='.'
1c47dbca 7PATHMAP_FILE='pathmap.ini'
2385238b
LW
8
9function usage()
10{
11 cat <<EOF
12USAGE:
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
16This script is currently in testing. By default it will echo the commands it would run to the screen.
17If you wan to deploy something you need to use the -d option.
18
19e.g. ./git-deploy.sh -r origin -b HEAD -d host1
20
21As well, this script will not deploy to our production servers currently. It will print out a message
22saying so if you try to use a production server as a host option or if you use the -P option to deploy
23to all production servers.
24
25OPTIONS:
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
1c47dbca 29 -c The config file with the path mapping between the repo and the server
2385238b
LW
30 -P Deploy to all production servers
31 -d Actually deploy. While testing this option is needed to force the commands to execute
1c47dbca
LW
32 -s Sync the entire branch (as much as possible tt2, pm, js, maybe others?) with the server(s)
33 -h This help information
2385238b
LW
34EOF
35}
36
1c47dbca
LW
37function get_hostname() {
38 HOST=$1
39 echo `echo $HOST | sed -e 's/^\([^.]*\).*$/\1/'`
40}
41
2385238b
LW
42function create_tmp_file() {
43 TMP_DIR=$1
44 FILENAME=$2
45 touch $TMP_DIR/$FILENAME
46 echo "$TMP_DIR/$FILENAME"
47}
48
1c47dbca
LW
49function 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
d8d64308 59function find_base_path() {
2385238b 60 RELATIVE_PATH=$1
1c47dbca
LW
61 HOST=$2
62 HOST=`get_hostname $HOST`
2385238b 63
1c47dbca
LW
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`
2385238b 76 do
1c47dbca 77 BASE_PATH=`$ACCESS_PATHMAP --config $LOCAL_PATHMAP_FILE --component $COMPONENT --srcpath $RELATIVE_PATH`
2385238b
LW
78 if [[ $BASE_PATH ]]
79 then
d8d64308
LW
80 echo $BASE_PATH
81 return
2385238b
LW
82 fi
83 done
84}
85
d8d64308
LW
86function 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
2385238b
LW
105function deployfile() {
106 REMOTE=$1
107 BRANCH=$2
d8d64308
LW
108 BASE_PATH=$3
109 RELATIVE_PATH=$4
110 FILENAME=$5
111 TMP_DIR=$6
1c47dbca 112 HOST=$7
2385238b
LW
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
d8d64308 130 FULL_PATH=`get_full_path $RELATIVE_PATH $BASE_PATH`
2385238b
LW
131
132 TEMPFILE=`create_tmp_file $TMP_DIR $FILENAME`
133 git --git-dir $REPO show $REMOTE/$BRANCH:$RELATIVE_PATH/$FILENAME > $TEMPFILE
1c47dbca
LW
134
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" ]]
2385238b 141 then
1c47dbca 142 echo $COMMAND
2385238b 143 else
1c47dbca 144 $COMMAND
2385238b 145 fi
1c47dbca 146 fi
2385238b
LW
147}
148
1c47dbca 149while getopts ":g:r:b:c:Pdsh" opt
2385238b
LW
150do
151 case $opt in
152 g ) REPO=$OPTARG;;
153 r ) REMOTE=$OPTARG;;
154 b ) BRANCH=$OPTARG;;
1c47dbca 155 c ) PATHMAP_FILE=$OPTARG;;
2385238b
LW
156 P ) PROD="P";;
157 d ) DEPLOY="d";;
d8d64308 158 s ) SYNC="s";;
2385238b
LW
159 h ) usage && exit 0;;
160 esac
161done
162
163if [[ ! "$REPO" =~ .git$ ]]
164then
165 REPO=$REPO"/.git"
166fi
167
168shift $(($OPTIND - 1))
169
170if [[ -z "$PROD" ]]
171then
172 HOST_LIST=$@
173else
174 HOST_LIST=$@$PROD_SERVERS
175fi
176
177if [[ -z $HOST_LIST ]]
178then
1c47dbca 179 echo 'You must specify a host to deploy to in order to use this script' >&2
2385238b
LW
180 exit 1
181fi
182
d8d64308
LW
183if [[ ! -z $SYNC ]]
184then
1c47dbca 185 read -p "Are you SURE you want to sync $HOST_LIST with $BRANCH (Yes/No): " ANSWER 2>&1
d8d64308
LW
186 if [[ ! "$ANSWER" =~ [Yy]es ]]
187 then
1c47dbca 188 echo "Aborting sync" >&2
d8d64308
LW
189 exit 2;
190 fi
191fi
192
1c47dbca
LW
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
198HOST_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%?}; }`
199TMP_DIR='/tmp/'$BRANCH'/'$HOST_LIST_FOR_DIR_NAME'/'`date +%Y_%m_%d_%H_%M_%S`
200
201mkdir -p $TMP_DIR
d8d64308
LW
202
203if [[ -z "$SYNC" ]]
204then
205 LIST_BRANCH_FILES=`git --git-dir $REPO show $REMOTE/$BRANCH --name-only --oneline | awk '{if(NR!=1) {print}}'`
206else
12850067 207 LIST_BRANCH_FILES=`cd $REPO && git ls-tree -r --full-name $REMOTE/$BRANCH | cut -f 2`
1c47dbca
LW
208fi
209
210#Find access_pathmap.pl and if not found assume it is in current direcotry
211ACCESS_PATHMAP=`which access_pathmap.pl`
212
213if [[ -z $ACCESS_PATHMAP ]]
214then
215 if does_file_exist access_pathmap.pl
216 then
217 ACCESS_PATHMAP='./access_pathmap.pl'
218 else
219 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
220 exit 3
221 fi
d8d64308
LW
222fi
223
224for PATH_AND_FILENAME in $LIST_BRANCH_FILES
2385238b
LW
225do
226 FILENAME=`basename $PATH_AND_FILENAME`
227 RELATIVE_PATH=`dirname $PATH_AND_FILENAME`
1c47dbca
LW
228 for DEPLOY_HOST in $HOST_LIST
229 do
230 BASE_PATH=`find_base_path $RELATIVE_PATH $DEPLOY_HOST`
231 if [[ $BASE_PATH ]]
232 then
233 deployfile $REMOTE $BRANCH $BASE_PATH $RELATIVE_PATH $FILENAME $TMP_DIR $DEPLOY_HOST
234 else
235 echo "Could not deploy $FILENAME to $DEPLOY_HOST because no mapping could be found in $PATHMAP_FILE or any host specific pathmap files" >&2
236 fi
237 done
2385238b 238done