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