[CI] Fix tests/platform-ci/README.md env var typo
[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 leap_info() {
70   echo "Running leap info on $TAG"
71   LEAP_CMD info "${TAG}"
72 }
73
74 test() {
75   LEAP_CMD test "$TAG"
76 }
77
78 ssh_setup() {
79   # set the provider name from the first argument passed to the function
80   provider_name=$1
81   # set CI_SSH_SECRET_PRIVATE_KEY to the variable name keyed off of the provider_name
82   CI_SSH_SECRET_PRIVATE_KEY=${provider_name}_PROVIDER_SSH_PRIVATE_KEY
83   # Set the SSH_PRIVATE_KEY to the value provided in the CI runner secret variable setting in gitlab
84   SSH_PRIVATE_KEY=${!CI_SSH_SECRET_PRIVATE_KEY}
85   echo "Working with provider: $provider_name"
86   [ -z "$SSH_PRIVATE_KEY" ] && fail "${provider_name}_PROVIDER_SSH_PRIVATE_KEY is not set - please provide it as env variable."
87   # install ssh-agent
88   which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )
89   # run ssh-agent
90   eval $(ssh-agent -s)
91   # add ssh key stored in SSH_PRIVATE_KEY variable to the agent store
92   # see https://gitlab.com/gitlab-org/gitlab-ee/issues/2940 for fixing
93   # broken line endings
94   ssh-add <(echo "$SSH_PRIVATE_KEY" | sed 's/\r$//')
95 }
96
97 build_from_scratch() {
98   # setup ssh keys
99   ssh_setup platform
100
101   # allow passing into the function the services, use a default set if empty
102   SERVICES=$1
103   if [ -z "$SERVICES" ]
104   then
105       SERVICES='couchdb,soledad,mx,webapp,tor_relay,monitor'
106   fi
107
108   # when using gitlab-runner locally, CI_JOB_ID is always 1 which
109   # will conflict with running/terminating AWS instances in subsequent runs
110   # therefore we pick a random number in this case
111   [ "${CI_JOB_ID}" == "1" ] && CI_JOB_ID="000${RANDOM}"
112
113   # create node(s) with unique id so we can run tests in parallel
114   NAME="citest${CI_JOB_ID:-0}"
115   TAG='single'
116
117   # leap_platform/tests/platform-ci/provider
118   PROVIDERDIR="${ROOTDIR}/provider"
119   /bin/echo "Provider directory: ${PROVIDERDIR}"
120   cd "$PROVIDERDIR"
121
122   # Create cloud.json needed for `leap vm` commands using AWS credentials
123   which jq || ( apt-get update -y && apt-get install jq -y )
124
125   # Disable xtrace
126   set +x
127
128   [ -z "$AWS_ACCESS_KEY" ]  && fail "\$AWS_ACCESS_KEY  is not set - please provide it as env variable."
129   [ -z "$AWS_SECRET_KEY" ]  && fail "\$AWS_SECRET_KEY  is not set - please provide it as env variable."
130
131   /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
132   # Enable xtrace again only if it was set at beginning of script
133   [[ $xtrace == true ]] && set -x
134
135   [ -d "./tags" ] || mkdir "./tags"
136   /bin/echo "{\"environment\": \"$TAG\"}" | /usr/bin/json_pp > "${PROVIDERDIR}/tags/${TAG}.json"
137
138   # configure deb repo component
139   echo '{}' | jq ".sources.platform.apt |= { \"source\": \"http://deb.leap.se/platform\", \"component\": \"${COMPONENT}\" }" > common.json
140
141   # remove old cached nodes
142   echo "Removing old cached nodes..."
143   find nodes -name 'citest*' -exec rm {} \;
144
145   echo "Listing current VM status..."
146   LEAP_CMD vm status "$TAG"
147   # shellcheck disable=SC2086
148   echo "Adding VM $NAME with the services: $SERVICES and the tags: $TAG"
149   LEAP_CMD vm add "$NAME" services:"$SERVICES" tags:"$TAG"
150   echo "Compiling $TAG..."
151   LEAP_CMD compile "$TAG"
152   echo "Listing current VM status for TAG: $TAG..."
153   LEAP_CMD vm status "$TAG"
154
155   echo "Running leap list..."
156   LEAP_CMD list
157
158   echo "Running leap node init on TAG: $TAG"
159   LEAP_CMD node init "$TAG"
160 }
161
162 run() {
163   provider_name=$1
164   provider_URI=$2
165   platform_branch=$3
166
167   # setup ssh keys
168   ssh_setup "$provider_name"
169
170   # Setup the provider repository
171   echo "Setting up the provider repository: $provider_name by cloning $provider_URI"
172   git clone -q --depth 1 "$provider_URI"
173   cd "$provider_name"
174   echo -n "$provider_name repo at revision: "
175   git rev-parse HEAD
176   echo -n "Operating in the $provider_name directory: "
177   pwd
178
179
180   # If the third argument is set make sure we are on that platform branch
181   if [[ -n $platform_branch ]]
182   then
183       echo "Checking out $platform_branch branch of platform"
184       cd "$PLATFORMDIR"
185       git checkout -B "$platform_branch"
186   fi
187
188   cd "${ROOTDIR}/${provider_name}"
189   echo "Listing current node information..."
190   LEAP_CMD list
191
192   # Do the deployment
193   echo "Attempting a deploy..."
194   LEAP_CMD cert renew "$CI_JOB_NAME"
195   deploy
196   echo "Attempting to run tests..."
197   test
198 }
199
200 soledad_migration() {
201   # check the version of soledad installed
202   # if the version is not greater than 0.9, we need to do the migration
203   if ! LEAP_CMD run "dpkg --compare-versions \$(dpkg -l |grep soledad-server|grep ^ii|awk '{ print \$3}') gt 0.8" vm |grep -q oops
204   then
205       echo "Need to migrate from soledad 0.8!"
206       if ! LEAP_CMD run 'systemctl stop leap-mx' vm
207       then fail
208       fi
209       if ! LEAP_CMD run 'systemctl stop soledad-server' vm
210       then fail
211       fi
212       if ! LEAP_CMD run --stream '/usr/share/soledad-server/migration/0.9/migrate.py --log-file /dev/stdout --verbose --do-migrate | tee /var/log/leap/soledad_migration.log' vm
213       then fail
214       fi
215       if ! LEAP_CMD run 'systemctl start leap-mx' vm
216       then fail
217       fi
218       if ! LEAP_CMD run 'systemctl start soledad-server' vm
219       then fail
220       fi
221   fi
222 }
223
224 upgrade_test() {
225   # Checkout stable branch containing previous stable release
226   # and deploy this
227   cd "$PLATFORMDIR"
228   # due to cache, this remote is sometimes already added
229   git remote add leap https://leap.se/git/leap_platform || true
230   git fetch leap
231   echo "Checking out leap/stable"
232   git checkout -b leap_stable remotes/leap/stable || true
233   echo -n "Current version: "
234   git rev-parse HEAD
235   # After checking out a different platform branch
236   # bundle install is needed again
237   cd "$ROOTDIR"
238   /usr/local/bin/bundle install
239
240   cd "$PROVIDERDIR"
241   LEAP_CMD --version
242   build_from_scratch 'couchdb,soledad,mx,webapp,tor,monitor'
243   deploy
244   leap_info
245   # In 0.9 leap info did not output apt sources, so we do it manually
246   # but can remove it for next release
247   cat /etc/apt/sources.list.d/*
248   test
249
250   # Checkout HEAD of current branch and re-deploy
251   cd "$PLATFORMDIR"
252   echo "Checking out: $CI_COMMIT_SHA"
253   git checkout "$CI_COMMIT_SHA"
254   echo -n "Current version: "
255   git rev-parse HEAD
256   # After checking out a different platform branch
257   # bundle install is needed again
258   cd "$ROOTDIR"
259   /usr/local/bin/bundle install
260
261   cd "$PROVIDERDIR"
262   LEAP_CMD --version
263
264   # due to the 'tor' service no longer being valid in 0.10, we need to change
265   # that service to 'tor_relay'. This is done by changing the services array
266   # with jq to be set to the full correct list of services
267   jq '.services = ["couchdb","soledad","mx","webapp","tor_relay","monitor"]' < nodes/${NAME}.json
268   deploy
269
270   # pre-migration test
271   # allowed to fail because when a migration is needed, soledad-server refuses to start
272   test || /bin/true
273
274   # check for soledad migration, and run it if necessary
275   soledad_migration
276
277   leap_info
278
279   # run the test again, this should succeed
280   test
281
282   cleanup
283
284 }
285
286 cleanup() {
287   # if everything succeeds, destroy the vm
288   LEAP_CMD vm rm "${TAG}"
289   [ -f "nodes/${NAME}.json" ] && /bin/rm "nodes/${NAME}.json"
290 }
291
292 #
293 # Main
294 #
295
296 /bin/echo "CI directory: ${ROOTDIR}"
297 /bin/echo "Platform directory: ${PLATFORMDIR}"
298
299 # Ensure we don't output secret stuff to console even when running in verbose mode with -x
300 set +x
301
302 # Enable xtrace again only if it was set at beginning of script
303 [[ $xtrace == true ]] && set -x
304
305 case "$CI_JOB_NAME" in
306   ci.leap.se)
307     TAG='latest'
308     run ibex ssh://gitolite@leap.se/ibex
309     ;;
310   mail.bitmask.net)
311     TAG='demomail'
312     run bitmask ssh://gitolite@leap.se/bitmask master
313     ;;
314   demo.bitmask.net)
315     TAG='demovpn'
316     run bitmask ssh://gitolite@leap.se/bitmask master
317     ;;
318   deploy_test*)
319     build_from_scratch
320     deploy
321     leap_info
322     test
323     cleanup
324     ;;
325   upgrade_test)
326     upgrade_test
327     ;;
328   *)
329     fail "Don't know what to do for \$CI_JOB_NAME \"$CI_JOB_NAME\"!"
330     ;;
331 esac