at 21.11-pre 5.6 kB view raw
1{ config, pkgs, lib, ... }: 2 3let 4 cfg = config.services.ddclient; 5 boolToStr = bool: if bool then "yes" else "no"; 6 dataDir = "/var/lib/ddclient"; 7 8 configText = '' 9 # This file can be used as a template for configFile or is automatically generated by Nix options. 10 cache=${dataDir}/ddclient.cache 11 foreground=YES 12 use=${cfg.use} 13 login=${cfg.username} 14 password=${cfg.password} 15 protocol=${cfg.protocol} 16 ${lib.optionalString (cfg.script != "") "script=${cfg.script}"} 17 ${lib.optionalString (cfg.server != "") "server=${cfg.server}"} 18 ${lib.optionalString (cfg.zone != "") "zone=${cfg.zone}"} 19 ssl=${boolToStr cfg.ssl} 20 wildcard=YES 21 quiet=${boolToStr cfg.quiet} 22 verbose=${boolToStr cfg.verbose} 23 ${cfg.extraConfig} 24 ${lib.concatStringsSep "," cfg.domains} 25 ''; 26 27in 28 29with lib; 30 31{ 32 33 imports = [ 34 (mkChangedOptionModule [ "services" "ddclient" "domain" ] [ "services" "ddclient" "domains" ] 35 (config: 36 let value = getAttrFromPath [ "services" "ddclient" "domain" ] config; 37 in if value != "" then [ value ] else [])) 38 (mkRemovedOptionModule [ "services" "ddclient" "homeDir" ] "") 39 ]; 40 41 ###### interface 42 43 options = { 44 45 services.ddclient = with lib.types; { 46 47 enable = mkOption { 48 default = false; 49 type = bool; 50 description = '' 51 Whether to synchronise your machine's IP address with a dynamic DNS provider (e.g. dyndns.org). 52 ''; 53 }; 54 55 domains = mkOption { 56 default = [ "" ]; 57 type = listOf str; 58 description = '' 59 Domain name(s) to synchronize. 60 ''; 61 }; 62 63 username = mkOption { 64 default = ""; 65 type = str; 66 description = '' 67 User name. 68 ''; 69 }; 70 71 password = mkOption { 72 default = ""; 73 type = str; 74 description = '' 75 Password. WARNING: The password becomes world readable in the Nix store. 76 ''; 77 }; 78 79 interval = mkOption { 80 default = "10min"; 81 type = str; 82 description = '' 83 The interval at which to run the check and update. 84 See <command>man 7 systemd.time</command> for the format. 85 ''; 86 }; 87 88 configFile = mkOption { 89 default = "/etc/ddclient.conf"; 90 type = path; 91 description = '' 92 Path to configuration file. 93 When set to the default '/etc/ddclient.conf' it will be populated with the various other options in this module. When it is changed (for example: '/root/nixos/secrets/ddclient.conf') the file read directly to configure ddclient. This is a source of impurity. 94 The purpose of this is to avoid placing secrets into the store. 95 ''; 96 example = "/root/nixos/secrets/ddclient.conf"; 97 }; 98 99 protocol = mkOption { 100 default = "dyndns2"; 101 type = str; 102 description = '' 103 Protocol to use with dynamic DNS provider (see https://sourceforge.net/p/ddclient/wiki/protocols). 104 ''; 105 }; 106 107 server = mkOption { 108 default = ""; 109 type = str; 110 description = '' 111 Server address. 112 ''; 113 }; 114 115 ssl = mkOption { 116 default = true; 117 type = bool; 118 description = '' 119 Whether to use to use SSL/TLS to connect to dynamic DNS provider. 120 ''; 121 }; 122 123 124 quiet = mkOption { 125 default = false; 126 type = bool; 127 description = '' 128 Print no messages for unnecessary updates. 129 ''; 130 }; 131 132 script = mkOption { 133 default = ""; 134 type = str; 135 description = '' 136 script as required by some providers. 137 ''; 138 }; 139 140 use = mkOption { 141 default = "web, web=checkip.dyndns.com/, web-skip='Current IP Address: '"; 142 type = str; 143 description = '' 144 Method to determine the IP address to send to the dynamic DNS provider. 145 ''; 146 }; 147 148 verbose = mkOption { 149 default = true; 150 type = bool; 151 description = '' 152 Print verbose information. 153 ''; 154 }; 155 156 zone = mkOption { 157 default = ""; 158 type = str; 159 description = '' 160 zone as required by some providers. 161 ''; 162 }; 163 164 extraConfig = mkOption { 165 default = ""; 166 type = lines; 167 description = '' 168 Extra configuration. Contents will be added verbatim to the configuration file. 169 ''; 170 }; 171 }; 172 }; 173 174 175 ###### implementation 176 177 config = mkIf config.services.ddclient.enable { 178 environment.etc."ddclient.conf" = { 179 enable = cfg.configFile == "/etc/ddclient.conf"; 180 mode = "0600"; 181 text = configText; 182 }; 183 184 systemd.services.ddclient = { 185 description = "Dynamic DNS Client"; 186 wantedBy = [ "multi-user.target" ]; 187 after = [ "network.target" ]; 188 restartTriggers = [ config.environment.etc."ddclient.conf".source ]; 189 190 serviceConfig = rec { 191 DynamicUser = true; 192 RuntimeDirectory = StateDirectory; 193 StateDirectory = builtins.baseNameOf dataDir; 194 Type = "oneshot"; 195 ExecStartPre = "!${lib.getBin pkgs.coreutils}/bin/install -m666 ${cfg.configFile} /run/${RuntimeDirectory}/ddclient.conf"; 196 ExecStart = "${lib.getBin pkgs.ddclient}/bin/ddclient -file /run/${RuntimeDirectory}/ddclient.conf"; 197 }; 198 }; 199 200 systemd.timers.ddclient = { 201 description = "Run ddclient"; 202 wantedBy = [ "timers.target" ]; 203 timerConfig = { 204 OnBootSec = cfg.interval; 205 OnUnitInactiveSec = cfg.interval; 206 }; 207 }; 208 }; 209}