Refactor deploy script a bit; make it less sensitive to transient errors
[arvados-dev.git] / jenkins / run-deploy.sh
1 #!/bin/bash
2
3
4 read -rd "\000" helpmessage <<EOF
5 $(basename $0): Deploy Arvados to a cluster
6
7 Syntax:
8         WORKSPACE=/path/to/arvados $(basename $0) <identifier> <deploy_repo_name>
9
10 Options:
11
12 identifier             Arvados cluster name
13 deploy_repo_name       Name for the repository with the (capistrano) deploy scripts
14
15 WORKSPACE=path         Path to the Arvados source tree to deploy from
16
17 EOF
18
19
20 IDENTIFIER=$1
21 DEPLOY_REPO=$2
22
23 if [[ "$IDENTIFIER" == '' || "$DEPLOY_REPO" == '' ]]; then
24   echo >&2 "$helpmessage"
25   echo >&2
26   exit 1
27 fi
28
29 # Sanity check
30 if ! [[ -n "$WORKSPACE" ]]; then
31   echo >&2 "$helpmessage"
32   echo >&2
33   echo >&2 "Error: WORKSPACE environment variable not set"
34   echo >&2
35   exit 1
36 fi
37
38 EXITCODE=0
39
40 COLUMNS=80
41
42 title () {
43   printf "\n%*s\n\n" $(((${#title}+$COLUMNS)/2)) "********** $1 **********"
44 }
45
46 # We only install capistrano in dev mode
47 export RAILS_ENV=development
48
49 source /etc/profile.d/rvm.sh
50 echo $WORKSPACE
51
52 # Weirdly, jenkins/rvm ties itself in a knot.
53 rvm use default
54
55 # Just say what version of ruby we're running
56 ruby --version
57
58 function run_puppet() {
59   node=$1
60   return_var=$2
61
62   TMP_FILE=`mktemp`
63   ssh -t -p2222 -o "StrictHostKeyChecking no" -o "ConnectTimeout 5" root@$node.$IDENTIFIER -C "/usr/bin/puppet agent -t" | tee $TMP_FILE
64
65   ECODE=$?
66   RESULT=$(cat $TMP_FILE)
67
68   if [[ "$ECODE" != "255" && ! ("$RESULT" =~ 'already in progress') && "$ECODE" != "2" && "$ECODE" != "0"  ]]; then
69     # Puppet exists 255 if the connection timed out. Just ignore that, it's possible that this node is
70     #   a compute node that was being shut down.
71     # Puppet exits 2 if there are changes. For real!
72     # Puppet prints 'Notice: Run of Puppet configuration client already in progress' if another puppet process
73     #   was already running
74     echo "ERROR updating $node.$IDENTIFIER: exit code $ECODE"
75   fi
76   rm -f $TMP_FILE
77   echo
78   eval "$return_var=$ECODE"
79 }
80
81 function ensure_symlink() {
82   if [[ ! -L $WORKSPACE/$1 ]]; then
83     ln -s $WORKSPACE/$DEPLOY_REPO/$1 $WORKSPACE/$1
84   fi
85 }
86
87 # Check out/update the $DEPLOY_REPO repository
88 if [[ ! -d $DEPLOY_REPO ]]; then
89   mkdir $DEPLOY_REPO
90   git clone git@git.curoverse.com:$DEPLOY_REPO.git
91 else
92   cd $DEPLOY_REPO
93   git pull
94 fi
95
96 # Make sure the necessary symlinks are in place
97 cd "$WORKSPACE"
98 ensure_symlink "apps/workbench/Capfile.workbench.$IDENTIFIER"
99 ensure_symlink "apps/workbench/config/deploy.common.rb"
100 ensure_symlink "apps/workbench/config/deploy.curoverse.rb"
101 ensure_symlink "apps/workbench/config/deploy.workbench.$IDENTIFIER.rb"
102
103 ensure_symlink "services/api/Capfile.$IDENTIFIER"
104 ensure_symlink "services/api/config/deploy.common.rb"
105 ensure_symlink "services/api/config/deploy.$IDENTIFIER.rb"
106
107 # Deploy API server
108 title "Deploying API server"
109 cd "$WORKSPACE"
110 cd services/api
111
112 bundle install --deployment
113
114 # make sure we do not print the output of config:check
115 sed -i'' -e "s/RAILS_ENV=production #{rake} config:check/RAILS_ENV=production QUIET=true #{rake} config:check/" $WORKSPACE/$DEPLOY_REPO/services/api/config/deploy.common.rb
116
117 bundle exec cap deploy -f Capfile.$IDENTIFIER
118
119 ECODE=$?
120
121 # restore unaltered deploy.common.rb
122 cd $WORKSPACE/$DEPLOY_REPO
123 git checkout services/api/config/deploy.common.rb
124
125 if [[ "$ECODE" != "0" ]]; then
126   title "!!!!!! DEPLOYING API SERVER FAILED !!!!!!"
127   EXITCODE=$(($EXITCODE + $ECODE))
128   exit $EXITCODE
129 fi
130
131 title "Deploying API server complete"
132
133 # Install updated debian packages
134 title "Deploying updated arvados debian packages"
135
136 ssh -p2222 root@$IDENTIFIER.arvadosapi.com -C "apt-get update && apt-get -qqy install arvados-src python-arvados-fuse python-arvados-python-client"
137
138 if [[ "$ECODE" != "0" ]]; then
139   title "!!!!!! DEPLOYING DEBIAN PACKAGES FAILED !!!!!!"
140   EXITCODE=$(($EXITCODE + $ECODE))
141   exit $EXITCODE
142 fi
143
144 title "Deploying updated arvados debian packages complete"
145
146 # Install updated arvados gems
147 title "Deploying updated arvados gems"
148
149 ssh -p2222 root@$IDENTIFIER.arvadosapi.com -C "/usr/local/rvm/bin/rvm default do gem install arvados arvados-cli && /usr/local/rvm/bin/rvm default do gem clean arvados arvados-cli"
150
151 if [[ "$ECODE" != "0" ]]; then
152   title "!!!!!! DEPLOYING ARVADOS GEMS FAILED !!!!!!"
153   EXITCODE=$(($EXITCODE + $ECODE))
154   exit $EXITCODE
155 fi
156
157 title "Deploying updated arvados gems complete"
158
159 # Deploy Workbench
160 title "Deploying workbench"
161 cd "$WORKSPACE"
162 cd apps/workbench
163 bundle install --deployment
164
165 # make sure we do not print the output of config:check
166 sed -i'' -e "s/RAILS_ENV=production #{rake} config:check/RAILS_ENV=production QUIET=true #{rake} config:check/" $WORKSPACE/$DEPLOY_REPO/apps/workbench/config/deploy.common.rb
167
168 bundle exec cap deploy -f Capfile.workbench.$IDENTIFIER
169
170 ECODE=$?
171
172 # restore unaltered deploy.common.rb
173 cd $WORKSPACE/$DEPLOY_REPO
174 git checkout apps/workbench/config/deploy.common.rb
175
176 if [[ "$ECODE" != "0" ]]; then
177   title "!!!!!! DEPLOYING WORKBENCH FAILED !!!!!!"
178   EXITCODE=$(($EXITCODE + $ECODE))
179   exit $EXITCODE
180 fi
181
182 title "Deploying workbench complete"
183
184 # Update compute node(s)
185 title "Update compute node(s)"
186
187 # Get list of nodes that are up
188 COMPRESSED_NODE_LIST=`ssh -p2222 root@$IDENTIFIER -C "sinfo --long -p crypto -r -o "%N" -h"`
189
190 if [[ "$COMPRESSED_NODE_LIST" != '' ]]; then
191   COMPUTE_NODES=`ssh -p2222 root@$IDENTIFIER -C "scontrol show hostname $COMPRESSED_NODE_LIST"`
192
193   SUM_ECODE=0
194   for node in $COMPUTE_NODES; do
195     echo "Updating $node.$IDENTIFIER"
196     run_puppet $node ECODE
197     SUM_ECODE=$(($SUM_ECODE + $ECODE))
198   done
199
200   if [[ "$SUM_ECODE" != "0" ]]; then
201     title "!!!!!! Update compute node(s) FAILED !!!!!!"
202     EXITCODE=$(($EXITCODE + $SUM_ECODE))
203   fi
204 fi
205
206 title "Update compute node(s) complete"
207
208 title "Update shell"
209
210 run_puppet shell ECODE
211
212 if [[ "$ECODE" == "2" ]]; then
213   # Puppet exits '2' if there are changes. For real!
214   ECODE=0
215 fi
216
217 if [[ "$ECODE" != "0" ]]; then
218   title "!!!!!! Update shell FAILED !!!!!!"
219   EXITCODE=$(($EXITCODE + $ECODE))
220 fi
221
222 title "Update shell complete"
223
224 title "Update keep0"
225
226 run_puppet keep0 ECODE
227
228 if [[ "$ECODE" == "2" ]]; then
229   # Puppet exits '2' if there are changes. For real!
230   ECODE=0
231 fi
232
233 if [[ "$ECODE" != "0" ]]; then
234   title "!!!!!! Update keep0 FAILED !!!!!!"
235   EXITCODE=$(($EXITCODE + $ECODE))
236 fi
237
238 title "Update keep0 complete"
239
240 exit $EXITCODE