CI: do soledad migration during upgrade test
[leap_platform.git] / tests / platform-ci / ci-build.sh
1 #!/bin/bash
2 #
3 # This script will run create a virtual provider
4 # and run tests on it.
5 #
6 # This script is triggered by .gitlab-ci.yml
7 #
8 # It depends on:
9 #   * leap_platform: in ../..
10 #   * test provider: in provider/
11 #   * leap-platform-test: installed in path
12 #   * AWS credentials as environment variables:
13 #     * `AWS_ACCESS_KEY`
14 #     * `AWS_SECRET_KEY`
15 #   * ssh private keys used to clone providers:
16 #     * `bitmask_PROVIDER_SSH_PRIVATE_KEY`
17 #     * `ibex_PROVIDER_SSH_PRIVATE_KEY`
18
19 # exit if any commands returns non-zero status
20 set -e
21 # because the ci-build is running in a pipe we need to also set the following
22 # so exit codes will be caught correctly.
23 set -o pipefail
24
25 # Check if scipt is run in debug mode so we can hide secrets
26 if [[ "$-" =~ 'x' ]]
27 then
28   echo 'Running with xtrace enabled!'
29   xtrace=true
30 else
31   echo 'Running with xtrace disabled!'
32   xtrace=false
33 fi
34
35 # leap_platform/tests/platform-ci
36 # shellcheck disable=SC2086
37 ROOTDIR=$(readlink -f "$(dirname $0)")
38
39 # leap_platform
40 PLATFORMDIR=$(readlink -f "${ROOTDIR}/../..")
41
42 # deb repo component to configure
43 COMPONENT=${COMPONENT:-"master"}
44
45 # In the gitlab CI pipeline leap is installed in a different
46 # stage by bundle. To debug you can run a single CI job locally
47 # so we install leap_cli as gem here.
48 if /usr/local/bin/bundle exec leap >/dev/null 2>&1
49 then
50   LEAP_CMD() {
51     /usr/local/bin/bundle exec leap -v2 --yes "$@"
52   }
53 else
54   sudo gem install leap_cli
55   LEAP_CMD() {
56     leap -v2 --yes "$@"
57   }
58 fi
59
60 fail() {
61   echo "$*"
62   exit 1
63 }
64
65 deploy() {
66   LEAP_CMD deploy "$TAG"
67 }
68
69 test() {
70   LEAP_CMD test "$TAG"
71 }
72
73 ssh_setup() {
74   # set the provider name from the first argument passed to the function
75   provider_name=$1
76   # set CI_SSH_SECRET_PRIVATE_KEY to the variable name keyed off of the provider_name
77   CI_SSH_SECRET_PRIVATE_KEY=${provider_name}_PROVIDER_SSH_PRIVATE_KEY
78   # Set the SSH_PRIVATE_KEY to the value provided in the CI runner secret variable setting in gitlab
79   SSH_PRIVATE_KEY=${!CI_SSH_SECRET_PRIVATE_KEY}
80   echo "Working with provider: $provider_name"
81   [ -z "$SSH_PRIVATE_KEY" ] && fail "${provider_name}_PROVIDER_SSH_PRIVATE_KEY is not set - please provide it as env variable."
82   # Configure ssh keypair
83   [ -d ~/.ssh ] || /bin/mkdir ~/.ssh
84   /bin/echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
85   /bin/chmod 600 ~/.ssh/id_rsa
86   /bin/cp "${ROOTDIR}/provider/users/gitlab-runner-${provider_name}/gitlab-runner-${provider_name}_ssh.pub" ~/.ssh/id_rsa.pub
87 }
88
89 build_from_scratch() {
90   # setup ssh keys
91   ssh_setup platform
92
93   # allow passing into the function the services, use a default set if empty
94   SERVICES=$1
95   if [ -z "$SERVICES" ]
96   then
97       SERVICES='couchdb,soledad,mx,webapp,tor_relay,monitor'
98   fi
99
100   # when using gitlab-runner locally, CI_JOB_ID is always 1 which
101   # will conflict with running/terminating AWS instances in subsequent runs
102   # therefore we pick a random number in this case
103   [ "${CI_JOB_ID}" == "1" ] && CI_JOB_ID="000${RANDOM}"
104
105   # create node(s) with unique id so we can run tests in parallel
106   NAME="citest${CI_JOB_ID:-0}"
107   TAG='single'
108
109   # leap_platform/tests/platform-ci/provider
110   PROVIDERDIR="${ROOTDIR}/provider"
111   /bin/echo "Provider directory: ${PROVIDERDIR}"
112   cd "$PROVIDERDIR"
113
114   # Create cloud.json needed for `leap vm` commands using AWS credentials
115   which jq || ( apt-get update -y && apt-get install jq -y )
116
117   # Disable xtrace
118   set +x
119
120   [ -z "$AWS_ACCESS_KEY" ]  && fail "\$AWS_ACCESS_KEY  is not set - please provide it as env variable."
121   [ -z "$AWS_SECRET_KEY" ]  && fail "\$AWS_SECRET_KEY  is not set - please provide it as env variable."
122
123   /usr/bin/jq ".platform_ci.auth |= .+ {\"aws_access_key_id\":\"$AWS_ACCESS_KEY\", \"aws_secret_access_key\":\"$AWS_SECRET_KEY\"}" < cloud.json.template > cloud.json
124   # Enable xtrace again only if it was set at beginning of script
125   [[ $xtrace == true ]] && set -x
126
127   [ -d "./tags" ] || mkdir "./tags"
128   /bin/echo "{\"environment\": \"$TAG\"}" | /usr/bin/json_pp > "${PROVIDERDIR}/tags/${TAG}.json"
129
130   # configure deb repo component
131   echo '{}' | jq ".sources.platform.apt |= { \"source\": \"http://deb.leap.se/platform\", \"component\": \"${COMPONENT}\" }" > common.json
132
133   # remove old cached nodes
134   echo "Removing old cached nodes..."
135   find nodes -name 'citest*' -exec rm {} \;
136
137   echo "Listing current VM status..."
138   LEAP_CMD vm status "$TAG"
139   # shellcheck disable=SC2086
140   echo "Adding VM $NAME with the services: $SERVICES and the tags: $TAG"
141   LEAP_CMD vm add "$NAME" services:"$SERVICES" tags:"$TAG"
142   echo "Compiling $TAG..."
143   LEAP_CMD compile "$TAG"
144   echo "Listing current VM status for TAG: $TAG..."
145   LEAP_CMD vm status "$TAG"
146
147   echo "Running leap list..."
148   LEAP_CMD list
149
150   echo "Running leap node init on TAG: $TAG"
151   LEAP_CMD node init "$TAG"
152   echo "Running leap info on $TAG"
153   LEAP_CMD info "${TAG}"
154 }
155
156 run() {
157   provider_name=$1
158   provider_URI=$2
159   platform_branch=$3
160
161   # setup ssh keys
162   ssh_setup "$provider_name"
163
164   # Setup the provider repository
165   echo "Setting up the provider repository: $provider_name by cloning $provider_URI"
166   git clone -q --depth 1 "$provider_URI"
167   cd "$provider_name"
168   echo -n "$provider_name repo at revision: "
169   git rev-parse HEAD
170   echo -n "Operating in the $provider_name directory: "
171   pwd
172
173
174   # If the third argument is set make sure we are on that platform branch
175   if [[ -n $platform_branch ]]
176   then
177       echo "Checking out $platform_branch branch of platform"
178       cd "$PLATFORMDIR"
179       git checkout -B "$platform_branch"
180   fi
181
182   cd "${ROOTDIR}/${provider_name}"
183   echo "Listing current node information..."
184   LEAP_CMD list
185
186   # Do the deployment
187   echo "Attempting a deploy..."
188   LEAP_CMD cert renew "$CI_JOB_NAME"
189   deploy
190   echo "Attempting to run tests..."
191   test
192 }
193
194 soledad_migration() {
195   # check the version of soledad installed
196   # if the version is not greater than 0.9, we need to do the migration
197   if ! LEAP_CMD run "dpkg --compare-versions \$(dpkg -l |grep soledad-server|grep ^ii|awk '{ print \$3}') gt 0.9" vm |grep -q oops
198   then
199       echo "Need to migrate from soledad 0.9!"
200       if ! LEAP_CMD run 'systemctl stop leap-mx' vm
201       then fail
202       fi
203       if ! LEAP_CMD run 'systemctl stop soledad-server' vm
204       then fail
205       fi
206       if ! LEAP_CMD run --stream '/usr/share/soledad-server/migration/0.9/migrate.py --verbose --log-file /var/log/leap/soledad_migration.log --do-migrate' vm
207       then fail
208       fi
209       if ! LEAP_CMD run 'systemctl start leap-mx' vm
210       then fail
211       fi
212       if ! LEAP_CMD run 'systemctl start soledad-server' vm
213       then fail
214       fi
215   fi
216 }
217
218 upgrade_test() {
219   # Checkout stable branch containing previous stable release
220   # and deploy this
221   cd "$PLATFORMDIR"
222   # due to cache, this remote is sometimes already added
223   git remote add leap https://leap.se/git/leap_platform || true
224   git fetch leap
225   echo "Checking out leap/stable"
226   git checkout -b leap_stable remotes/leap/stable || true
227   echo -n "Current version: "
228   git rev-parse HEAD
229   # After checking out a different platform branch
230   # bundle install is needed again
231   cd "$ROOTDIR"
232   /usr/local/bin/bundle install
233
234   cd "$PROVIDERDIR"
235   LEAP_CMD --version
236   build_from_scratch 'couchdb,soledad,mx,webapp,tor,monitor'
237   deploy
238   test
239
240   # Checkout HEAD of current branch and re-deploy
241   cd "$PLATFORMDIR"
242   echo "Checking out: $CI_COMMIT_SHA"
243   git checkout "$CI_COMMIT_SHA"
244   echo -n "Current version: "
245   git rev-parse HEAD
246   # After checking out a different platform branch
247   # bundle install is needed again
248   cd "$ROOTDIR"
249   /usr/local/bin/bundle install
250
251   cd "$PROVIDERDIR"
252   LEAP_CMD --version
253   
254   # due to the 'tor' service no longer being valid in 0.10, we need to change
255   # that service to 'tor_relay'. This is done by changing the services array
256   # with jq to be set to the full correct list of services
257   jq '.services = ["couchdb","soledad","mx","webapp","tor_relay","monitor"]' < nodes/${NAME}.json
258   deploy
259
260   # check for soledad migration, and run it if necessary
261   soledad_migration
262
263   test
264
265   cleanup
266
267 }
268
269 cleanup() {
270   # if everything succeeds, destroy the vm
271   LEAP_CMD vm rm "${TAG}"
272   [ -f "nodes/${NAME}.json" ] && /bin/rm "nodes/${NAME}.json"
273 }
274
275 #
276 # Main
277 #
278
279 /bin/echo "CI directory: ${ROOTDIR}"
280 /bin/echo "Platform directory: ${PLATFORMDIR}"
281
282 # Ensure we don't output secret stuff to console even when running in verbose mode with -x
283 set +x
284
285 # Enable xtrace again only if it was set at beginning of script
286 [[ $xtrace == true ]] && set -x
287
288 case "$CI_JOB_NAME" in
289   ci.leap.se)
290     TAG='latest'
291     run ibex ssh://gitolite@leap.se/ibex
292     ;;
293   mail.bitmask.net)
294     TAG='demomail'
295     run bitmask ssh://gitolite@leap.se/bitmask master
296     ;;
297   demo.bitmask.net)
298     TAG='demovpn'
299     run bitmask ssh://gitolite@leap.se/bitmask master
300     ;;
301   deploy_test*)
302     build_from_scratch
303     deploy
304     test
305     cleanup
306     ;;
307   upgrade_test)
308     upgrade_test
309     ;;
310   *)
311     fail "Don't know what to do for \$CI_JOB_NAME \"$CI_JOB_NAME\"!"
312     ;;
313 esac