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.
- New step! trivially implementing support for multiple OS images