1{ config, lib, pkgs, ... }:
2with lib;
3
4let
5 nncpCfgFile = "/run/nncp.hjson";
6 programCfg = config.programs.nncp;
7 callerCfg = config.services.nncp.caller;
8 daemonCfg = config.services.nncp.daemon;
9 settingsFormat = pkgs.formats.json { };
10 jsonCfgFile = settingsFormat.generate "nncp.json" programCfg.settings;
11 pkg = programCfg.package;
12in {
13 options = {
14
15 services.nncp = {
16 caller = {
17 enable = mkEnableOption ''
18 cron'ed NNCP TCP daemon caller.
19 The daemon will take configuration from
20 [](#opt-programs.nncp.settings)
21 '';
22 extraArgs = mkOption {
23 type = with types; listOf str;
24 description = "Extra command-line arguments to pass to caller.";
25 default = [ ];
26 example = [ "-autotoss" ];
27 };
28 };
29
30 daemon = {
31 enable = mkEnableOption ''
32 NNCP TCP synronization daemon.
33 The daemon will take configuration from
34 [](#opt-programs.nncp.settings)
35 '';
36 socketActivation = {
37 enable = mkEnableOption ''
38 Whether to run nncp-daemon persistently or socket-activated.
39 '';
40 listenStreams = mkOption {
41 type = with types; listOf str;
42 description = ''
43 TCP sockets to bind to.
44 See [](#opt-systemd.sockets._name_.listenStreams).
45 '';
46 default = [ "5400" ];
47 };
48 };
49 extraArgs = mkOption {
50 type = with types; listOf str;
51 description = "Extra command-line arguments to pass to daemon.";
52 default = [ ];
53 example = [ "-autotoss" ];
54 };
55 };
56
57 };
58 };
59
60 config = mkIf (programCfg.enable or callerCfg.enable or daemonCfg.enable) {
61
62 assertions = [{
63 assertion = with builtins;
64 let
65 callerCongfigured =
66 let neigh = config.programs.nncp.settings.neigh or { };
67 in lib.lists.any (x: hasAttr "calls" x && x.calls != [ ])
68 (attrValues neigh);
69 in !callerCfg.enable || callerCongfigured;
70 message = "NNCP caller enabled but call configuration is missing";
71 }];
72
73 systemd.services."nncp-caller" = {
74 inherit (callerCfg) enable;
75 description = "Croned NNCP TCP daemon caller.";
76 documentation = [ "http://www.nncpgo.org/nncp_002dcaller.html" ];
77 after = [ "network.target" ];
78 wantedBy = [ "multi-user.target" ];
79 serviceConfig = {
80 ExecStart = ''
81 ${pkg}/bin/nncp-caller -noprogress -cfg "${nncpCfgFile}" ${
82 lib.strings.escapeShellArgs callerCfg.extraArgs
83 }'';
84 Group = "uucp";
85 UMask = "0002";
86 };
87 };
88
89 systemd.services."nncp-daemon" = mkIf daemonCfg.enable {
90 enable = !daemonCfg.socketActivation.enable;
91 description = "NNCP TCP syncronization daemon.";
92 documentation = [ "http://www.nncpgo.org/nncp_002ddaemon.html" ];
93 after = [ "network.target" ];
94 wantedBy = [ "multi-user.target" ];
95 serviceConfig = {
96 ExecStart = ''
97 ${pkg}/bin/nncp-daemon -noprogress -cfg "${nncpCfgFile}" ${
98 lib.strings.escapeShellArgs daemonCfg.extraArgs
99 }'';
100 Restart = "on-failure";
101 Group = "uucp";
102 UMask = "0002";
103 };
104 };
105
106 systemd.services."nncp-daemon@" = mkIf daemonCfg.socketActivation.enable {
107 description = "NNCP TCP syncronization daemon.";
108 documentation = [ "http://www.nncpgo.org/nncp_002ddaemon.html" ];
109 after = [ "network.target" ];
110 serviceConfig = {
111 ExecStart = ''
112 ${pkg}/bin/nncp-daemon -noprogress -ucspi -cfg "${nncpCfgFile}" ${
113 lib.strings.escapeShellArgs daemonCfg.extraArgs
114 }'';
115 Group = "uucp";
116 UMask = "0002";
117 StandardInput = "socket";
118 StandardOutput = "inherit";
119 StandardError = "journal";
120 };
121 };
122
123 systemd.sockets.nncp-daemon = mkIf daemonCfg.socketActivation.enable {
124 inherit (daemonCfg.socketActivation) listenStreams;
125 description = "socket for NNCP TCP syncronization.";
126 conflicts = [ "nncp-daemon.service" ];
127 wantedBy = [ "sockets.target" ];
128 socketConfig.Accept = true;
129 };
130 };
131}