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 = { NIX_REMOTE = "daemon"; };
69 type = with types; attrsOf str;
70 description = ''
71 Additional environment variables to be passed to the jenkins process.
72 The environment will always include JENKINS_HOME.
73 '';
74 };
75
76 extraOptions = mkOption {
77 type = types.listOf types.str;
78 default = [ ];
79 example = [ "--debug=9" "--httpListenAddress=localhost" ];
80 description = ''
81 Additional command line arguments to pass to Jenkins.
82 '';
83 };
84 };
85 };
86
87 config = mkIf cfg.enable {
88 users.extraGroups = optional (cfg.group == "jenkins") {
89 name = "jenkins";
90 gid = config.ids.gids.jenkins;
91 };
92
93 users.extraUsers = optional (cfg.user == "jenkins") {
94 name = "jenkins";
95 description = "jenkins user";
96 createHome = true;
97 home = cfg.home;
98 group = cfg.group;
99 extraGroups = cfg.extraGroups;
100 useDefaultShell = true;
101 uid = config.ids.uids.jenkins;
102 };
103
104 systemd.services.jenkins = {
105 description = "Jenkins Continuous Integration Server";
106 after = [ "network.target" ];
107 wantedBy = [ "multi-user.target" ];
108
109 environment = {
110 JENKINS_HOME = cfg.home;
111 } // cfg.environment;
112
113 path = cfg.packages;
114
115 script = ''
116 ${pkgs.jdk}/bin/java -jar ${pkgs.jenkins} --httpPort=${toString cfg.port} ${concatStringsSep " " cfg.extraOptions}
117 '';
118
119 postStart = ''
120 until ${pkgs.curl}/bin/curl -s -L localhost:${toString cfg.port} ; do
121 sleep 10
122 done
123 while true ; do
124 index=`${pkgs.curl}/bin/curl -s -L localhost:${toString cfg.port}`
125 if [[ !("$index" =~ 'Please wait while Jenkins is restarting' ||
126 "$index" =~ 'Please wait while Jenkins is getting ready to work') ]]; then
127 exit 0
128 fi
129 sleep 30
130 done
131 '';
132
133 serviceConfig = {
134 User = cfg.user;
135 };
136 };
137 };
138}