1
0
Fork 1
mirror of https://github.com/NixOS/nixpkgs.git synced 2024-11-17 19:21:04 +00:00

[24.05] nixos/gitlab-runner: Add support for runner authentication tokens (#322440)

* nixos/gitlab-runner: Remove global with lib;

(cherry picked from commit 92a26526b9)

* nixos/gitlab-runner: Add support runner authentication tokens

Support for *runner registration tokens* is deprecated since GitLab
16.0, has been disabled by default in GitLab 17.0 and will be removed in
GitLab 18.0, as outlined in the [GitLab documentation].

It is possible to [re-enable support for runner registration tokens]
until GitLab 18.0, to prevent the registration workflow from
breaking.

*Runner authentication tokens*, the replacement for registration tokens,
have been available since GitLab 16.0 and are expected to be defined in
the `CI_SERVER_TOKEN` environment variable, instead of the previous
`REGISTRATION_TOKEN` variable.

This commit adds a new option
`services.gitlab-runner.services.<name>.authenticationTokenConfigFile`.
Defining such option next to
`services.gitlab-runner.services.<name>.registrationConfigFile` brings
the following benefits:
- A warning message can be emitted to notify module users about the
  upcoming breaking change with GitLab 17.0, where *runner registration
  tokens* will be disabled by default, potentially disrupting
  operations.
- Some configuration options are no longer supported with *runner
  authentication tokens* since they will be defined when creating a new
  token in the GitLab UI instead. New warning messages can be emitted to
  notify users to remove the affected options from their configuration.
- Once support for *registration tokens* has been removed in GitLab 18,
  we can remove
  `services.gitlab-runner.services.<name>.registrationConfigFile` as
  well and make module users configure an *authentication token*
  instead.

This commit changes the option type of
`services.gitlab-runner.services.<name>.registrationConfigFile` to
`with lib.types; nullOr str` to allow configuring an authentication
token in
`services.gitlab-runner.services.<name>.authenticationTokenConfigFile`
instead.

A new assertion will make sure that
`services.gitlab-runner.services.<name>.registrationConfigFile` and
`services.gitlab-runner.services.<name>.authenticationTokenConfigFile`
are mutually exclusive. Setting both at the same time would not make
much sense in this case.

[GitLab documentation]: https://docs.gitlab.com/17.0/ee/ci/runners/new_creation_workflow.html#estimated-time-frame-for-planned-changes
[re-enable support for runner registration tokens]: https://docs.gitlab.com/17.0/ee/ci/runners/new_creation_workflow.html#prevent-your-runner-registration-workflow-from-breaking

(cherry picked from commit 6f211d899d)
This commit is contained in:
Yaya 2024-06-26 11:29:14 +02:00 committed by GitHub
parent 8fdb4ad006
commit ec89585696
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,7 +1,43 @@
{ config, lib, pkgs, ... }:
with builtins;
with lib;
let
inherit (builtins)
hashString
map
substring
toJSON
toString
unsafeDiscardStringContext
;
inherit (lib)
any
assertMsg
attrValues
concatStringsSep
escapeShellArg
filterAttrs
hasPrefix
isStorePath
literalExpression
mapAttrs'
mapAttrsToList
mkDefault
mkEnableOption
mkIf
mkOption
mkPackageOption
mkRemovedOptionModule
mkRenamedOptionModule
nameValuePair
optional
optionalAttrs
optionals
teams
toShellVar
types
;
cfg = config.services.gitlab-runner;
hasDocker = config.virtualisation.docker.enable;
@ -20,17 +56,16 @@ let
configPath = ''"$HOME"/.gitlab-runner/config.toml'';
configureScript = pkgs.writeShellApplication {
name = "gitlab-runner-configure";
runtimeInputs = with pkgs; [
runtimeInputs = [ cfg.package ] ++ (with pkgs; [
bash
gawk
jq
moreutils
remarshal
util-linux
cfg.package
perl
python3
];
]);
text = if (cfg.configFile != null) then ''
cp ${cfg.configFile} ${configPath}
# make config file readable by service
@ -84,15 +119,20 @@ let
# TODO so here we should mention NEW_SERVICES
if [ -v 'NEW_SERVICES["${name}"]' ] ; then
bash -c ${escapeShellArg (concatStringsSep " \\\n " ([
"set -a && source ${service.registrationConfigFile} &&"
"set -a && source ${
if service.registrationConfigFile != null
then service.registrationConfigFile
else service.authenticationTokenConfigFile} &&"
"gitlab-runner register"
"--non-interactive"
"--name '${name}'"
"--executor ${service.executor}"
"--limit ${toString service.limit}"
"--request-concurrency ${toString service.requestConcurrency}"
]
++ optional (service.authenticationTokenConfigFile == null)
"--maximum-timeout ${toString service.maximumTimeout}"
] ++ service.registrationFlags
++ service.registrationFlags
++ optional (service.buildsDir != null)
"--builds-dir ${service.buildsDir}"
++ optional (service.cloneUrl != null)
@ -103,11 +143,11 @@ let
"--pre-build-script ${service.preBuildScript}"
++ optional (service.postBuildScript != null)
"--post-build-script ${service.postBuildScript}"
++ optional (service.tagList != [ ])
++ optional (service.authenticationTokenConfigFile == null && service.tagList != [ ])
"--tag-list ${concatStringsSep "," service.tagList}"
++ optional service.runUntagged
++ optional (service.authenticationTokenConfigFile == null && service.runUntagged)
"--run-untagged"
++ optional service.protected
++ optional (service.authenticationTokenConfigFile == null && service.protected)
"--access-level ref_protected"
++ optional service.debugTraceDisabled
"--debug-trace-disabled"
@ -214,9 +254,14 @@ in {
# nix store will be readable in runner, might be insecure
nix = {
# File should contain at least these two variables:
# `CI_SERVER_URL`
# `REGISTRATION_TOKEN`
# - `CI_SERVER_URL`
# - `REGISTRATION_TOKEN`
#
# NOTE: Support for runner registration tokens will be removed in GitLab 18.0.
# Please migrate to runner authentication tokens soon. For reference, the example
# runners below this one are configured with authentication tokens instead.
registrationConfigFile = "/run/secrets/gitlab-runner-registration";
dockerImage = "alpine";
dockerVolumes = [
"/nix/store:/nix/store:ro"
@ -255,8 +300,9 @@ in {
docker-images = {
# File should contain at least these two variables:
# `CI_SERVER_URL`
# `REGISTRATION_TOKEN`
registrationConfigFile = "/run/secrets/gitlab-runner-registration";
# `CI_SERVER_TOKEN`
authenticationTokenConfigFile = "/run/secrets/gitlab-runner-docker-images-token-env";
dockerImage = "docker:stable";
dockerVolumes = [
"/var/run/docker.sock:/var/run/docker.sock"
@ -269,8 +315,9 @@ in {
shell = {
# File should contain at least these two variables:
# `CI_SERVER_URL`
# `REGISTRATION_TOKEN`
registrationConfigFile = "/run/secrets/gitlab-runner-registration";
# `CI_SERVER_TOKEN`
authenticationTokenConfigFile = "/run/secrets/gitlab-runner-shell-token-env";
executor = "shell";
tagList = [ "shell" ];
};
@ -278,30 +325,67 @@ in {
default = {
# File should contain at least these two variables:
# `CI_SERVER_URL`
# `REGISTRATION_TOKEN`
registrationConfigFile = "/run/secrets/gitlab-runner-registration";
# `CI_SERVER_TOKEN`
authenticationTokenConfigFile = "/run/secrets/gitlab-runner-default-token-env";
dockerImage = "debian:stable";
};
}
'';
type = types.attrsOf (types.submodule {
options = {
authenticationTokenConfigFile = mkOption {
type = with types; nullOr path;
default = null;
description = ''
Absolute path to a file containing environment variables used for
gitlab-runner registrations with *runner authentication tokens*.
They replace the deprecated *runner registration tokens*, as
outlined in the [GitLab documentation].
A list of all supported environment variables can be found with
`gitlab-runner register --help`.
The ones you probably want to set are:
- `CI_SERVER_URL=<CI server URL>`
- `CI_SERVER_TOKEN=<runner authentication token secret>`
::: {.warning}
Make sure to use a quoted absolute path,
or it is going to be copied to Nix Store.
:::
[GitLab documentation]: https://docs.gitlab.com/17.0/ee/ci/runners/new_creation_workflow.html#estimated-time-frame-for-planned-changes
'';
};
registrationConfigFile = mkOption {
type = types.path;
type = with types; nullOr path;
default = null;
description = ''
Absolute path to a file with environment variables
used for gitlab-runner registration.
used for gitlab-runner registration with *runner registration
tokens*.
A list of all supported environment variables can be found in
`gitlab-runner register --help`.
Ones that you probably want to set is
The ones you probably want to set are:
- `CI_SERVER_URL=<CI server URL>`
- `REGISTRATION_TOKEN=<registration secret>`
`CI_SERVER_URL=<CI server URL>`
Support for *runner registration tokens* is deprecated since
GitLab 16.0, has been disabled by default in GitLab 17.0 and
will be removed in GitLab 18.0, as outlined in the
[GitLab documentation]. Please consider migrating to
[runner authentication tokens] and check the documentation on
{option}`services.gitlab-runner.services.<name>.authenticationTokenConfigFile`.
`REGISTRATION_TOKEN=<registration secret>`
WARNING: make sure to use quoted absolute path,
::: {.warning}
Make sure to use a quoted absolute path,
or it is going to be copied to Nix Store.
:::
[GitLab documentation]: https://docs.gitlab.com/17.0/ee/ci/runners/new_creation_workflow.html#estimated-time-frame-for-planned-changes
[runner authentication tokens]: https://docs.gitlab.com/17.0/ee/ci/runners/new_creation_workflow.html#the-new-runner-registration-workflow
'';
};
registrationFlags = mkOption {
@ -439,6 +523,9 @@ in {
default = [ ];
description = ''
Tag list.
This option has no effect for runners registered with an runner
authentication tokens and will be ignored.
'';
};
runUntagged = mkOption {
@ -447,6 +534,9 @@ in {
description = ''
Register to run untagged builds; defaults to
`true` when {option}`tagList` is empty.
This option has no effect for runners registered with an runner
authentication tokens and will be ignored.
'';
};
limit = mkOption {
@ -470,6 +560,9 @@ in {
description = ''
What is the maximum timeout (in seconds) that will be set for
job when using this Runner. 0 (default) simply means don't limit.
This option has no effect for runners registered with an runner
authentication tokens and will be ignored.
'';
};
protected = mkOption {
@ -478,6 +571,9 @@ in {
description = ''
When set to true Runner will only run on pipelines
triggered on protected branches.
This option has no effect for runners registered with an runner
authentication tokens and will be ignored.
'';
};
debugTraceDisabled = mkOption {
@ -530,9 +626,67 @@ in {
};
};
config = mkIf cfg.enable {
warnings = mapAttrsToList
(n: v: "services.gitlab-runner.services.${n}.`registrationConfigFile` points to a file in Nix Store. You should use quoted absolute path to prevent this.")
(filterAttrs (n: v: isStorePath v.registrationConfigFile) cfg.services);
assertions =
mapAttrsToList (name: serviceConfig: {
assertion = serviceConfig.registrationConfigFile == null || serviceConfig.authenticationTokenConfigFile == null;
message = "`services.gitlab-runner.${name}.registrationConfigFile` and `services.gitlab-runner.services.${name}.authenticationTokenConfigFile` are mutually exclusive.";
}) cfg.services;
warnings =
mapAttrsToList
(name: serviceConfig: "services.gitlab-runner.services.${name}.`registrationConfigFile` points to a file in Nix Store. You should use quoted absolute path to prevent this.")
(filterAttrs (name: serviceConfig: isStorePath serviceConfig.registrationConfigFile) cfg.services)
++ mapAttrsToList
(name: serviceConfig: "services.gitlab-runner.services.${name}.`authenticationTokenConfigFile` points to a file in Nix Store. You should use quoted absolute path to prevent this.")
(filterAttrs (name: serviceConfig: isStorePath serviceConfig.authenticationTokenConfigFile) cfg.services)
++ mapAttrsToList
(name: serviceConfig: ''
Runner registration tokens have been deprecated and disabled by default in GitLab >= 17.0.
Consider migrating to runner authentication tokens by setting `services.gitlab-runner.services.${name}.authenticationTokenConfigFile`.
https://docs.gitlab.com/17.0/ee/ci/runners/new_creation_workflow.html''
)
(
filterAttrs (name: serviceConfig:
serviceConfig.authenticationTokenConfigFile == null
) cfg.services
)
++ mapAttrsToList
(name: serviceConfig: ''
`services.gitlab-runner.services.${name}.protected` with runner authentication tokens has no effect and will be ignored. Please remove it from your configuration.''
)
(
filterAttrs (name: serviceConfig:
serviceConfig.authenticationTokenConfigFile != null && serviceConfig.protected == true
) cfg.services
)
++ mapAttrsToList
(name: serviceConfig: ''
`services.gitlab-runner.services.${name}.runUntagged` with runner authentication tokens has no effect and will be ignored. Please remove it from your configuration.''
)
(
filterAttrs (name: serviceConfig:
serviceConfig.authenticationTokenConfigFile != null && serviceConfig.runUntagged == true
) cfg.services
)
++ mapAttrsToList
(name: v: ''
`services.gitlab-runner.services.${name}.maximumTimeout` with runner authentication tokens has no effect and will be ignored. Please remove it from your configuration.''
)
(
filterAttrs (name: serviceConfig:
serviceConfig.authenticationTokenConfigFile != null && serviceConfig.maximumTimeout != 0
) cfg.services
)
++ mapAttrsToList
(name: v: ''
`services.gitlab-runner.services.${name}.tagList` with runner authentication tokens has no effect and will be ignored. Please remove it from your configuration.''
)
(
filterAttrs (serviceName: serviceConfig:
serviceConfig.authenticationTokenConfigFile != null && serviceConfig.tagList != [ ]
) cfg.services
)
;
environment.systemPackages = [ cfg.package ];
systemd.services.gitlab-runner = {
@ -545,15 +699,19 @@ in {
environment = config.networking.proxy.envVars // {
HOME = "/var/lib/gitlab-runner";
};
path = with pkgs; [
bash
gawk
jq
moreutils
remarshal
util-linux
cfg.package
] ++ cfg.extraPackages;
path =
(with pkgs; [
bash
gawk
jq
moreutils
remarshal
util-linux
])
++ [ cfg.package ]
++ cfg.extraPackages;
reloadIfChanged = true;
serviceConfig = {
# Set `DynamicUser` under `systemd.services.gitlab-runner.serviceConfig`