1{ config, lib, pkgs, ... }: 2with lib; 3let 4 cfg = config.services.jenkins; 5in { 6 options = { 7 services.jenkins = { 8 enable = mkOption { 9 type = types.bool; 10 default = false; 11 description = '' 12 Whether to enable the jenkins continuous integration server. 13 ''; 14 }; 15 16 user = mkOption { 17 default = "jenkins"; 18 type = types.str; 19 description = '' 20 User the jenkins server should execute under. 21 ''; 22 }; 23 24 group = mkOption { 25 default = "jenkins"; 26 type = types.str; 27 description = '' 28 If the default user "jenkins" is configured then this is the primary 29 group of that user. 30 ''; 31 }; 32 33 extraGroups = mkOption { 34 type = types.listOf types.str; 35 default = [ ]; 36 example = [ "wheel" "dialout" ]; 37 description = '' 38 List of extra groups that the "jenkins" user should be a part of. 39 ''; 40 }; 41 42 home = mkOption { 43 default = "/var/lib/jenkins"; 44 type = types.path; 45 description = '' 46 The path to use as JENKINS_HOME. If the default user "jenkins" is configured then 47 this is the home of the "jenkins" user. 48 ''; 49 }; 50 51 port = mkOption { 52 default = 8080; 53 type = types.int; 54 description = '' 55 Specifies port number on which the jenkins HTTP interface listens. The default is 8080. 56 ''; 57 }; 58 59 packages = mkOption { 60 default = [ pkgs.stdenv pkgs.git pkgs.jdk config.programs.ssh.package pkgs.nix ]; 61 type = types.listOf types.package; 62 description = '' 63 Packages to add to PATH for the jenkins process. 64 ''; 65 }; 66 67 environment = mkOption { 68 default = { }; 69 type = with types; attrsOf str; 70 description = '' 71 Additional environment variables to be passed to the jenkins process. 72 As a base environment, jenkins receives NIX_PATH, SSL_CERT_FILE and 73 GIT_SSL_CAINFO from <option>environment.sessionVariables</option>, 74 NIX_REMOTE is set to "daemon" and JENKINS_HOME is set to 75 the value of <option>services.jenkins.home</option>. This option has 76 precedence and can be used to override those mentioned variables. 77 ''; 78 }; 79 80 extraOptions = mkOption { 81 type = types.listOf types.str; 82 default = [ ]; 83 example = [ "--debug=9" "--httpListenAddress=localhost" ]; 84 description = '' 85 Additional command line arguments to pass to Jenkins. 86 ''; 87 }; 88 }; 89 }; 90 91 config = mkIf cfg.enable { 92 users.extraGroups = optional (cfg.group == "jenkins") { 93 name = "jenkins"; 94 gid = config.ids.gids.jenkins; 95 }; 96 97 users.extraUsers = optional (cfg.user == "jenkins") { 98 name = "jenkins"; 99 description = "jenkins user"; 100 createHome = true; 101 home = cfg.home; 102 group = cfg.group; 103 extraGroups = cfg.extraGroups; 104 useDefaultShell = true; 105 uid = config.ids.uids.jenkins; 106 }; 107 108 systemd.services.jenkins = { 109 description = "Jenkins Continuous Integration Server"; 110 after = [ "network.target" ]; 111 wantedBy = [ "multi-user.target" ]; 112 113 environment = 114 let 115 selectedSessionVars = 116 lib.filterAttrs (n: v: builtins.elem n 117 [ "NIX_PATH" 118 "SSL_CERT_FILE" 119 "GIT_SSL_CAINFO" 120 ]) 121 config.environment.sessionVariables; 122 in 123 selectedSessionVars // 124 { JENKINS_HOME = cfg.home; 125 NIX_REMOTE = "daemon"; 126 } // 127 cfg.environment; 128 129 path = cfg.packages; 130 131 script = '' 132 ${pkgs.jdk}/bin/java -jar ${pkgs.jenkins} --httpPort=${toString cfg.port} ${concatStringsSep " " cfg.extraOptions} 133 ''; 134 135 postStart = '' 136 until ${pkgs.curl}/bin/curl -s -L localhost:${toString cfg.port} ; do 137 sleep 10 138 done 139 while true ; do 140 index=`${pkgs.curl}/bin/curl -s -L localhost:${toString cfg.port}` 141 if [[ !("$index" =~ 'Please wait while Jenkins is restarting' || 142 "$index" =~ 'Please wait while Jenkins is getting ready to work') ]]; then 143 exit 0 144 fi 145 sleep 30 146 done 147 ''; 148 149 serviceConfig = { 150 User = cfg.user; 151 }; 152 }; 153 }; 154}