about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorzimbatm <zimbatm@zimbatm.com>2018-02-20 11:28:42 +0000
committerGitHub <noreply@github.com>2018-02-20 11:28:42 +0000
commit3b30e4355bead5978751bafe548ae1d787bb655e (patch)
tree90f47aa427c5a13dbc1ac3e4f92cf79ba93e85b9 /nixos
parentc7aa4fd65bbd2ec5715da6fd164b74a95d41cd5b (diff)
parente552633c20db1c516f6fd46280627ff5f0ee33a0 (diff)
downloadnixlib-3b30e4355bead5978751bafe548ae1d787bb655e.tar
nixlib-3b30e4355bead5978751bafe548ae1d787bb655e.tar.gz
nixlib-3b30e4355bead5978751bafe548ae1d787bb655e.tar.bz2
nixlib-3b30e4355bead5978751bafe548ae1d787bb655e.tar.lz
nixlib-3b30e4355bead5978751bafe548ae1d787bb655e.tar.xz
nixlib-3b30e4355bead5978751bafe548ae1d787bb655e.tar.zst
nixlib-3b30e4355bead5978751bafe548ae1d787bb655e.zip
Merge pull request #35129 from rvl/buildkite-agent-hooks
buildkite-agent service: declarative hooks and extraConfig option
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/continuous-integration/buildkite-agent.nix140
1 files changed, 123 insertions, 17 deletions
diff --git a/nixos/modules/services/continuous-integration/buildkite-agent.nix b/nixos/modules/services/continuous-integration/buildkite-agent.nix
index 1b0198ac93fe..0a0c9f665d25 100644
--- a/nixos/modules/services/continuous-integration/buildkite-agent.nix
+++ b/nixos/modules/services/continuous-integration/buildkite-agent.nix
@@ -4,6 +4,31 @@ with lib;
 
 let
   cfg = config.services.buildkite-agent;
+
+  mkHookOption = { name, description, example ? null }: {
+    inherit name;
+    value = mkOption {
+      default = null;
+      inherit description;
+      type = types.nullOr types.lines;
+    } // (if example == null then {} else { inherit example; });
+  };
+  mkHookOptions = hooks: listToAttrs (map mkHookOption hooks);
+
+  hooksDir = let
+    mkHookEntry = name: value: ''
+      cat > $out/${name} <<EOF
+      #! ${pkgs.stdenv.shell}
+      set -e
+      ${value}
+      EOF
+      chmod 755 $out/${name}
+    '';
+  in pkgs.runCommand "buildkite-agent-hooks" {} ''
+    mkdir $out
+    ${concatStringsSep "\n" (mapAttrsToList mkHookEntry (filterAttrs (n: v: v != null) cfg.hooks))}
+  '';
+
 in
 
 {
@@ -43,25 +68,28 @@ in
 
       name = mkOption {
         type = types.str;
+        default = "%hostname-%n";
         description = ''
           The name of the agent.
         '';
       };
 
-      hooksPath = mkOption {
-        type = types.path;
-        default = "${pkgs.buildkite-agent}/share/hooks";
-        defaultText = "${pkgs.buildkite-agent}/share/hooks";
+      meta-data = mkOption {
+        type = types.str;
+        default = "";
+        example = "queue=default,docker=true,ruby2=true";
         description = ''
-          Path to the directory storing the hooks.
+          Meta data for the agent. This is a comma-separated list of
+          <code>key=value</code> pairs.
         '';
       };
 
-      meta-data = mkOption {
-        type = types.str;
+      extraConfig = mkOption {
+        type = types.lines;
         default = "";
+        example = "debug=true";
         description = ''
-          Meta data for the agent.
+          Extra lines to be added verbatim to the configuration file.
         '';
       };
 
@@ -85,6 +113,74 @@ in
             '';
           };
         };
+
+      hooks = mkHookOptions [
+        { name = "checkout";
+          description = ''
+            The `checkout` hook script will replace the default checkout routine of the
+            bootstrap.sh script. You can use this hook to do your own SCM checkout
+            behaviour
+          ''; }
+        { name = "command";
+          description = ''
+            The `command` hook script will replace the default implementation of running
+            the build command.
+          ''; }
+        { name = "environment";
+          description = ''
+            The `environment` hook will run before all other commands, and can be used
+            to set up secrets, data, etc. Anything exported in hooks will be available
+            to the build script.
+
+            Note: the contents of this file will be copied to the world-readable
+            Nix store.
+          '';
+          example = ''
+            export SECRET_VAR=`head -1 /run/keys/secret`
+          ''; }
+        { name = "post-artifact";
+          description = ''
+            The `post-artifact` hook will run just after artifacts are uploaded
+          ''; }
+        { name = "post-checkout";
+          description = ''
+            The `post-checkout` hook will run after the bootstrap script has checked out
+            your projects source code.
+          ''; }
+        { name = "post-command";
+          description = ''
+            The `post-command` hook will run after the bootstrap script has run your
+            build commands
+          ''; }
+        { name = "pre-artifact";
+          description = ''
+            The `pre-artifact` hook will run just before artifacts are uploaded
+          ''; }
+        { name = "pre-checkout";
+          description = ''
+            The `pre-checkout` hook will run just before your projects source code is
+            checked out from your SCM provider
+          ''; }
+        { name = "pre-command";
+          description = ''
+            The `pre-command` hook will run just before your build command runs
+          ''; }
+        { name = "pre-exit";
+          description = ''
+            The `pre-exit` hook will run just before your build job finishes
+          ''; }
+      ];
+
+      hooksPath = mkOption {
+        type = types.path;
+        default = hooksDir;
+        defaultText = "generated from services.buildkite-agent.hooks";
+        description = ''
+          Path to the directory storing the hooks.
+          Consider using <option>services.buildkite-agent.hooks.&lt;name&gt;</option>
+          instead.
+        '';
+      };
     };
   };
 
@@ -100,13 +196,10 @@ in
     environment.systemPackages = [ cfg.package ];
 
     systemd.services.buildkite-agent =
-      let copy = x: target: perms:
-                 "cp -f ${x} ${target}; ${pkgs.coreutils}/bin/chmod ${toString perms} ${target}; ";
-      in
       { description = "Buildkite Agent";
         wantedBy = [ "multi-user.target" ];
         after = [ "network.target" ];
-        path = cfg.runtimePackages;
+        path = cfg.runtimePackages ++ [ pkgs.coreutils ];
         environment = config.networking.proxy.envVars // {
           HOME = cfg.dataDir;
           NIX_REMOTE = "daemon";
@@ -114,10 +207,14 @@ in
 
         ## NB: maximum care is taken so that secrets (ssh keys and the CI token)
         ##     don't end up in the Nix store.
-        preStart = ''
-            ${pkgs.coreutils}/bin/mkdir -m 0700 -p ${cfg.dataDir}/.ssh
-            ${copy (toString cfg.openssh.privateKeyPath) "${cfg.dataDir}/.ssh/id_rsa"     600}
-            ${copy (toString cfg.openssh.publicKeyPath)  "${cfg.dataDir}/.ssh/id_rsa.pub" 600}
+        preStart = let
+          sshDir = "${cfg.dataDir}/.ssh";
+        in
+          ''
+            mkdir -m 0700 -p "${sshDir}"
+            cp -f "${toString cfg.openssh.privateKeyPath}" "${sshDir}/id_rsa"
+            cp -f "${toString cfg.openssh.publicKeyPath}"  "${sshDir}/id_rsa.pub"
+            chmod 600 "${sshDir}"/id_rsa*
 
             cat > "${cfg.dataDir}/buildkite-agent.cfg" <<EOF
             token="$(cat ${toString cfg.tokenPath})"
@@ -125,7 +222,7 @@ in
             meta-data="${cfg.meta-data}"
             build-path="${cfg.dataDir}/builds"
             hooks-path="${cfg.hooksPath}"
-            bootstrap-script="${pkgs.buildkite-agent}/share/bootstrap.sh"
+            ${cfg.extraConfig}
             EOF
           '';
 
@@ -137,6 +234,15 @@ in
             TimeoutSec = 10;
           };
       };
+
+    assertions = [
+      { assertion = cfg.hooksPath == hooksDir || all isNull (attrValues cfg.hooks);
+        message = ''
+          Options `services.buildkite-agent.hooksPath' and
+          `services.buildkite-agent.hooks.<name>' are mutually exclusive.
+        '';
+      }
+    ];
   };
   imports = [
     (mkRenamedOptionModule [ "services" "buildkite-agent" "token" ]                [ "services" "buildkite-agent" "tokenPath" ])