Skip to content

Commit

Permalink
nixos/duckdns: init module
Browse files Browse the repository at this point in the history
  • Loading branch information
notthebee committed Oct 26, 2024
1 parent 44475e4 commit dacff5c
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@
./services/misc/disnix.nix
./services/misc/docker-registry.nix
./services/misc/domoticz.nix
./services/misc/duckdns.nix
./services/misc/duckling.nix
./services/misc/dwm-status.nix
./services/misc/dysnomia.nix
Expand Down
98 changes: 98 additions & 0 deletions nixos/modules/services/misc/duckdns.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.duckdns;
in
{
options.services.duckdns = {
enable = lib.mkEnableOption "DuckDNS Dynamic DNS Client";
tokenFile = lib.mkOption {
default = null;
type = lib.types.path;
description = ''
The path to a file containing the token
used to authenticate with DuckDNS.
'';
};

domains = lib.mkOption {
default = null;
type = lib.types.nullOr (lib.types.listOf lib.types.str);
example = [ "examplehost" ];
description = ''
The domain(s) to update in DuckDNS
(without the .duckdns.org prefix)
'';
};

domainsFile = lib.mkOption {
default = null;
type = lib.types.nullOr lib.types.path;
example = lib.literalExpression ''
pkgs.writeText "duckdns-domains.txt" '''
examplehost
examplehost2
examplehost3
'''
'';
description = ''
The path to a file containing a
newline-separated list of DuckDNS
domain(s) to be updated
(without the .duckdns.org prefix)
'';
};

};

config = lib.mkIf cfg.enable {
assertions = [
{
assertion = cfg.domains != null || cfg.domainsFile != null;
message = "Either services.duckdns.domains or services.duckdns.domainsFile has to be defined";
}
{
assertion = lib.xor (cfg.domains != null) (cfg.domainsFile != null);
message = "Only one of services.duckdns.domains and services.duckdns.domainsFile can be defined at the same time";
}
{
assertion = (cfg.tokenFile != null);
message = "services.duckdns.tokenFile has to be defined";
}
];
systemd.services.duckdns = {
description = "DuckDNS Dynamic DNS Client";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
startAt = "*:0/5";
path = [
pkgs.gnused
pkgs.systemd
pkgs.curl
];
serviceConfig = {
Type = "simple";
LoadCredential = [
"DUCKDNS_TOKEN_FILE:${cfg.tokenFile}"
] ++ lib.optionals (cfg.domainsFile != null) [ "DUCKDNS_DOMAINS_FILE:${cfg.domainsFile}" ];
DynamicUser = true;
};
script = ''
export DUCKDNS_TOKEN=$(systemd-creds cat DUCKDNS_TOKEN_FILE)
${lib.optionalString (cfg.domains != null) ''
export DUCKDNS_DOMAINS='${lib.strings.concatStringsSep "," cfg.domains}'
''}
${lib.optionalString (cfg.domainsFile != null) ''
export DUCKDNS_DOMAINS=$(systemd-creds cat DUCKDNS_DOMAINS_FILE | sed -z 's/\n/,/g')
''}
curl --no-progress-meter -k -K- <<< "url = \"https://www.duckdns.org/update?domains=$DUCKDNS_DOMAINS&token=$DUCKDNS_TOKEN&ip=\"" | grep -v "KO"
'';
};
};

meta.maintainers = with lib.maintainers; [ notthebee ];
}

0 comments on commit dacff5c

Please sign in to comment.