@ -1,17 +1,33 @@
{ config , pkgs , lib , . . . }:
let
inherit ( lib ) mkOption mkIf singleton ;
inherit ( pkgs ) ddclient ;
stateDir = " / v a r / s p o o l / d d c l i e n t " ;
ddclientUser = " d d c l i e n t " ;
ddclientFlags = " - f o r e g r o u n d - f i l e ${ config . services . ddclient . configFile } " ;
ddclientPIDFile = " ${ stateDir } / d d c l i e n t . p i d " ;
cfg = config . services . ddclient ;
boolToStr = bool : if bool then " y e s " else " n o " ;
configText = ''
# This file can be used as a template for configFile or is automatically generated by Nix options.
daemon = $ { toString cfg . interval }
cache = $ { cfg . homeDir } /ddclient.cache
pid = /run/ddclient/ddclient.pid
foreground = NO
use = $ { cfg . use }
login = $ { cfg . username }
password = $ { cfg . password }
protocol = $ { cfg . protocol }
$ { let server = cfg . server ; in
lib . optionalString ( server != " " ) " s e r v e r = ${ server } " }
ssl = $ { boolToStr cfg . ssl }
wildcard = YES
quiet = $ { boolToStr cfg . quiet }
verbose = $ { boolToStr cfg . verbose }
$ { cfg . domain }
$ { cfg . extraConfig }
'' ;
in
with lib ;
{
###### interface
@ -28,6 +44,12 @@ in
'' ;
} ;
homeDir = mkOption {
default = " / v a r / l i b / d d c l i e n t " ;
type = str ;
description = " H o m e d i r e c t o r y f o r t h e d a e m o n u s e r . " ;
} ;
domain = mkOption {
default = " " ;
type = str ;
@ -52,6 +74,12 @@ in
'' ;
} ;
interval = mkOption {
default = 600 ;
type = int ;
description = " T h e i n t e r v a l a t w h i c h t o r u n t h e c h e c k a n d u p d a t e . " ;
} ;
configFile = mkOption {
default = " / e t c / d d c l i e n t . c o n f " ;
type = path ;
@ -126,37 +154,24 @@ in
config = mkIf config . services . ddclient . enable {
environment . systemPackages = [ ddclient ] ;
users = {
extraGroups . ddclient . gid = config . ids . gids . ddclient ;
users . extraUsers = singleton {
name = ddclientUser ;
uid = config . ids . uids . ddclient ;
description = " d d c l i e n t d a e m o n u s e r " ;
home = stateDir ;
extraUsers . ddclient = {
uid = config . ids . uids . ddclient ;
description = " d d c l i e n t d a e m o n u s e r " ;
group = " d d c l i e n t " ;
home = cfg . homeDir ;
createHome = true ;
} ;
} ;
environment . etc . " d d c l i e n t . c o n f " = {
enable = con fi g . services . ddclient . configFile == " / e t c / d d c l i e n t . c o n f " ;
enable = cfg . configFile == " / e t c / d d c l i e n t . c o n f " ;
uid = config . ids . uids . ddclient ;
gid = config . ids . gids . ddclient ;
mode = " 0 6 0 0 " ;
text = ''
# This file can be used as a template for configFile or is automatically generated by Nix options.
daemon = 600
cache = $ { stateDir } /ddclient.cache
pid = $ { ddclientPIDFile }
use = $ { config . services . ddclient . use }
login = $ { config . services . ddclient . username }
password = $ { config . services . ddclient . password }
protocol = $ { config . services . ddclient . protocol }
$ { let server = config . services . ddclient . server ; in
lib . optionalString ( server != " " ) " s e r v e r = ${ server } " }
ssl = $ { if config . services . ddclient . ssl then " y e s " else " n o " }
wildcard = YES
quiet = $ { if config . services . ddclient . quiet then " y e s " else " n o " }
verbose = $ { if config . services . ddclient . verbose then " y e s " else " n o " }
$ { config . services . ddclient . domain }
$ { config . services . ddclient . extraConfig }
'' ;
text = configText ;
} ;
systemd . services . ddclient = {
@ -166,17 +181,14 @@ in
restartTriggers = [ config . environment . etc . " d d c l i e n t . c o n f " . source ] ;
serviceConfig = {
# Uncomment this if too many problems occur:
# Type = "forking";
User = ddclientUser ;
Group = " n o g r o u p " ; #TODO get this to work
PermissionsStartOnly = " t r u e " ;
PIDFile = ddclientPIDFile ;
ExecStartPre = ''
$ { pkgs . stdenv . shell } - c " ${ pkgs . coreutils } / b i n / m k d i r - m 0 7 5 5 - p ${ stateDir } & & ${ pkgs . coreutils } / b i n / c h o w n ${ ddclientUser } ${ stateDir } "
'' ;
ExecStart = " ${ ddclient } / b i n / d d c l i e n t ${ ddclientFlags } " ;
#ExecStartPost = "${pkgs.coreutils}/bin/rm -r ${stateDir}"; # Should we have this?
RuntimeDirectory = " d d c l i e n t " ;
# we cannot run in forking mode as it swallows all the program output
Type = " s i m p l e " ;
User = " d d c l i e n t " ;
Group = " d d c l i e n t " ;
ExecStart = " ${ lib . getBin pkgs . ddclient } / b i n / d d c l i e n t - f o r e g r o u n d - f i l e ${ cfg . configFile } " ;
ProtectSystem = " f u l l " ;
PrivateTmp = true ;
} ;
} ;
} ;