From 4bf66ba89caacc99605aea46fe937a2acb31c446 Mon Sep 17 00:00:00 2001 From: Eduard Bachmakov Date: Wed, 18 Feb 2015 23:44:29 -0500 Subject: [PATCH] ddclient module: fix module * rewrite to systemd.services * disable forking to give systemd better control * verifiably run as ddclient user * expose ssl option * unset default value for dyndns server * rename option "web" to "use" to be consistent with ddclient docs * add descriptions * add types to options * clean up formatting --- .../modules/services/networking/ddclient.nix | 99 +++++++++++-------- 1 file changed, 58 insertions(+), 41 deletions(-) diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix index bb94a8dacfa2..f01deb6ee7c8 100644 --- a/nixos/modules/services/networking/ddclient.nix +++ b/nixos/modules/services/networking/ddclient.nix @@ -3,24 +3,22 @@ let inherit (lib) mkOption mkIf singleton; - inherit (pkgs) ddclient; stateDir = "/var/spool/ddclient"; - ddclientUser = "ddclient"; - - ddclientFlags = "-foreground -file ${ddclientCfg}"; - + ddclientFlags = "-foreground -verbose -noquiet -file ${ddclientCfg}"; + ddclientPIDFile = "${stateDir}/ddclient.pid"; ddclientCfg = pkgs.writeText "ddclient.conf" '' daemon=600 cache=${stateDir}/ddclient.cache - pid=${stateDir}/ddclient.pid - use=${config.services.ddclient.web} + pid=${ddclientPIDFile} + use=${config.services.ddclient.use} login=${config.services.ddclient.username} password=${config.services.ddclient.password} protocol=${config.services.ddclient.protocol} server=${config.services.ddclient.server} + ssl=${if config.services.ddclient.ssl then "yes" else "yes"} wildcard=YES ${config.services.ddclient.domain} ${config.services.ddclient.extraConfig} @@ -34,10 +32,11 @@ in options = { - services.ddclient = { + services.ddclient = with lib.types; { enable = mkOption { default = false; + type = bool; description = '' Whether to synchronise your machine's IP address with a dynamic DNS provider (e.g. dyndns.org). ''; @@ -45,6 +44,7 @@ in domain = mkOption { default = ""; + type = str; description = '' Domain name to synchronize. ''; @@ -52,76 +52,93 @@ in username = mkOption { default = ""; + type = str; description = '' Username. ''; }; password = mkOption { - default = "" ; + default = ""; + type = str; description = '' Password. ''; }; protocol = mkOption { - default = "dyndns2" ; + default = "dyndns2"; + type = str; description = '' - Protocol to use with dynamic DNS provider. (see also, http://sourceforge.net/apps/trac/ddclient/wiki/Protocols) + Protocol to use with dynamic DNS provider (see http://sourceforge.net/apps/trac/ddclient/wiki/Protocols). ''; }; server = mkOption { - default = "members.dyndns.org" ; + default = ""; + type = str; description = '' - Server + Server address. + ''; + }; + + ssl = mkOption { + default = true; + type = bool; + description = '' + Whether to use to use SSL/TLS to connect to dynamic DNS provider. ''; }; extraConfig = mkOption { - default = "" ; + default = ""; + type = str; description = '' Extra configuration. Contents will be added verbatim to the configuration file. ''; }; - web = mkOption { - default = "web, web=checkip.dyndns.com/, web-skip='Current IP Address: '" ; - description = ""; + use = mkOption { + default = "web, web=checkip.dyndns.com/, web-skip='Current IP Address: '"; + type = str; + description = '' + Method to determine the IP address to send to the dymanic DNS provider. + ''; }; - }; - }; ###### implementation config = mkIf config.services.ddclient.enable { - + environment.systemPackages = [ ddclient ]; - users.extraUsers = singleton - { name = ddclientUser; - uid = config.ids.uids.ddclient; - description = "ddclient daemon user"; - home = stateDir; + users.extraUsers = singleton { + name = ddclientUser; + uid = config.ids.uids.ddclient; + description = "ddclient daemon user"; + home = stateDir; + }; + + systemd.services.ddclient = { + description = "Dynamic DNS Client"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + # This may change back to forking if too many problems occur: + type = "simple"; + User = ddclientUser; + Group = "nogroup"; #TODO get this to work + PermissionsStartOnly = "true"; + PIDFile = ddclientPIDFile; + ExecStartPre = '' + ${pkgs.stdenv.shell} -c "${pkgs.coreutils}/bin/mkdir -m 0755 -p ${stateDir} && ${pkgs.coreutils}/bin/chown ${ddclientUser} ${stateDir}" + ''; + ExecStart = "${ddclient}/bin/ddclient ${ddclientFlags}"; + #ExecStartPost = "${pkgs.coreutils}/bin/rm -r ${stateDir}"; # Should we have this? }; - - jobs.ddclient = - { name = "ddclient"; - - startOn = "startup"; - - preStart = - '' - mkdir -m 0755 -p ${stateDir} - chown ${ddclientUser} ${stateDir} - ''; - - exec = "${ddclient}/bin/ddclient ${ddclientFlags}"; - }; - + }; }; - }