summaryrefslogtreecommitdiff
path: root/tests/platform-ci/ci-build.sh
blob: 2b6657499789e98ba0506d0aa8d49994e857f4a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
#!/bin/bash
#
# This script will run create a virtual provider
# and run tests on it.
#
# This script is triggered by .gitlab-ci.yml
#
# It depends on:
#   * leap_platform: in ../..
#   * test provider: in provider/
#   * leap-platform-test: installed in path
#   * AWS credentials as environment variables:
#     * `AWS_ACCESS_KEY`
#     * `AWS_SECRET_KEY`
#   * ssh private keys used to clone providers:
#     * `bitmask_PROVIDER_SSH_PRIVATE_KEY`
#     * `ibex_PROVIDER_SSH_PRIVATE_KEY`

# exit if any commands returns non-zero status
set -e
# because the ci-build is running in a pipe we need to also set the following
# so exit codes will be caught correctly.
set -o pipefail

# Check if scipt is run in debug mode so we can hide secrets
if [[ "$-" =~ 'x' ]]
then
  echo 'Running with xtrace enabled!'
  xtrace=true
else
  echo 'Running with xtrace disabled!'
  xtrace=false
fi

# leap_platform/tests/platform-ci
# shellcheck disable=SC2086
ROOTDIR=$(readlink -f "$(dirname $0)")

# leap_platform
PLATFORMDIR=$(readlink -f "${ROOTDIR}/../..")

# deb repo component to configure
COMPONENT=${COMPONENT:-"master"}

# In the gitlab CI pipeline leap is installed in a different
# stage by bundle. To debug you can run a single CI job locally
# so we install leap_cli as gem here.
if /usr/local/bin/bundle exec leap >/dev/null 2>&1
then
  LEAP_CMD() {
    /usr/local/bin/bundle exec leap -v2 --yes "$@"
  }
else
  sudo gem install leap_cli
  LEAP_CMD() {
    leap -v2 --yes "$@"
  }
fi

fail() {
  echo "$*"
  exit 1
}

deploy() {
  LEAP_CMD deploy "$TAG"
}

test() {
  LEAP_CMD test "$TAG"
}

ssh_setup() {
  # set the provider name from the first argument passed to the function
  provider_name=$1
  # set CI_SSH_SECRET_PRIVATE_KEY to the variable name keyed off of the provider_name
  CI_SSH_SECRET_PRIVATE_KEY=${provider_name}_PROVIDER_SSH_PRIVATE_KEY
  # Set the SSH_PRIVATE_KEY to the value provided in the CI runner secret variable setting in gitlab
  SSH_PRIVATE_KEY=${!CI_SSH_SECRET_PRIVATE_KEY}
  echo "Working with provider: $provider_name"
  [ -z "$SSH_PRIVATE_KEY" ] && fail "${provider_name}_PROVIDER_SSH_PRIVATE_KEY is not set - please provide it as env variable."
  # Configure ssh keypair
  [ -d ~/.ssh ] || /bin/mkdir ~/.ssh
  /bin/echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
  /bin/chmod 600 ~/.ssh/id_rsa
  /bin/cp "${ROOTDIR}/provider/users/gitlab-runner-${provider_name}/gitlab-runner-${provider_name}_ssh.pub" ~/.ssh/id_rsa.pub
}

build_from_scratch() {
  # setup ssh keys
  ssh_setup platform

  # allow passing into the function the services, use a default set if empty
  SERVICES=$1
  if [ -z "$SERVICES" ]
  then
      SERVICES='couchdb,soledad,mx,webapp,tor_relay,monitor'
  fi

  # when using gitlab-runner locally, CI_JOB_ID is always 1 which
  # will conflict with running/terminating AWS instances in subsequent runs
  # therefore we pick a random number in this case
  [ "${CI_JOB_ID}" == "1" ] && CI_JOB_ID="000${RANDOM}"

  # create node(s) with unique id so we can run tests in parallel
  NAME="citest${CI_JOB_ID:-0}"
  TAG='single'

  # leap_platform/tests/platform-ci/provider
  PROVIDERDIR="${ROOTDIR}/provider"
  /bin/echo "Provider directory: ${PROVIDERDIR}"
  cd "$PROVIDERDIR"

  # Create cloud.json needed for `leap vm` commands using AWS credentials
  which jq || ( apt-get update -y && apt-get install jq -y )

  # Disable xtrace
  set +x

  [ -z "$AWS_ACCESS_KEY" ]  && fail "\$AWS_ACCESS_KEY  is not set - please provide it as env variable."
  [ -z "$AWS_SECRET_KEY" ]  && fail "\$AWS_SECRET_KEY  is not set - please provide it as env variable."

  /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
  # Enable xtrace again only if it was set at beginning of script
  [[ $xtrace == true ]] && set -x

  [ -d "./tags" ] || mkdir "./tags"
  /bin/echo "{\"environment\": \"$TAG\"}" | /usr/bin/json_pp > "${PROVIDERDIR}/tags/${TAG}.json"

  # configure deb repo component
  echo '{}' | jq ".sources.platform.apt |= { \"source\": \"http://deb.leap.se/platform\", \"component\": \"${COMPONENT}\" }" > common.json

  # remove old cached nodes
  echo "Removing old cached nodes..."
  find nodes -name 'citest*' -exec rm {} \;

  echo "Listing current VM status..."
  LEAP_CMD vm status "$TAG"
  # shellcheck disable=SC2086
  echo "Adding VM $NAME with the services: $SERVICES and the tags: $TAG"
  LEAP_CMD vm add "$NAME" services:"$SERVICES" tags:"$TAG"
  echo "Compiling $TAG..."
  LEAP_CMD compile "$TAG"
  echo "Listing current VM status for TAG: $TAG..."
  LEAP_CMD vm status "$TAG"

  echo "Running leap list..."
  LEAP_CMD list

  echo "Running leap node init on TAG: $TAG"
  LEAP_CMD node init "$TAG"
  echo "Running leap info on $TAG"
  LEAP_CMD info "${TAG}"
}

run() {
  provider_name=$1
  provider_URI=$2
  platform_branch=$3

  # setup ssh keys
  ssh_setup "$provider_name"

  # Setup the provider repository
  echo "Setting up the provider repository: $provider_name by cloning $provider_URI"
  git clone -q --depth 1 "$provider_URI"
  cd "$provider_name"
  echo -n "$provider_name repo at revision: "
  git rev-parse HEAD
  echo -n "Operating in the $provider_name directory: "
  pwd


  # If the third argument is set make sure we are on that platform branch
  if [[ -n $platform_branch ]]
  then
      echo "Checking out $platform_branch branch of platform"
      cd "$PLATFORMDIR"
      git checkout -B "$platform_branch"
  fi

  cd "${ROOTDIR}/${provider_name}"
  echo "Listing current node information..."
  LEAP_CMD list

  # Do the deployment
  echo "Attempting a deploy..."
  LEAP_CMD cert renew "$CI_JOB_NAME"
  deploy
  echo "Attempting to run tests..."
  test
}

soledad_migration() {
  # check the version of soledad installed
  # if the version is not greater than 0.9, we need to do the migration
  if ! LEAP_CMD run "dpkg --compare-versions \$(dpkg -l |grep soledad-server|grep ^ii|awk '{ print \$3}') gt 0.9" vm |grep -q oops
  then
      echo "Need to migrate from soledad 0.9!"
      if ! LEAP_CMD run 'systemctl stop leap-mx' vm
      then fail
      fi
      if ! LEAP_CMD run 'systemctl stop soledad-server' vm
      then fail
      fi
      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
      then fail
      fi
      if ! LEAP_CMD run 'systemctl start leap-mx' vm
      then fail
      fi
      if ! LEAP_CMD run 'systemctl start soledad-server' vm
      then fail
      fi
  fi
}

upgrade_test() {
  # Checkout stable branch containing previous stable release
  # and deploy this
  cd "$PLATFORMDIR"
  # due to cache, this remote is sometimes already added
  git remote add leap https://leap.se/git/leap_platform || true
  git fetch leap
  echo "Checking out leap/stable"
  git checkout -b leap_stable remotes/leap/stable || true
  echo -n "Current version: "
  git rev-parse HEAD
  # After checking out a different platform branch
  # bundle install is needed again
  cd "$ROOTDIR"
  /usr/local/bin/bundle install

  cd "$PROVIDERDIR"
  LEAP_CMD --version
  build_from_scratch 'couchdb,soledad,mx,webapp,tor,monitor'
  deploy
  test

  # Checkout HEAD of current branch and re-deploy
  cd "$PLATFORMDIR"
  echo "Checking out: $CI_COMMIT_SHA"
  git checkout "$CI_COMMIT_SHA"
  echo -n "Current version: "
  git rev-parse HEAD
  # After checking out a different platform branch
  # bundle install is needed again
  cd "$ROOTDIR"
  /usr/local/bin/bundle install

  cd "$PROVIDERDIR"
  LEAP_CMD --version
  
  # due to the 'tor' service no longer being valid in 0.10, we need to change
  # that service to 'tor_relay'. This is done by changing the services array
  # with jq to be set to the full correct list of services
  jq '.services = ["couchdb","soledad","mx","webapp","tor_relay","monitor"]' < nodes/${NAME}.json
  deploy

  # pre-migration test
  test

  # check for soledad migration, and run it if necessary
  soledad_migration

  # run the test again, this should succeed
  test

  cleanup

}

cleanup() {
  # if everything succeeds, destroy the vm
  LEAP_CMD vm rm "${TAG}"
  [ -f "nodes/${NAME}.json" ] && /bin/rm "nodes/${NAME}.json"
}

#
# Main
#

/bin/echo "CI directory: ${ROOTDIR}"
/bin/echo "Platform directory: ${PLATFORMDIR}"

# Ensure we don't output secret stuff to console even when running in verbose mode with -x
set +x

# Enable xtrace again only if it was set at beginning of script
[[ $xtrace == true ]] && set -x

case "$CI_JOB_NAME" in
  ci.leap.se)
    TAG='latest'
    run ibex ssh://gitolite@leap.se/ibex
    ;;
  mail.bitmask.net)
    TAG='demomail'
    run bitmask ssh://gitolite@leap.se/bitmask master
    ;;
  demo.bitmask.net)
    TAG='demovpn'
    run bitmask ssh://gitolite@leap.se/bitmask master
    ;;
  deploy_test*)
    build_from_scratch
    deploy
    test
    cleanup
    ;;
  upgrade_test)
    upgrade_test
    ;;
  *)
    fail "Don't know what to do for \$CI_JOB_NAME \"$CI_JOB_NAME\"!"
    ;;
esac