Custom GitLab Runner driver that provisions CI jobs in Vagrant VMs (currently Windows and macOS guest boxes) using the runner custom executor lifecycle.
On macOS, you can use homebrew with this repository as a custom tap:
brew tap nicerloop/gitlab-vagrant-driver https://github.com/nicerloop/gitlab-vagrant-driver
brew install gitlab-vagrant-driverOr, in a brew bundle Brewfile:
tap "nicerloop/gitlab-vagrant-driver", "https://github.com/nicerloop/gitlab-vagrant-driver"
brew "gitlab-vagrant-driver"When registering a GitLab Runner for this driver, choose the custom executor, install the driver script in a directory on PATH, then configure the custom stage commands to call gitlab-vagrant-driver.
Example install:
install -m 0755 ./bin/gitlab-vagrant-driver /usr/local/bin/gitlab-vagrant-driverExample config.toml section for a registered runner:
[[runners]]
name = "vagrant-custom-runner"
executor = "custom"
builds_dir = "builds"
cache_dir = "cache"
[runners.custom]
config_exec = "gitlab-vagrant-driver"
config_args = ["config", "image=bento/windows-11", "provider=virtualbox", "template=share/templates/Vagrantfile.vbox.win.erb"]
prepare_exec = "gitlab-vagrant-driver"
prepare_args = ["prepare"]
run_exec = "gitlab-vagrant-driver"
run_args = ["run"]
cleanup_exec = "gitlab-vagrant-driver"
cleanup_args = ["cleanup"]When installed via Homebrew, templates are under $(brew --prefix)/share/gitlab-vagrant-driver/. Use the full path in config_args:
config_args = ["config", "image=bento/windows-11", "provider=virtualbox", "template=$(brew --prefix)/share/gitlab-vagrant-driver/Vagrantfile.vbox.win.erb"]Ensure the runner service account can resolve gitlab-vagrant-driver from PATH.
The driver script is at bin/gitlab-vagrant-driver and supports four stages:
config: returns driver + job environment metadata in JSONprepare: creates aVagrantfileand boots the VMrun: uploads and executes the job script in the guestcleanup: destroys the VM
bin/gitlab-vagrant-driver <stage> [args...]bin/gitlab-vagrant-driver config image=bento/windows-11 provider=virtualbox template=share/templates/Vagrantfile.vbox.win.erbAccepted args:
image=<box-name[:version]>provider=<vagrant-provider>template=<path-to-vagrantfile-template>
Notes:
CUSTOM_ENV_CI_JOB_IMAGEoverrides theimagevalue when present.- Supported guests are inferred from image/box name:
- names containing
windowsusepowershell(PowerShell Desktop) +winrm - names containing
macosusesh+ssh
- names containing
- The JSON output includes a
job_envblock. GitLab Runner injects these as plain environment variables (withoutCUSTOM_ENV_prefix) into all subsequent stage calls (prepare,run,cleanup). This is howprovider,template,image,communicator, andtempare passed between stages.
bin/gitlab-vagrant-driver prepareRuns:
vagrant init ... --forcevagrant up ...
bin/gitlab-vagrant-driver run <script_path> <stage_name>GitLab Runner invokes run_exec multiple times, each time passing the path to
a generated script and the name of the current sub-stage (e.g. prepare_script,
get_sources, build_script, …). Both arguments are required.
Behavior:
- uploads script to guest temp dir
- executes through the selected communicator (
winrmorssh)
bin/gitlab-vagrant-driver cleanupDestroys VM with force.
Enable shell tracing and emit driver.env during config:
export VAGRANT_DRIVER_DEBUG=1Built-in templates (under share/templates/ in the repo, $(brew --prefix)/share/gitlab-vagrant-driver/ after Homebrew install):
share/templates/Vagrantfile.erbshare/templates/Vagrantfile.tart.mac.erbshare/templates/Vagrantfile.vbox.win.erbshare/templates/gitlab-runner-config-template.toml
Under test/:
start.sh: boots local GitLab, registers runner, creates sample project/pipelinestop.sh: tears down local test environmentbuild-bento.sh: builds and adds localbento/windows-11box
Note:
start.shuses the deprecated--registration-tokenrunner registration flow. GitLab 16.0+ recommends runner authentication tokens (--token) instead.
Run from repo root:
cd test
./start.sh
# ... validate pipeline execution ...
./stop.sh