This post is part of a series about trying to setup a gitlab runner based on systemd-nspawn. I published the polished result as nspawn-runner on GitHub.
gitlab-runner
supports adding extra arguments to the custom scripts,
and I can take advantage of that to pack all the various scripts that I
prototyped so far into an all-in-one nspawn-runner
command:
usage: nspawn-runner [-h] [-v] [--debug]
{chroot-create,chroot-login,prepare,run,cleanup,gitlab-config,toml}
...
Manage systemd-nspawn machines for CI runs.
positional arguments:
{chroot-create,chroot-login,prepare,run,cleanup,gitlab-config,toml}
sub-command help
chroot-create create a chroot that serves as a base for ephemeral
machines
chroot-login enter the chroot to perform maintenance
prepare start an ephemeral system for a CI run
run run a command inside a CI machine
cleanup cleanup a CI machine after it's run
gitlab-config configuration step for gitlab-runner
toml output the toml configuration for the custom runner
optional arguments:
-h, --help show this help message and exit
-v, --verbose verbose output
--debug verbose output
chroot maintenance
chroot-create
and chroot-login
are similar to what
pbuilder,
cowbuilder,
schroot,
debspawn and similar tools do.
They only take a chroot name, and default the rest of paths to where
nspawn-runner
expects things to be under /var/lib/nspawn-runner
.
gitlab-runner setup
nspawn-runner toml <chroot-name>
outputs a snippet to add to
/etc/gitlab-runner/config.toml
to configure the CI.
For example:`
$ ./nspawn-runner toml buster
[[runners]]
name="buster"
url="TODO"
token="TODO"
executor = "custom"
builds_dir = "/var/lib/nspawn-runner/.build"
cache_dir = "/var/lib/nspawn-runner/.cache"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.custom]
config_exec = "/home/enrico/…/nspawn-runner/nspawn-runner"
config_args = ["gitlab-config"]
config_exec_timeout = 200
prepare_exec = "/home/enrico/…/nspawn-runner/nspawn-runner"
prepare_args = ["prepare", "buster"]
prepare_exec_timeout = 200
run_exec = "/home/enrico/dev/nspawn-runner/nspawn-runner"
run_args = ["run"]
cleanup_exec = "/home/enrico/…/nspawn-runner/nspawn-runner"
cleanup_args = ["cleanup"]
cleanup_exec_timeout = 200
graceful_kill_timeout = 200
force_kill_timeout = 200
One needs to remember to set url
and token
, and the runner is configured.
The end, for now
This is it, it works! Time will tell what issues or ideas will come up: for now, it's a pretty decent first version.
The various prepare
, run
, cleanup
steps are generic enough that they can
be used outside of gitlab-runner
: feel free to build on them, and drop me a
note if you find this useful!
Updated: Issues noticed so far, that could go into a new version:
- updating the master chroot would disturb the running CI jobs that use it. Using nspawn's btrfs-specfic features would prevent this problem, and possibly simplify the implementation even more. This is now done!
- New step! trivially implementing support for multiple OS images