From a23eec607720328830fb9082850cfbdc6e8e0586 Mon Sep 17 00:00:00 2001 From: Andre Anjos <andre.dos.anjos@gmail.com> Date: Fri, 22 Feb 2019 15:23:39 +0100 Subject: [PATCH] [scripts][gitlab] New runners command to enable and disable runners on groups and projects --- bob/devtools/scripts/runners.py | 117 ++++++++++++++++++++++++++++++++ conda/meta.yaml | 1 + doc/linux.rst | 9 +++ setup.py | 1 + 4 files changed, 128 insertions(+) create mode 100644 bob/devtools/scripts/runners.py diff --git a/bob/devtools/scripts/runners.py b/bob/devtools/scripts/runners.py new file mode 100644 index 00000000..a6af22a8 --- /dev/null +++ b/bob/devtools/scripts/runners.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python + +import os + +import click + +from . import bdt +from ..release import get_gitlab_instance, update_files_with_mr, \ + update_files_at_master + +from ..log import verbosity_option, get_logger +logger = get_logger(__name__) + + +@click.command(epilog=''' +Examples: + + 1. Disables the runner with description "macmini" for all active projects in group "bob": + + $ bdt gitlab runners -vv bob disable macmini + + + 2. Enables the runner with description "linux-srv01" on all projects inside group "beat": + + $ bdt gitlab runners -vv beat enable linux-srv01 + + + 3. Enables the runner with description "linux-srv02" on a specific project: + + $ bdt gitlab runners -vv bob/bob.extension enable linux-srv02 + +''') +@click.argument('target') +@click.argument('cmd', type=click.Choice(['enable', 'disable'])) +@click.argument('name') +@click.option('-d', '--dry-run/--no-dry-run', default=False, + help='Only goes through the actions, but does not execute them ' \ + '(combine with the verbosity flags - e.g. ``-vvv``) to enable ' \ + 'printing to help you understand what will be done') +@verbosity_option() +@bdt.raise_on_error +def runners(target, cmd, name, dry_run): + """Enables and disables runners on whole gitlab groups or single projects + """ + + gl = get_gitlab_instance() + gl.auth() + user_id = gl.user.attributes['id'] + + if '/' in target: #it is a specific project + packages = [gl.projects.get(target)] + logger.debug('Found gitlab project %s (id=%d)', + packages[0].attributes['path_with_namespace'], packages[0].id) + + else: #it is a group - get all projects + logger.warn('Retrieving group by name - may take long...') + group = gl.groups.get(target) + logger.debug('Found gitlab group %s (id=%d)', group.attributes['path'], + group.id) + logger.warn('Retrieving all projects (with details) from group ' \ + '%s (id=%d)...', group.attributes['path'], group.id) + packages = [gl.projects.get(k.id) for k in \ + group.projects.list(all=True, simple=True)] + logger.info('Found %d projects under group %s', len(packages), + group.attributes['path']) + + # search for the runner to affect + the_runner = [k for k in gl.runners.list(all=True) if \ + k.attributes['description'] == name] + if not the_runner: + raise RuntimeError('Cannot find runner with description = %s', name) + the_runner = the_runner[0] + logger.info('Found runner %s (id=%d)', + the_runner.attributes['description'], the_runner.attributes['id']) + + for k in packages: + logger.info('Processing project %s (id=%d)', + k.attributes['path_with_namespace'], k.id) + + if cmd == 'enable': + + #checks if runner is not enabled first + enabled = False + for l in k.runners.list(all=True): + if l.id == the_runner.id: #it is there already + logger.warn('Runner %s (id=%d) is already enabled for project %s', + l.attributes['description'], l.id, + k.attributes['path_with_namespace']) + enabled = True + break + + if not enabled: #enable it + if not dry_run: + k.runners.create({'runner_id': the_runner.id}) + logger.info('Enabled runner %s (id=%d) for project %s', + the_runner.attributes['description'], the_runner.id, + k.attributes['path_with_namespace']) + + + elif cmd == 'disable': + + #checks if runner is not already disabled first + disabled = True + for l in k.runners.list(all=True): + if l.id == the_runner.id: #it is there already + logger.debug('Runner %s (id=%d) is enabled for project %s', + l.attributes['description'], l.id, + k.attributes['path_with_namespace']) + disabled = False + break + + if not disabled: #enable it + if not dry_run: + k.runners.delete(the_runner.id) + logger.info('Disabled runner %s (id=%d) for project %s', + the_runner.attributes['description'], the_runner.id, + k.attributes['path_with_namespace']) diff --git a/conda/meta.yaml b/conda/meta.yaml index 32af26cf..5390d62f 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -77,6 +77,7 @@ test: #- bdt gitlab visibility -vv bob/bob.devtools - bdt gitlab getpath --help #- bdt gitlab getpath -vv bob/bob.devtools .gitignore + - bdt gitlab runners --help - bdt ci --help - bdt ci base-build --help - bdt ci build --help diff --git a/doc/linux.rst b/doc/linux.rst index cba25433..5ad04d8f 100644 --- a/doc/linux.rst +++ b/doc/linux.rst @@ -166,3 +166,12 @@ The `docker-cleanup.sh` is: # Unused image leafs echo "Removing unused image leafs..." docker rmi $(docker images --filter "dangling=true" -q --no-trunc) + + +Conda and shared builds +======================= + +To avoid problems with conda and using shared builders, consider creating the +directory ``~gitlab-runner/.conda`` and touching the file +``environments.txt`` in that directory, setting a mode of ``444`` (i.e., make +it read-only). diff --git a/setup.py b/setup.py index ae8e42e9..122f0710 100644 --- a/setup.py +++ b/setup.py @@ -61,6 +61,7 @@ setup( 'release = bob.devtools.scripts.release:release', 'changelog = bob.devtools.scripts.changelog:changelog', 'lasttag = bob.devtools.scripts.lasttag:lasttag', + 'runners = bob.devtools.scripts.runners:runners', 'visibility = bob.devtools.scripts.visibility:visibility', 'getpath = bob.devtools.scripts.getpath:getpath', ], -- GitLab