Commit | Line | Data |
---|---|---|
2385238b LW |
1 | #!/bin/bash |
2 | ||
3 | #TODO decide about sql files and other odd files | |
2385238b LW |
4 | |
5 | PROD_SERVERS=" app1-1 app1-2 app2-1 app2-2 app3-1 app3-2 stanns bibc-prod " | |
6 | REPO='.' | |
1c47dbca | 7 | PATHMAP_FILE='pathmap.ini' |
2385238b LW |
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 | |
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 |
34 | EOF |
35 | } | |
36 | ||
1c47dbca LW |
37 | function get_hostname() { |
38 | HOST=$1 | |
39 | echo `echo $HOST | sed -e 's/^\([^.]*\).*$/\1/'` | |
40 | } | |
41 | ||
2385238b LW |
42 | function create_tmp_file() { |
43 | TMP_DIR=$1 | |
44 | FILENAME=$2 | |
45 | touch $TMP_DIR/$FILENAME | |
46 | echo "$TMP_DIR/$FILENAME" | |
47 | } | |
48 | ||
1c47dbca LW |
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 | ||
d8d64308 | 59 | function 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 |
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 | ||
2385238b LW |
105 | function 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 | |
f24c6790 | 134 | echo "git --git-dir $REPO show $REMOTE/$BRANCH:$RELATIVE_PATH/$FILENAME > $TEMPFILE" |
1c47dbca LW |
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 | 149 | while getopts ":g:r:b:c:Pdsh" opt |
2385238b LW |
150 | do |
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 | |
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 | |
1c47dbca | 179 | echo 'You must specify a host to deploy to in order to use this script' >&2 |
2385238b LW |
180 | exit 1 |
181 | fi | |
182 | ||
d8d64308 LW |
183 | if [[ ! -z $SYNC ]] |
184 | then | |
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 | |
191 | fi | |
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 | |
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%?}; }` | |
1c47dbca | 199 | |
9ba22c5c LW |
200 | #do a git fetch on the repo |
201 | echo "Fetching $REMOTE from the $REPO" | |
202 | git --git-dir $REPO fetch $REMOTE | |
d8d64308 LW |
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 | |
12850067 | 208 | LIST_BRANCH_FILES=`cd $REPO && git ls-tree -r --full-name $REMOTE/$BRANCH | cut -f 2` |
1c47dbca LW |
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 | |
d8d64308 LW |
223 | fi |
224 | ||
225 | for PATH_AND_FILENAME in $LIST_BRANCH_FILES | |
2385238b LW |
226 | do |
227 | FILENAME=`basename $PATH_AND_FILENAME` | |
228 | RELATIVE_PATH=`dirname $PATH_AND_FILENAME` | |
1c47dbca LW |
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 | |
f24c6790 LW |
234 | TMP_DIR='/tmp/'$BRANCH'/'$HOST_LIST_FOR_DIR_NAME'/'`date +%Y_%m_%d_%H_%M_%S`'/'$RELATIVE_PATH |
235 | mkdir -p $TMP_DIR | |
1c47dbca LW |
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 | |
2385238b | 241 | done |