From 07ac997c9311dbf23b88ab74220fb04e873ef20b Mon Sep 17 00:00:00 2001 From: Mel Date: Thu, 20 Aug 2026 22:29:00 +0200 Subject: Package in Nix flake, package & module Signed-off-by: Mel --- flake.nix | 17 +++++++++++ module.nix | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ package.nix | 29 ++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 flake.nix create mode 100644 module.nix create mode 100644 package.nix diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..03c9d0d --- /dev/null +++ b/flake.nix @@ -0,0 +1,17 @@ +{ + description = "ddnnss - dynamic domain no-name system service"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; + + outputs = { self, nixpkgs }: + let + forAll = nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" ]; + in + { + nixosModules.default = import ./module.nix; + + packages = forAll (system: + let pkgs = import nixpkgs { inherit system; }; + in { default = pkgs.callPackage ./package.nix { }; }); + }; +} diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..b227085 --- /dev/null +++ b/module.nix @@ -0,0 +1,97 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (lib) + getExe + literalExpression + mkEnableOption + mkIf + mkOption + types + ; + + cfg = config.services.ddnnss; + + ddnnss = pkgs.callPackage ./package.nix { }; + + configFile = pkgs.writeText "ddnnss.json" (builtins.toJSON cfg.settings); +in +{ + options.services.ddnnss = { + enable = mkEnableOption "ddnnss"; + + interval = mkOption { + type = types.str; + default = "5min"; + description = '' + How often to run an update cycle. + ''; + }; + + settings = mkOption { + type = types.attrs; + description = '' + The ddnnss configuration. + Any key values expand environment variables. + ''; + example = literalExpression '' + { + records = [{ + zone = "rnrd.eu"; + name = "silly"; + type = "AAAA"; + provider = "bunny-rnrd"; + source = "icanhazip"; + }]; + providers.bunny-rnrd = { + kind = "bunny"; + keyFile = "$CREDENTIALS_DIRECTORY/bunny-dns"; + }; + sources.icanhazip = { kind = "icanhazip"; }; + } + ''; + }; + + credentials = mkOption { + type = types.attrsOf types.path; + default = { }; + description = '' + Secrets exposed to ddnnss during the cycle, as systemd credentials. + ''; + example = literalExpression '' + { bunny-dns = config.age.secrets.bunny-dns.path; } + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.services.ddnnss = { + description = "ddnnss dynamic dns update cycle"; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + + serviceConfig = { + Type = "oneshot"; + DynamicUser = true; + LoadCredential = lib.mapAttrsToList + (name: path: "${name}:${path}") cfg.credentials; + ExecStart = "${getExe ddnnss} -config ${configFile}"; + }; + }; + + systemd.timers.ddnnss = { + wantedBy = [ "timers.target" ]; + timerConfig = { + # wait 2 minutes from the start, with 30 second jitter. + OnBootSec = "2min"; + RandomizedDelaySec = "30s"; + OnUnitActiveSec = cfg.interval; + }; + }; + }; +} diff --git a/package.nix b/package.nix new file mode 100644 index 0000000..2ab0d95 --- /dev/null +++ b/package.nix @@ -0,0 +1,29 @@ +{ + lib, + buildGoModule, +}: + +buildGoModule { + pname = "ddnnss"; + version = "1.0"; + + src = lib.fileset.toSource { + root = ./.; + fileset = lib.fileset.unions [ + ./go.mod + ./main.go + ./config.go + ./source + ./provider + ]; + }; + + # stdlib only. + vendorHash = null; + + meta = { + description = "dynamic domain no-name system service"; + homepage = "https://git.rnrd.eu/ddnnss"; + mainProgram = "ddnnss"; + }; +} -- cgit v1.3.1