843642a42ac33e3131814f8a8f5d990e983e35b7
[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 upgrade_test() {
195   # Checkout stable branch containing last release
196   # and deploy this
197   cd "$PLATFORMDIR"
198   # due to cache, this remote is sometimes already added
199   git remote add leap https://leap.se/git/leap_platform || true
200   git fetch leap
201   echo "Checking out leap/stable"
202   git checkout -b leap_stable remotes/leap/stable || true
203   echo -n "Current version: "
204   git rev-parse HEAD
205   # After checking out a different platform branch
206   # bundle install is needed again
207   cd "$ROOTDIR"
208   /usr/local/bin/bundle install
209
210   cd "$PROVIDERDIR"
211
212   build_from_scratch 'couchdb,soledad,mx,webapp,tor,monitor'
213   deploy
214   test
215
216   # Checkout HEAD of current branch and re-deploy
217   cd "$PLATFORMDIR"
218   echo "Checking out: $CI_COMMIT_SHA"
219   git checkout "$CI_COMMIT_SHA"
220   echo -n "Current version: "
221   git rev-parse HEAD
222   # After checking out a different platform branch
223   # bundle install is needed again
224   cd "$ROOTDIR"
225   /usr/local/bin/bundle install
226
227   cd "$PROVIDERDIR"
228
229   # due to the 'tor' service no longer being valid in 0.10, we need to change
230   # that service to 'tor_relay'. This is done by changing the services array
231   # with jq to be set to the full correct list of services
232   jq '.services = ["couchdb","soledad","mx","webapp","tor_relay","monitor"]' < nodes/${NAME}.json
233   deploy
234   test
235
236   cleanup
237
238 }
239
240 cleanup() {
241   # if everything succeeds, destroy the vm
242   LEAP_CMD vm rm "${TAG}"
243   [ -f "nodes/${NAME}.json" ] && /bin/rm "nodes/${NAME}.json"
244 }
245
246 #
247 # Main
248 #
249
250 /bin/echo "CI directory: ${ROOTDIR}"
251 /bin/echo "Platform directory: ${PLATFORMDIR}"
252
253 # Ensure we don't output secret stuff to console even when running in verbose mode with -x
254 set +x
255
256 # Enable xtrace again only if it was set at beginning of script
257 [[ $xtrace == true ]] && set -x
258
259 case "$CI_JOB_NAME" in
260   ci.leap.se)
261     TAG='latest'
262     run ibex ssh://gitolite@leap.se/ibex
263     ;;
264   mail.bitmask.net)
265     TAG='demomail'
266     run bitmask ssh://gitolite@leap.se/bitmask master
267     ;;
268   demo.bitmask.net)
269     TAG='demovpn'
270     run bitmask ssh://gitolite@leap.se/bitmask master
271     ;;
272   deploy_test*)
273     build_from_scratch
274     deploy
275     test
276     cleanup
277     ;;
278   upgrade_test)
279     upgrade_test
280     ;;
281   *)
282     fail "Don't know what to do for \$CI_JOB_NAME \"$CI_JOB_NAME\"!"
283     ;;
284 esac