GitLab CI custom executor to help Beaker jobs clean up their own VMs
beaker-cleanup-driver is a GitLab CI runner custom executor that properly cleans up each CI job’s child processes and VMs―even if
the job failed, was cancelled, or timed out (probably).
It is designed to run multi-node acceptance tests using Puppet’s
Beaker while avoiding the shell executor’s tendency to
accumulate hundreds of gigs of disk space and running VM processes, left
over from jobs that didn’t terminate cleanly.
As root, clone the contents of this repository into a directory on the runner,
and make sure that the gitlab-runner
user can read and execute the directory
path and the *.sh
scripts:
# We'll keep using this $CUSTOM_EXECUTOR_DIR in the next example, too
CUSTOM_EXECUTOR_DIR=/opt/simp/gitlab-runner/beaker-cleanup-driver
THIS_REPOSITORY_URL="<the url of this git repository>"
umask 0027
git clone "$THIS_REPOSITORY_URL" "$CUSTOM_EXECUTOR_DIR"
# Ensure that gitlab-runner can read and execute the scripts
chgrp -R gitlab-runner "$CUSTOM_EXECUTOR_DIR"
chmod -R g=u-w "$CUSTOM_EXECUTOR_DIR"
A Gitlab Runner configuration template file
is provided to simplify registration.
Tailor the template file beaker-cleanup-driver.template.toml
_exec
entries in the [runners.custom]
section are under the$CUSTOM_EXECUTOR_DIR
).Register a new GitLab Runner using the --template-config
option:
gitlab-runner register \
--name "$RUNNER_NAME" \
--registration-token "$REGISTRATION_TOKEN" \
--url "${CI_SERVER_URL:-https://gitlab.com/}" \
--executor custom \
--template-config "$CUSTOM_EXECUTOR_DIR/beaker-cleanup-driver.template.toml" \
--tag-list "${RUNNER_TAG_LIST:-beaker}" \
--non-interactive \
--paused \
--locked
For more information, see GitLab’s documentation about Registering Runners
You can set environment variables (in the job_env
key of the executor’s config_exec.sh
script[0])
Environment Variable | Purpose | Default |
---|---|---|
CI_RUNNER_USER |
non-privileged build user | gitlab-runner |
CI_RUNNER_USER_DIR |
parent path for non-privileged build user’s build/cache directories | /var/lib/${CI_RUNNER_USER} |
Beaker (and its VM orchestration) does not lend itself to using PID files, so
instead the custom executor “tags” every process it starts with a unique
environment variable:
$_CI_JOB_TAG
to$_CI_JOB_TAG
set to this samecleanup_exec
stage executes, all processes with $_CI_JOB_TAG
setvagrant global-status --prune
will run if any VMs were shut down/proc/*/environ
for the$_CI_JOB_TAG
value$_CI_JOB_TAG
pid’s associated/proc/$pid/cmdline
for VBoxHeadlessThe technique of tagging processes for later cleanup using environment
variables (and identifying them via /proc/*/environ
) was informed by the
discussion at https://serverfault.com/a/274613 .
beaker-cleanup-driver
The custom executor logs its activity to the Runner console output and to
journald under the syslog identifier beaker-cleanup-driver
.
You can follow these messages via journalctl
:
journalctl -t beaker-cleanup-driver -f
While troubleshooting, you are likely to only be interested in messages from a
single job. To see a specific job’s progress, grep for the job’s unique_CI_JOB_TAG
value (shown in the Runner console output at the beginning of
every exec stage and sub-stage):
journalctl -t beaker-cleanup-driver -n 3000 -e | egrep _CI_JOB_TAG=runner-1751173-project-17669670-concurrent-0-487152645 -A5 -B6 | less
gitlab-runner
serviceThe gitlab-runner
unit’s journald log can also be useful for correlating the
Runner’s communication and setup events during troubleshooting. Depending on
the gitlab-runner’s debug_level
, some executor messages (ONLY from thecleanup_exec
stage) will also appear in this log.
You can follow the unit’s log via journalctl
:
journalctl -u gitlab-runner -f -n 3000
The gitlab-runner’s log can have a lot of noise in addition to the executor
output To help filter the noise, you can grep the logs:
journalctl -u gitlab-runner -e -n 3000 | egrep '==|--' | less
To follow a specific job’s progress, grep for the _CI_JOB_TAG value (shown in
the Runner console output at the beginning of every exec stage and sub-stage):
journalctl -u gitlab-runner -e | grep _CI_JOB_TAG=runner-1751173-project-17669670-concurrent-0-485904412
gitlab-runner
unit’s journald log only includes output from thecleanup_exec
script (when log_level
is warn
or higher)