From 98325d71370dfa4280ba0acea7d7e8fb982c2438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Wed, 21 Oct 2020 14:44:10 +0200 Subject: [PATCH 1/2] Run Flake8 and PyLint in GitLab CI --- .gitlab-ci.yml | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eab5ea1..386ed84 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,9 +1,24 @@ -image: registry.gitlab.isc.org/isc-projects/images/bind9:debian-sid-amd64 - -shellcheck: +.test_job: &test_job stage: test tags: - amd64 - docker + - linux + +flake8: + <<: *test_job + image: registry.gitlab.isc.org/isc-projects/images/bind9:debian-buster-amd64 + script: + - find . -name "*.py" -execdir flake8 {} + + +pylint: + <<: *test_job + image: registry.gitlab.isc.org/isc-projects/images/bind9:debian-buster-amd64 + script: + - find . -name "*.py" -execdir pylint {} + + +shellcheck: + <<: *test_job + image: registry.gitlab.isc.org/isc-projects/images/bind9:debian-sid-amd64 script: - find . -name "*.sh" -execdir shellcheck -x {} + -- GitLab From 9ada3335263eae6233ca12dbdcfba262651135a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Wed, 21 Oct 2020 14:44:10 +0200 Subject: [PATCH 2/2] Add an executor for Docker on Windows --- windows-docker/README.md | 45 ++++++++++++++ windows-docker/executor.py | 123 +++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 windows-docker/README.md create mode 100644 windows-docker/executor.py diff --git a/windows-docker/README.md b/windows-docker/README.md new file mode 100644 index 0000000..68a5d2d --- /dev/null +++ b/windows-docker/README.md @@ -0,0 +1,45 @@ +# GitLab Runner Custom Executor for Docker on Windows + +## Overview + +This Python script allows GitLab CI jobs to be run inside Docker +containers on Windows Server systems which are [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/ diff --git a/windows-docker/executor.py b/windows-docker/executor.py new file mode 100644 index 0000000..3cc6dbd --- /dev/null +++ b/windows-docker/executor.py @@ -0,0 +1,123 @@ +""" +executor.py - GitLab Runner Custom executor script for Docker on Windows + +Written in 2020 by Michał Kępień + +To the extent possible under law, the author(s) have dedicated all copyright +and related and neighboring rights to this software to the public domain +worldwide. This software is distributed without any warranty. + +You should have received a copy of the CC0 Public Domain Dedication along with +this software. If not, see http://creativecommons.org/publicdomain/zero/1.0/. +""" + +import json +import os +import subprocess +import sys + + +DOCKER_PATH = 'C:\\Program Files\\Docker\\docker.exe' + + +def fatal_error(message): + """ + Print an error message to stderr and exit. + """ + print(message, file=sys.stderr) + sys.exit(1) + + +def docker_command(cmd): + """ + Invoke the given Docker command, exiting immediately if it fails. + """ + try: + subprocess.run([DOCKER_PATH] + cmd, check=True) + except subprocess.CalledProcessError: + sys.exit(1) + + +def do_config(*_): + """ + Perform the Config stage of a GitLab CI job. + """ + config = { + 'builds_dir': 'C:\\builds', + 'cache_dir': 'C:\\cache', + 'builds_dir_is_shared': False, + } + print(json.dumps(config)) + + +def do_prepare(container_name, _): + """ + Perform the Prepare stage of a GitLab CI job. + """ + docker_command(['run', + '--name', container_name, + '--interactive', + '--detach', + '--rm', + os.environ['CUSTOM_ENV_CI_JOB_IMAGE']]) + + +def do_run(container_name, args): + """ + Perform the Run stage of a GitLab CI job. + """ + 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, _): + """ + Perform the Cleanup stage of a GitLab CI job. + """ + docker_command(['stop', container_name]) + + +def main(): + """ + Parse arguments and perform the requested stage of a GitLab CI job. + """ + 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() -- GitLab