1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.icecream.daemon;
7in {
8
9 ###### interface
10
11 options = {
12
13 services.icecream.daemon = {
14
15 enable = mkEnableOption "Icecream Daemon";
16
17 openFirewall = mkOption {
18 type = types.bool;
19 description = ''
20 Whether to automatically open receive port in the firewall.
21 '';
22 };
23
24 openBroadcast = mkOption {
25 type = types.bool;
26 description = ''
27 Whether to automatically open the firewall for scheduler discovery.
28 '';
29 };
30
31 cacheLimit = mkOption {
32 type = types.ints.u16;
33 default = 256;
34 description = ''
35 Maximum size in Megabytes of cache used to store compile environments of compile clients.
36 '';
37 };
38
39 netName = mkOption {
40 type = types.str;
41 default = "ICECREAM";
42 description = ''
43 Network name to connect to. A scheduler with the same name needs to be running.
44 '';
45 };
46
47 noRemote = mkOption {
48 type = types.bool;
49 default = false;
50 description = ''
51 Prevent jobs from other nodes being scheduled on this daemon.
52 '';
53 };
54
55 schedulerHost = mkOption {
56 type = types.nullOr types.str;
57 default = null;
58 description = ''
59 Explicit scheduler hostname, useful in firewalled environments.
60
61 Uses scheduler autodiscovery via broadcast if set to null.
62 '';
63 };
64
65 maxProcesses = mkOption {
66 type = types.nullOr types.ints.u16;
67 default = null;
68 description = ''
69 Maximum number of compile jobs started in parallel for this daemon.
70
71 Uses the number of CPUs if set to null.
72 '';
73 };
74
75 nice = mkOption {
76 type = types.int;
77 default = 5;
78 description = ''
79 The level of niceness to use.
80 '';
81 };
82
83 hostname = mkOption {
84 type = types.nullOr types.str;
85 default = null;
86 description = ''
87 Hostname of the daemon in the icecream infrastructure.
88
89 Uses the hostname retrieved via uname if set to null.
90 '';
91 };
92
93 user = mkOption {
94 type = types.str;
95 default = "icecc";
96 description = ''
97 User to run the icecream daemon as. Set to root to enable receive of
98 remote compile environments.
99 '';
100 };
101
102 package = mkPackageOption pkgs "icecream" { };
103
104 extraArgs = mkOption {
105 type = types.listOf types.str;
106 default = [];
107 description = "Additional command line parameters.";
108 example = [ "-v" ];
109 };
110 };
111 };
112
113 ###### implementation
114
115 config = mkIf cfg.enable {
116 networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ 10245 ];
117 networking.firewall.allowedUDPPorts = mkIf cfg.openBroadcast [ 8765 ];
118
119 systemd.services.icecc-daemon = {
120 description = "Icecream compile daemon";
121 after = [ "network.target" ];
122 wantedBy = [ "multi-user.target" ];
123
124 serviceConfig = {
125 ExecStart = escapeShellArgs ([
126 "${getBin cfg.package}/bin/iceccd"
127 "-b" "$STATE_DIRECTORY"
128 "-u" "icecc"
129 (toString cfg.nice)
130 ]
131 ++ optionals (cfg.schedulerHost != null) ["-s" cfg.schedulerHost]
132 ++ optionals (cfg.netName != null) [ "-n" cfg.netName ]
133 ++ optionals (cfg.cacheLimit != null) [ "--cache-limit" (toString cfg.cacheLimit) ]
134 ++ optionals (cfg.maxProcesses != null) [ "-m" (toString cfg.maxProcesses) ]
135 ++ optionals (cfg.hostname != null) [ "-N" (cfg.hostname) ]
136 ++ optional cfg.noRemote "--no-remote"
137 ++ cfg.extraArgs);
138 DynamicUser = true;
139 User = "icecc";
140 Group = "icecc";
141 StateDirectory = "icecc";
142 RuntimeDirectory = "icecc";
143 AmbientCapabilities = "CAP_SYS_CHROOT";
144 CapabilityBoundingSet = "CAP_SYS_CHROOT";
145 };
146 };
147 };
148
149 meta.maintainers = with lib.maintainers; [ emantor ];
150}