1{ config, pkgs, lib, ... }:
2
3let
4
5 inherit (lib) mkOption mkIf singleton;
6 inherit (pkgs) ddclient;
7
8 stateDir = "/var/spool/ddclient";
9 ddclientUser = "ddclient";
10 ddclientFlags = "-foreground -verbose -noquiet -file ${ddclientCfg}";
11 ddclientPIDFile = "${stateDir}/ddclient.pid";
12 ddclientCfg = pkgs.writeText "ddclient.conf" ''
13 daemon=600
14 cache=${stateDir}/ddclient.cache
15 pid=${ddclientPIDFile}
16 use=${config.services.ddclient.use}
17 login=${config.services.ddclient.username}
18 password=${config.services.ddclient.password}
19 protocol=${config.services.ddclient.protocol}
20 server=${config.services.ddclient.server}
21 ssl=${if config.services.ddclient.ssl then "yes" else "no"}
22 wildcard=YES
23 ${config.services.ddclient.domain}
24 ${config.services.ddclient.extraConfig}
25 '';
26
27in
28
29{
30
31 ###### interface
32
33 options = {
34
35 services.ddclient = with lib.types; {
36
37 enable = mkOption {
38 default = false;
39 type = bool;
40 description = ''
41 Whether to synchronise your machine's IP address with a dynamic DNS provider (e.g. dyndns.org).
42 '';
43 };
44
45 domain = mkOption {
46 default = "";
47 type = str;
48 description = ''
49 Domain name to synchronize.
50 '';
51 };
52
53 username = mkOption {
54 default = "";
55 type = str;
56 description = ''
57 Username.
58 '';
59 };
60
61 password = mkOption {
62 default = "";
63 type = str;
64 description = ''
65 Password.
66 '';
67 };
68
69 protocol = mkOption {
70 default = "dyndns2";
71 type = str;
72 description = ''
73 Protocol to use with dynamic DNS provider (see http://sourceforge.net/apps/trac/ddclient/wiki/Protocols).
74 '';
75 };
76
77 server = mkOption {
78 default = "";
79 type = str;
80 description = ''
81 Server address.
82 '';
83 };
84
85 ssl = mkOption {
86 default = true;
87 type = bool;
88 description = ''
89 Whether to use to use SSL/TLS to connect to dynamic DNS provider.
90 '';
91 };
92
93 extraConfig = mkOption {
94 default = "";
95 type = str;
96 description = ''
97 Extra configuration. Contents will be added verbatim to the configuration file.
98 '';
99 };
100
101 use = mkOption {
102 default = "web, web=checkip.dyndns.com/, web-skip='Current IP Address: '";
103 type = str;
104 description = ''
105 Method to determine the IP address to send to the dymanic DNS provider.
106 '';
107 };
108 };
109 };
110
111
112 ###### implementation
113
114 config = mkIf config.services.ddclient.enable {
115
116 environment.systemPackages = [ ddclient ];
117
118 users.extraUsers = singleton {
119 name = ddclientUser;
120 uid = config.ids.uids.ddclient;
121 description = "ddclient daemon user";
122 home = stateDir;
123 };
124
125 systemd.services.ddclient = {
126 description = "Dynamic DNS Client";
127 wantedBy = [ "multi-user.target" ];
128 after = [ "network.target" ];
129
130 serviceConfig = {
131 # Uncomment this if too many problems occur:
132 # Type = "forking";
133 User = ddclientUser;
134 Group = "nogroup"; #TODO get this to work
135 PermissionsStartOnly = "true";
136 PIDFile = ddclientPIDFile;
137 ExecStartPre = ''
138 ${pkgs.stdenv.shell} -c "${pkgs.coreutils}/bin/mkdir -m 0755 -p ${stateDir} && ${pkgs.coreutils}/bin/chown ${ddclientUser} ${stateDir}"
139 '';
140 ExecStart = "${ddclient}/bin/ddclient ${ddclientFlags}";
141 #ExecStartPost = "${pkgs.coreutils}/bin/rm -r ${stateDir}"; # Should we have this?
142 };
143 };
144 };
145}