576 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			576 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, lib, pkgs, ... }:
 | 
						||
with builtins;
 | 
						||
with lib;
 | 
						||
let
 | 
						||
  cfg = config.services.gitlab-runner;
 | 
						||
  hasDocker = config.virtualisation.docker.enable;
 | 
						||
  hashedServices = mapAttrs'
 | 
						||
    (name: service: nameValuePair
 | 
						||
      "${name}_${config.networking.hostName}_${
 | 
						||
        substring 0 12
 | 
						||
        (hashString "md5" (unsafeDiscardStringContext (toJSON service)))}"
 | 
						||
      service)
 | 
						||
    cfg.services;
 | 
						||
  configPath = "$HOME/.gitlab-runner/config.toml";
 | 
						||
  configureScript = pkgs.writeShellScriptBin "gitlab-runner-configure" (
 | 
						||
    if (cfg.configFile != null) then ''
 | 
						||
      mkdir -p $(dirname ${configPath})
 | 
						||
      cp ${cfg.configFile} ${configPath}
 | 
						||
      # make config file readable by service
 | 
						||
      chown -R --reference=$HOME $(dirname ${configPath})
 | 
						||
    '' else ''
 | 
						||
      export CONFIG_FILE=${configPath}
 | 
						||
 | 
						||
      mkdir -p $(dirname ${configPath})
 | 
						||
 | 
						||
      # remove no longer existing services
 | 
						||
      gitlab-runner verify --delete
 | 
						||
 | 
						||
      # current and desired state
 | 
						||
      NEEDED_SERVICES=$(echo ${concatStringsSep " " (attrNames hashedServices)} | tr " " "\n")
 | 
						||
      REGISTERED_SERVICES=$(gitlab-runner list 2>&1 | grep 'Executor' | awk '{ print $1 }')
 | 
						||
 | 
						||
      # difference between current and desired state
 | 
						||
      NEW_SERVICES=$(grep -vxF -f <(echo "$REGISTERED_SERVICES") <(echo "$NEEDED_SERVICES") || true)
 | 
						||
      OLD_SERVICES=$(grep -vxF -f <(echo "$NEEDED_SERVICES") <(echo "$REGISTERED_SERVICES") || true)
 | 
						||
 | 
						||
      # register new services
 | 
						||
      ${concatStringsSep "\n" (mapAttrsToList (name: service: ''
 | 
						||
        if echo "$NEW_SERVICES" | grep -xq ${name}; then
 | 
						||
          bash -c ${escapeShellArg (concatStringsSep " \\\n " ([
 | 
						||
            "set -a && source ${service.registrationConfigFile} &&"
 | 
						||
            "gitlab-runner register"
 | 
						||
            "--non-interactive"
 | 
						||
            "--name ${name}"
 | 
						||
            "--executor ${service.executor}"
 | 
						||
            "--limit ${toString service.limit}"
 | 
						||
            "--request-concurrency ${toString service.requestConcurrency}"
 | 
						||
            "--maximum-timeout ${toString service.maximumTimeout}"
 | 
						||
          ] ++ service.registrationFlags
 | 
						||
            ++ optional (service.buildsDir != null)
 | 
						||
            "--builds-dir ${service.buildsDir}"
 | 
						||
            ++ optional (service.cloneUrl != null)
 | 
						||
            "--clone-url ${service.cloneUrl}"
 | 
						||
            ++ optional (service.preCloneScript != null)
 | 
						||
            "--pre-clone-script ${service.preCloneScript}"
 | 
						||
            ++ optional (service.preBuildScript != null)
 | 
						||
            "--pre-build-script ${service.preBuildScript}"
 | 
						||
            ++ optional (service.postBuildScript != null)
 | 
						||
            "--post-build-script ${service.postBuildScript}"
 | 
						||
            ++ optional (service.tagList != [ ])
 | 
						||
            "--tag-list ${concatStringsSep "," service.tagList}"
 | 
						||
            ++ optional service.runUntagged
 | 
						||
            "--run-untagged"
 | 
						||
            ++ optional service.protected
 | 
						||
            "--access-level ref_protected"
 | 
						||
            ++ optional service.debugTraceDisabled
 | 
						||
            "--debug-trace-disabled"
 | 
						||
            ++ map (e: "--env ${escapeShellArg e}") (mapAttrsToList (name: value: "${name}=${value}") service.environmentVariables)
 | 
						||
            ++ optionals (service.executor == "docker") (
 | 
						||
              assert (
 | 
						||
                assertMsg (service.dockerImage != null)
 | 
						||
                  "dockerImage option is required for docker executor (${name})");
 | 
						||
              [ "--docker-image ${service.dockerImage}" ]
 | 
						||
              ++ optional service.dockerDisableCache
 | 
						||
              "--docker-disable-cache"
 | 
						||
              ++ optional service.dockerPrivileged
 | 
						||
              "--docker-privileged"
 | 
						||
              ++ map (v: "--docker-volumes ${escapeShellArg v}") service.dockerVolumes
 | 
						||
              ++ map (v: "--docker-extra-hosts ${escapeShellArg v}") service.dockerExtraHosts
 | 
						||
              ++ map (v: "--docker-allowed-images ${escapeShellArg v}") service.dockerAllowedImages
 | 
						||
              ++ map (v: "--docker-allowed-services ${escapeShellArg v}") service.dockerAllowedServices
 | 
						||
            )
 | 
						||
          ))} && sleep 1 || exit 1
 | 
						||
        fi
 | 
						||
      '') hashedServices)}
 | 
						||
 | 
						||
      # unregister old services
 | 
						||
      for NAME in $(echo "$OLD_SERVICES")
 | 
						||
      do
 | 
						||
        [ ! -z "$NAME" ] && gitlab-runner unregister \
 | 
						||
          --name "$NAME" && sleep 1
 | 
						||
      done
 | 
						||
 | 
						||
      # update global options
 | 
						||
      remarshal --if toml --of json ${configPath} \
 | 
						||
        | jq -cM ${escapeShellArg (concatStringsSep " | " [
 | 
						||
            ".check_interval = ${toJSON cfg.checkInterval}"
 | 
						||
            ".concurrent = ${toJSON cfg.concurrent}"
 | 
						||
            ".sentry_dsn = ${toJSON cfg.sentryDSN}"
 | 
						||
            ".listen_address = ${toJSON cfg.prometheusListenAddress}"
 | 
						||
            ".session_server.listen_address = ${toJSON cfg.sessionServer.listenAddress}"
 | 
						||
            ".session_server.advertise_address = ${toJSON cfg.sessionServer.advertiseAddress}"
 | 
						||
            ".session_server.session_timeout = ${toJSON cfg.sessionServer.sessionTimeout}"
 | 
						||
            "del(.[] | nulls)"
 | 
						||
            "del(.session_server[] | nulls)"
 | 
						||
          ])} \
 | 
						||
        | remarshal --if json --of toml \
 | 
						||
        | sponge ${configPath}
 | 
						||
 | 
						||
      # make config file readable by service
 | 
						||
      chown -R --reference=$HOME $(dirname ${configPath})
 | 
						||
    '');
 | 
						||
  startScript = pkgs.writeShellScriptBin "gitlab-runner-start" ''
 | 
						||
    export CONFIG_FILE=${configPath}
 | 
						||
    exec gitlab-runner run --working-directory $HOME
 | 
						||
  '';
 | 
						||
in
 | 
						||
{
 | 
						||
  options.services.gitlab-runner = {
 | 
						||
    enable = mkEnableOption "Gitlab Runner";
 | 
						||
    configFile = mkOption {
 | 
						||
      type = types.nullOr types.path;
 | 
						||
      default = null;
 | 
						||
      description = ''
 | 
						||
        Configuration file for gitlab-runner.
 | 
						||
 | 
						||
        <option>configFile</option> takes precedence over <option>services</option>.
 | 
						||
        <option>checkInterval</option> and <option>concurrent</option> will be ignored too.
 | 
						||
 | 
						||
        This option is deprecated, please use <option>services</option> instead.
 | 
						||
        You can use <option>registrationConfigFile</option> and
 | 
						||
        <option>registrationFlags</option>
 | 
						||
        for settings not covered by this module.
 | 
						||
      '';
 | 
						||
    };
 | 
						||
    checkInterval = mkOption {
 | 
						||
      type = types.int;
 | 
						||
      default = 0;
 | 
						||
      example = literalExample "with lib; (length (attrNames config.services.gitlab-runner.services)) * 3";
 | 
						||
      description = ''
 | 
						||
        Defines the interval length, in seconds, between new jobs check.
 | 
						||
        The default value is 3;
 | 
						||
        if set to 0 or lower, the default value will be used.
 | 
						||
        See <link xlink:href="https://docs.gitlab.com/runner/configuration/advanced-configuration.html#how-check_interval-works">runner documentation</link> for more information.
 | 
						||
      '';
 | 
						||
    };
 | 
						||
    concurrent = mkOption {
 | 
						||
      type = types.int;
 | 
						||
      default = 1;
 | 
						||
      example = literalExample "config.nix.maxJobs";
 | 
						||
      description = ''
 | 
						||
        Limits how many jobs globally can be run concurrently.
 | 
						||
        The most upper limit of jobs using all defined runners.
 | 
						||
        0 does not mean unlimited.
 | 
						||
      '';
 | 
						||
    };
 | 
						||
    sentryDSN = mkOption {
 | 
						||
      type = types.nullOr types.str;
 | 
						||
      default = null;
 | 
						||
      example = "https://public:private@host:port/1";
 | 
						||
      description = ''
 | 
						||
        Data Source Name for tracking of all system level errors to Sentry.
 | 
						||
      '';
 | 
						||
    };
 | 
						||
    prometheusListenAddress = mkOption {
 | 
						||
      type = types.nullOr types.str;
 | 
						||
      default = null;
 | 
						||
      example = "localhost:8080";
 | 
						||
      description = ''
 | 
						||
        Address (<host>:<port>) on which the Prometheus metrics HTTP server
 | 
						||
        should be listening.
 | 
						||
      '';
 | 
						||
    };
 | 
						||
    sessionServer = mkOption {
 | 
						||
      type = types.submodule {
 | 
						||
        options = {
 | 
						||
          listenAddress = mkOption {
 | 
						||
            type = types.nullOr types.str;
 | 
						||
            default = null;
 | 
						||
            example = "0.0.0.0:8093";
 | 
						||
            description = ''
 | 
						||
              An internal URL to be used for the session server.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          advertiseAddress = mkOption {
 | 
						||
            type = types.nullOr types.str;
 | 
						||
            default = null;
 | 
						||
            example = "runner-host-name.tld:8093";
 | 
						||
            description = ''
 | 
						||
              The URL that the Runner will expose to GitLab to be used
 | 
						||
              to access the session server.
 | 
						||
              Fallbacks to <option>listenAddress</option> if not defined.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          sessionTimeout = mkOption {
 | 
						||
            type = types.int;
 | 
						||
            default = 1800;
 | 
						||
            description = ''
 | 
						||
              How long in seconds the session can stay active after
 | 
						||
              the job completes (which will block the job from finishing).
 | 
						||
            '';
 | 
						||
          };
 | 
						||
        };
 | 
						||
      };
 | 
						||
      default = { };
 | 
						||
      example = literalExample ''
 | 
						||
        {
 | 
						||
          listenAddress = "0.0.0.0:8093";
 | 
						||
        }
 | 
						||
      '';
 | 
						||
      description = ''
 | 
						||
        The session server allows the user to interact with jobs
 | 
						||
        that the Runner is responsible for. A good example of this is the
 | 
						||
        <link xlink:href="https://docs.gitlab.com/ee/ci/interactive_web_terminal/index.html">interactive web terminal</link>.
 | 
						||
      '';
 | 
						||
    };
 | 
						||
    gracefulTermination = mkOption {
 | 
						||
      type = types.bool;
 | 
						||
      default = false;
 | 
						||
      description = ''
 | 
						||
        Finish all remaining jobs before stopping.
 | 
						||
        If not set gitlab-runner will stop immediatly without waiting
 | 
						||
        for jobs to finish, which will lead to failed builds.
 | 
						||
      '';
 | 
						||
    };
 | 
						||
    gracefulTimeout = mkOption {
 | 
						||
      type = types.str;
 | 
						||
      default = "infinity";
 | 
						||
      example = "5min 20s";
 | 
						||
      description = ''
 | 
						||
        Time to wait until a graceful shutdown is turned into a forceful one.
 | 
						||
      '';
 | 
						||
    };
 | 
						||
    package = mkOption {
 | 
						||
      type = types.package;
 | 
						||
      default = pkgs.gitlab-runner;
 | 
						||
      defaultText = "pkgs.gitlab-runner";
 | 
						||
      example = literalExample "pkgs.gitlab-runner_1_11";
 | 
						||
      description = "Gitlab Runner package to use.";
 | 
						||
    };
 | 
						||
    extraPackages = mkOption {
 | 
						||
      type = types.listOf types.package;
 | 
						||
      default = [ ];
 | 
						||
      description = ''
 | 
						||
        Extra packages to add to PATH for the gitlab-runner process.
 | 
						||
      '';
 | 
						||
    };
 | 
						||
    services = mkOption {
 | 
						||
      description = "GitLab Runner services.";
 | 
						||
      default = { };
 | 
						||
      example = literalExample ''
 | 
						||
        {
 | 
						||
          # runner for building in docker via host's nix-daemon
 | 
						||
          # nix store will be readable in runner, might be insecure
 | 
						||
          nix = {
 | 
						||
            # File should contain at least these two variables:
 | 
						||
            # `CI_SERVER_URL`
 | 
						||
            # `REGISTRATION_TOKEN`
 | 
						||
            registrationConfigFile = "/run/secrets/gitlab-runner-registration";
 | 
						||
            dockerImage = "alpine";
 | 
						||
            dockerVolumes = [
 | 
						||
              "/nix/store:/nix/store:ro"
 | 
						||
              "/nix/var/nix/db:/nix/var/nix/db:ro"
 | 
						||
              "/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket:ro"
 | 
						||
            ];
 | 
						||
            dockerDisableCache = true;
 | 
						||
            preBuildScript = pkgs.writeScript "setup-container" '''
 | 
						||
              mkdir -p -m 0755 /nix/var/log/nix/drvs
 | 
						||
              mkdir -p -m 0755 /nix/var/nix/gcroots
 | 
						||
              mkdir -p -m 0755 /nix/var/nix/profiles
 | 
						||
              mkdir -p -m 0755 /nix/var/nix/temproots
 | 
						||
              mkdir -p -m 0755 /nix/var/nix/userpool
 | 
						||
              mkdir -p -m 1777 /nix/var/nix/gcroots/per-user
 | 
						||
              mkdir -p -m 1777 /nix/var/nix/profiles/per-user
 | 
						||
              mkdir -p -m 0755 /nix/var/nix/profiles/per-user/root
 | 
						||
              mkdir -p -m 0700 "$HOME/.nix-defexpr"
 | 
						||
 | 
						||
              . ''${pkgs.nix}/etc/profile.d/nix.sh
 | 
						||
 | 
						||
              ''${pkgs.nix}/bin/nix-env -i ''${concatStringsSep " " (with pkgs; [ nix cacert git openssh ])}
 | 
						||
 | 
						||
              ''${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixpkgs-unstable
 | 
						||
              ''${pkgs.nix}/bin/nix-channel --update nixpkgs
 | 
						||
            ''';
 | 
						||
            environmentVariables = {
 | 
						||
              ENV = "/etc/profile";
 | 
						||
              USER = "root";
 | 
						||
              NIX_REMOTE = "daemon";
 | 
						||
              PATH = "/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin";
 | 
						||
              NIX_SSL_CERT_FILE = "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt";
 | 
						||
            };
 | 
						||
            tagList = [ "nix" ];
 | 
						||
          };
 | 
						||
          # runner for building docker images
 | 
						||
          docker-images = {
 | 
						||
            # File should contain at least these two variables:
 | 
						||
            # `CI_SERVER_URL`
 | 
						||
            # `REGISTRATION_TOKEN`
 | 
						||
            registrationConfigFile = "/run/secrets/gitlab-runner-registration";
 | 
						||
            dockerImage = "docker:stable";
 | 
						||
            dockerVolumes = [
 | 
						||
              "/var/run/docker.sock:/var/run/docker.sock"
 | 
						||
            ];
 | 
						||
            tagList = [ "docker-images" ];
 | 
						||
          };
 | 
						||
          # runner for executing stuff on host system (very insecure!)
 | 
						||
          # make sure to add required packages (including git!)
 | 
						||
          # to `environment.systemPackages`
 | 
						||
          shell = {
 | 
						||
            # File should contain at least these two variables:
 | 
						||
            # `CI_SERVER_URL`
 | 
						||
            # `REGISTRATION_TOKEN`
 | 
						||
            registrationConfigFile = "/run/secrets/gitlab-runner-registration";
 | 
						||
            executor = "shell";
 | 
						||
            tagList = [ "shell" ];
 | 
						||
          };
 | 
						||
          # runner for everything else
 | 
						||
          default = {
 | 
						||
            # File should contain at least these two variables:
 | 
						||
            # `CI_SERVER_URL`
 | 
						||
            # `REGISTRATION_TOKEN`
 | 
						||
            registrationConfigFile = "/run/secrets/gitlab-runner-registration";
 | 
						||
            dockerImage = "debian:stable";
 | 
						||
          };
 | 
						||
        }
 | 
						||
      '';
 | 
						||
      type = types.attrsOf (types.submodule {
 | 
						||
        options = {
 | 
						||
          registrationConfigFile = mkOption {
 | 
						||
            type = types.path;
 | 
						||
            description = ''
 | 
						||
              Absolute path to a file with environment variables
 | 
						||
              used for gitlab-runner registration.
 | 
						||
              A list of all supported environment variables can be found in
 | 
						||
              <literal>gitlab-runner register --help</literal>.
 | 
						||
 | 
						||
              Ones that you probably want to set is
 | 
						||
 | 
						||
              <literal>CI_SERVER_URL=<CI server URL></literal>
 | 
						||
 | 
						||
              <literal>REGISTRATION_TOKEN=<registration secret></literal>
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          registrationFlags = mkOption {
 | 
						||
            type = types.listOf types.str;
 | 
						||
            default = [ ];
 | 
						||
            example = [ "--docker-helper-image my/gitlab-runner-helper" ];
 | 
						||
            description = ''
 | 
						||
              Extra command-line flags passed to
 | 
						||
              <literal>gitlab-runner register</literal>.
 | 
						||
              Execute <literal>gitlab-runner register --help</literal>
 | 
						||
              for a list of supported flags.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          environmentVariables = mkOption {
 | 
						||
            type = types.attrsOf types.str;
 | 
						||
            default = { };
 | 
						||
            example = { NAME = "value"; };
 | 
						||
            description = ''
 | 
						||
              Custom environment variables injected to build environment.
 | 
						||
              For secrets you can use <option>registrationConfigFile</option>
 | 
						||
              with <literal>RUNNER_ENV</literal> variable set.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          executor = mkOption {
 | 
						||
            type = types.str;
 | 
						||
            default = "docker";
 | 
						||
            description = ''
 | 
						||
              Select executor, eg. shell, docker, etc.
 | 
						||
              See <link xlink:href="https://docs.gitlab.com/runner/executors/README.html">runner documentation</link> for more information.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          buildsDir = mkOption {
 | 
						||
            type = types.nullOr types.path;
 | 
						||
            default = null;
 | 
						||
            example = "/var/lib/gitlab-runner/builds";
 | 
						||
            description = ''
 | 
						||
              Absolute path to a directory where builds will be stored
 | 
						||
              in context of selected executor (Locally, Docker, SSH).
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          cloneUrl = mkOption {
 | 
						||
            type = types.nullOr types.str;
 | 
						||
            default = null;
 | 
						||
            example = "http://gitlab.example.local";
 | 
						||
            description = ''
 | 
						||
              Overwrite the URL for the GitLab instance. Used if the Runner can’t connect to GitLab on the URL GitLab exposes itself.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          dockerImage = mkOption {
 | 
						||
            type = types.nullOr types.str;
 | 
						||
            default = null;
 | 
						||
            description = ''
 | 
						||
              Docker image to be used.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          dockerVolumes = mkOption {
 | 
						||
            type = types.listOf types.str;
 | 
						||
            default = [ ];
 | 
						||
            example = [ "/var/run/docker.sock:/var/run/docker.sock" ];
 | 
						||
            description = ''
 | 
						||
              Bind-mount a volume and create it
 | 
						||
              if it doesn't exist prior to mounting.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          dockerDisableCache = mkOption {
 | 
						||
            type = types.bool;
 | 
						||
            default = false;
 | 
						||
            description = ''
 | 
						||
              Disable all container caching.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          dockerPrivileged = mkOption {
 | 
						||
            type = types.bool;
 | 
						||
            default = false;
 | 
						||
            description = ''
 | 
						||
              Give extended privileges to container.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          dockerExtraHosts = mkOption {
 | 
						||
            type = types.listOf types.str;
 | 
						||
            default = [ ];
 | 
						||
            example = [ "other-host:127.0.0.1" ];
 | 
						||
            description = ''
 | 
						||
              Add a custom host-to-IP mapping.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          dockerAllowedImages = mkOption {
 | 
						||
            type = types.listOf types.str;
 | 
						||
            default = [ ];
 | 
						||
            example = [ "ruby:*" "python:*" "php:*" "my.registry.tld:5000/*:*" ];
 | 
						||
            description = ''
 | 
						||
              Whitelist allowed images.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          dockerAllowedServices = mkOption {
 | 
						||
            type = types.listOf types.str;
 | 
						||
            default = [ ];
 | 
						||
            example = [ "postgres:9" "redis:*" "mysql:*" ];
 | 
						||
            description = ''
 | 
						||
              Whitelist allowed services.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          preCloneScript = mkOption {
 | 
						||
            type = types.nullOr types.path;
 | 
						||
            default = null;
 | 
						||
            description = ''
 | 
						||
              Runner-specific command script executed before code is pulled.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          preBuildScript = mkOption {
 | 
						||
            type = types.nullOr types.path;
 | 
						||
            default = null;
 | 
						||
            description = ''
 | 
						||
              Runner-specific command script executed after code is pulled,
 | 
						||
              just before build executes.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          postBuildScript = mkOption {
 | 
						||
            type = types.nullOr types.path;
 | 
						||
            default = null;
 | 
						||
            description = ''
 | 
						||
              Runner-specific command script executed after code is pulled
 | 
						||
              and just after build executes.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          tagList = mkOption {
 | 
						||
            type = types.listOf types.str;
 | 
						||
            default = [ ];
 | 
						||
            description = ''
 | 
						||
              Tag list.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          runUntagged = mkOption {
 | 
						||
            type = types.bool;
 | 
						||
            default = false;
 | 
						||
            description = ''
 | 
						||
              Register to run untagged builds; defaults to
 | 
						||
              <literal>true</literal> when <option>tagList</option> is empty.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          limit = mkOption {
 | 
						||
            type = types.int;
 | 
						||
            default = 0;
 | 
						||
            description = ''
 | 
						||
              Limit how many jobs can be handled concurrently by this service.
 | 
						||
              0 (default) simply means don't limit.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          requestConcurrency = mkOption {
 | 
						||
            type = types.int;
 | 
						||
            default = 0;
 | 
						||
            description = ''
 | 
						||
              Limit number of concurrent requests for new jobs from GitLab.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          maximumTimeout = mkOption {
 | 
						||
            type = types.int;
 | 
						||
            default = 0;
 | 
						||
            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.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          protected = mkOption {
 | 
						||
            type = types.bool;
 | 
						||
            default = false;
 | 
						||
            description = ''
 | 
						||
              When set to true Runner will only run on pipelines
 | 
						||
              triggered on protected branches.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
          debugTraceDisabled = mkOption {
 | 
						||
            type = types.bool;
 | 
						||
            default = false;
 | 
						||
            description = ''
 | 
						||
              When set to true Runner will disable the possibility of
 | 
						||
              using the <literal>CI_DEBUG_TRACE</literal> feature.
 | 
						||
            '';
 | 
						||
          };
 | 
						||
        };
 | 
						||
      });
 | 
						||
    };
 | 
						||
  };
 | 
						||
  config = mkIf cfg.enable {
 | 
						||
    warnings = optional (cfg.configFile != null) "services.gitlab-runner.`configFile` is deprecated, please use services.gitlab-runner.`services`.";
 | 
						||
    environment.systemPackages = [ cfg.package ];
 | 
						||
    systemd.services.gitlab-runner = {
 | 
						||
      description = "Gitlab Runner";
 | 
						||
      documentation = [ "https://docs.gitlab.com/runner/" ];
 | 
						||
      after = [ "network.target" ]
 | 
						||
        ++ optional hasDocker "docker.service";
 | 
						||
      requires = optional hasDocker "docker.service";
 | 
						||
      wantedBy = [ "multi-user.target" ];
 | 
						||
      environment = config.networking.proxy.envVars // {
 | 
						||
        HOME = "/var/lib/gitlab-runner";
 | 
						||
      };
 | 
						||
      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`
 | 
						||
        # to `lib.mkForce false` in your configuration to run this service as root.
 | 
						||
        # You can also set `User` and `Group` options to run this service as desired user.
 | 
						||
        # Make sure to restart service or changes won't apply.
 | 
						||
        DynamicUser = true;
 | 
						||
        StateDirectory = "gitlab-runner";
 | 
						||
        SupplementaryGroups = optional hasDocker "docker";
 | 
						||
        ExecStartPre = "!${configureScript}/bin/gitlab-runner-configure";
 | 
						||
        ExecStart = "${startScript}/bin/gitlab-runner-start";
 | 
						||
        ExecReload = "!${configureScript}/bin/gitlab-runner-configure";
 | 
						||
      } // optionalAttrs (cfg.gracefulTermination) {
 | 
						||
        TimeoutStopSec = "${cfg.gracefulTimeout}";
 | 
						||
        KillSignal = "SIGQUIT";
 | 
						||
        KillMode = "process";
 | 
						||
      };
 | 
						||
    };
 | 
						||
    # Enable docker if `docker` executor is used in any service
 | 
						||
    virtualisation.docker.enable = mkIf (
 | 
						||
      any (s: s.executor == "docker") (attrValues cfg.services)
 | 
						||
    ) (mkDefault true);
 | 
						||
  };
 | 
						||
  imports = [
 | 
						||
    (mkRenamedOptionModule [ "services" "gitlab-runner" "packages" ] [ "services" "gitlab-runner" "extraPackages" ] )
 | 
						||
    (mkRemovedOptionModule [ "services" "gitlab-runner" "configOptions" ] "Use services.gitlab-runner.services option instead" )
 | 
						||
    (mkRemovedOptionModule [ "services" "gitlab-runner" "workDir" ] "You should move contents of workDir (if any) to /var/lib/gitlab-runner" )
 | 
						||
  ];
 | 
						||
}
 |