1{
2 config,
3 lib,
4 options,
5 pkgs,
6 ...
7}:
8let
9 cfg = config.services.gocd-agent;
10 opt = options.services.gocd-agent;
11in
12{
13 options = {
14 services.gocd-agent = {
15 enable = lib.mkEnableOption "gocd-agent";
16
17 user = lib.mkOption {
18 default = "gocd-agent";
19 type = lib.types.str;
20 description = ''
21 User the Go.CD agent should execute under.
22 '';
23 };
24
25 group = lib.mkOption {
26 default = "gocd-agent";
27 type = lib.types.str;
28 description = ''
29 If the default user "gocd-agent" is configured then this is the primary
30 group of that user.
31 '';
32 };
33
34 extraGroups = lib.mkOption {
35 type = lib.types.listOf lib.types.str;
36 default = [ ];
37 example = [
38 "wheel"
39 "docker"
40 ];
41 description = ''
42 List of extra groups that the "gocd-agent" user should be a part of.
43 '';
44 };
45
46 packages = lib.mkOption {
47 default = [
48 pkgs.stdenv
49 pkgs.jre
50 pkgs.git
51 config.programs.ssh.package
52 pkgs.nix
53 ];
54 defaultText = lib.literalExpression "[ pkgs.stdenv pkgs.jre pkgs.git config.programs.ssh.package pkgs.nix ]";
55 type = lib.types.listOf lib.types.package;
56 description = ''
57 Packages to add to PATH for the Go.CD agent process.
58 '';
59 };
60
61 agentConfig = lib.mkOption {
62 default = "";
63 type = lib.types.str;
64 example = ''
65 agent.auto.register.resources=ant,java
66 agent.auto.register.environments=QA,Performance
67 agent.auto.register.hostname=Agent01
68 '';
69 description = ''
70 Agent registration configuration.
71 '';
72 };
73
74 goServer = lib.mkOption {
75 default = "https://127.0.0.1:8154/go";
76 type = lib.types.str;
77 description = ''
78 URL of the GoCD Server to attach the Go.CD Agent to.
79 '';
80 };
81
82 workDir = lib.mkOption {
83 default = "/var/lib/go-agent";
84 type = lib.types.str;
85 description = ''
86 Specifies the working directory in which the Go.CD agent java archive resides.
87 '';
88 };
89
90 initialJavaHeapSize = lib.mkOption {
91 default = "128m";
92 type = lib.types.str;
93 description = ''
94 Specifies the initial java heap memory size for the Go.CD agent java process.
95 '';
96 };
97
98 maxJavaHeapMemory = lib.mkOption {
99 default = "256m";
100 type = lib.types.str;
101 description = ''
102 Specifies the java maximum heap memory size for the Go.CD agent java process.
103 '';
104 };
105
106 startupOptions = lib.mkOption {
107 type = lib.types.listOf lib.types.str;
108 default = [
109 "-Xms${cfg.initialJavaHeapSize}"
110 "-Xmx${cfg.maxJavaHeapMemory}"
111 "-Djava.io.tmpdir=/tmp"
112 "-Dcruise.console.publish.interval=10"
113 "-Djava.security.egd=file:/dev/./urandom"
114 ];
115 defaultText = lib.literalExpression ''
116 [
117 "-Xms''${config.${opt.initialJavaHeapSize}}"
118 "-Xmx''${config.${opt.maxJavaHeapMemory}}"
119 "-Djava.io.tmpdir=/tmp"
120 "-Dcruise.console.publish.interval=10"
121 "-Djava.security.egd=file:/dev/./urandom"
122 ]
123 '';
124 description = ''
125 Specifies startup command line arguments to pass to Go.CD agent
126 java process.
127 '';
128 };
129
130 extraOptions = lib.mkOption {
131 default = [ ];
132 type = lib.types.listOf lib.types.str;
133 example = [
134 "-X debug"
135 "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006"
136 "-verbose:gc"
137 "-Xloggc:go-agent-gc.log"
138 "-XX:+PrintGCTimeStamps"
139 "-XX:+PrintTenuringDistribution"
140 "-XX:+PrintGCDetails"
141 "-XX:+PrintGC"
142 ];
143 description = ''
144 Specifies additional command line arguments to pass to Go.CD agent
145 java process. Example contains debug and gcLog arguments.
146 '';
147 };
148
149 environment = lib.mkOption {
150 default = { };
151 type = with lib.types; attrsOf str;
152 description = ''
153 Additional environment variables to be passed to the Go.CD agent process.
154 As a base environment, Go.CD agent receives NIX_PATH from
155 {option}`environment.sessionVariables`, NIX_REMOTE is set to
156 "daemon".
157 '';
158 };
159 };
160 };
161
162 config = lib.mkIf cfg.enable {
163 users.groups = lib.optionalAttrs (cfg.group == "gocd-agent") {
164 gocd-agent.gid = config.ids.gids.gocd-agent;
165 };
166
167 users.users = lib.optionalAttrs (cfg.user == "gocd-agent") {
168 gocd-agent = {
169 description = "gocd-agent user";
170 createHome = true;
171 home = cfg.workDir;
172 group = cfg.group;
173 extraGroups = cfg.extraGroups;
174 useDefaultShell = true;
175 uid = config.ids.uids.gocd-agent;
176 };
177 };
178
179 systemd.services.gocd-agent = {
180 description = "GoCD Agent";
181 after = [ "network.target" ];
182 wantedBy = [ "multi-user.target" ];
183
184 environment =
185 let
186 selectedSessionVars = lib.filterAttrs (
187 n: v: builtins.elem n [ "NIX_PATH" ]
188 ) config.environment.sessionVariables;
189 in
190 selectedSessionVars
191 // {
192 NIX_REMOTE = "daemon";
193 AGENT_WORK_DIR = cfg.workDir;
194 AGENT_STARTUP_ARGS = ''${lib.concatStringsSep " " cfg.startupOptions}'';
195 LOG_DIR = cfg.workDir;
196 LOG_FILE = "${cfg.workDir}/go-agent-start.log";
197 }
198 // cfg.environment;
199
200 path = cfg.packages;
201
202 script = ''
203 MPATH="''${PATH}";
204 source /etc/profile
205 export PATH="''${MPATH}:''${PATH}";
206
207 if ! test -f ~/.nixpkgs/config.nix; then
208 mkdir -p ~/.nixpkgs/
209 echo "{ allowUnfree = true; }" > ~/.nixpkgs/config.nix
210 fi
211
212 mkdir -p config
213 rm -f config/autoregister.properties
214 ln -s "${pkgs.writeText "autoregister.properties" cfg.agentConfig}" config/autoregister.properties
215
216 ${pkgs.git}/bin/git config --global --add http.sslCAinfo ${config.security.pki.caBundle}
217 ${pkgs.jre}/bin/java ${lib.concatStringsSep " " cfg.startupOptions} \
218 ${lib.concatStringsSep " " cfg.extraOptions} \
219 -jar ${pkgs.gocd-agent}/go-agent/agent-bootstrapper.jar \
220 -serverUrl ${cfg.goServer}
221 '';
222
223 serviceConfig = {
224 User = cfg.user;
225 WorkingDirectory = cfg.workDir;
226 RestartSec = 30;
227 Restart = "on-failure";
228 };
229 };
230 };
231}