Commit 5fca9821 authored by Michał Kępień's avatar Michał Kępień

Add an executor for Docker on Windows Server 2016

parent 0d9d0903
Pipeline #54698 failed with stage
in 8 seconds
# GitLab Runner Custom Executor for Docker on Windows Server 2016
## Overview
This Python script allows GitLab CI jobs to be run inside Docker
containers on Windows Server 2016, which is [not supported][1] by the
native Docker executor included in GitLab Runner.
## Prerequisites
- [GitLab Runner][2]
- [Docker][3]
- [Python 3.6+][4]
## Installation
- Register a new GitLab CI runner using `gitlab-runner.exe register`,
specifying `custom` as the executor to use.
- Adjust the relevant section of GitLab Runner's `config.toml` so
that the executor gets invoked properly:
```toml
shell = "powershell"
[runners.custom]
config_exec = "C:\\path\\to\\python\\python.exe"
config_args = [ "C:\\path\\to\\windows-docker\\executor.py", "config" ]
prepare_exec = "C:\\path\\to\\python\\python.exe"
prepare_args = [ "C:\\path\\to\\windows-docker\\executor.py", "prepare" ]
run_exec = "C:\\path\\to\\python\\python.exe"
run_args = [ "C:\\path\\to\\windows-docker\\executor.py", "run" ]
cleanup_exec = "C:\\path\\to\\python\\python.exe"
cleanup_args = [ "C:\\path\\to\\windows-docker\\executor.py", "cleanup" ]
```
## Limitations
- Docker images are *not* automatically pulled or updated to the latest
available version during job setup. `docker pull` needs to be either
run manually or from the Windows Task Scheduler.
[1]: https://docs.gitlab.com/runner/executors/docker.html#supported-windows-versions
[2]: https://docs.gitlab.com/runner/install/windows.html
[3]: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/set-up-environment
[4]: https://www.python.org/downloads/windows/
import json
import os
import subprocess
import sys
DOCKER_PATH = 'C:\\Program Files\\Docker\\docker.exe'
def fatal_error(message):
print(message, file=sys.stderr)
sys.exit(1)
def docker_command(cmd):
try:
subprocess.run([DOCKER_PATH] + cmd, check=True)
except subprocess.CalledProcessError:
sys.exit(1)
def do_config(*_):
config = {
'builds_dir': 'C:\\builds',
'cache_dir': 'C:\\cache',
'builds_dir_is_shared': False,
}
print(json.dumps(config))
def do_prepare(container_name, _):
docker_command(['run',
'--name', container_name,
'--interactive',
'--detach',
'--rm',
os.environ['CUSTOM_ENV_CI_JOB_IMAGE']])
def do_run(container_name, args):
valid_stages = [
'prepare_script',
'get_sources',
'restore_cache',
'download_artifacts',
'build_script',
'step_script',
'after_script',
'archive_cache',
'upload_artifacts_on_success',
'upload_artifacts_on_failure',
]
script_src = args[0]
stage = args[1]
if stage not in valid_stages:
fatal_error(f'Unsupported run stage "{stage}"')
script_dst_path = f'C:\\{stage}.ps1'
script_dst = f'{container_name}:{script_dst_path}'
docker_command(['cp', script_src, script_dst])
docker_command(['exec', container_name, 'powershell.exe', script_dst_path])
def do_cleanup(container_name, _):
docker_command(['stop', container_name])
def main():
actions = {
'config': do_config,
'prepare': do_prepare,
'run': do_run,
'cleanup': do_cleanup,
}
valid_actions = '|'.join(actions.keys())
try:
action = actions[sys.argv[1]]
except (IndexError, KeyError):
fatal_error(f'Usage: {sys.argv[0]} {valid_actions} [args...]')
container_name = 'gitlab-runner-' + os.environ['CUSTOM_ENV_CI_JOB_ID']
action(container_name, sys.argv[2:])
if __name__ == '__main__':
main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment