From fbb2c04132d7226304895a3b656eb049c2fd53b6 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Fri, 4 Aug 2023 20:39:29 +0100 Subject: [PATCH] move module-based-service parameter types into service This is in preparation for writing something that extracts them into documentation. user configurations now call config.system.service.foo.build { ...params } instead of config.system.service.foo the parameter type definitions themselves now move into the config stanza of the module referencing the service new helper function liminix.callService The only service moved so far is dnsmasq --- examples/rotuer.nix | 2 +- modules/dnsmasq/default.nix | 36 +++++++++++++++++++++++++-- modules/dnsmasq/service.nix | 47 ++++++++--------------------------- pkgs/default.nix | 40 +++++++++++++++++++---------- tests/pppoe/configuration.nix | 2 +- 5 files changed, 73 insertions(+), 54 deletions(-) diff --git a/examples/rotuer.nix b/examples/rotuer.nix index 9f757c33d..10b549ba2 100644 --- a/examples/rotuer.nix +++ b/examples/rotuer.nix @@ -119,7 +119,7 @@ in rec { services.dns = let interface = services.int; - in svc.dnsmasq { + in svc.dnsmasq.build { resolvconf = services.resolvconf; inherit interface; ranges = [ diff --git a/modules/dnsmasq/default.nix b/modules/dnsmasq/default.nix index a87ecfe86..9ce750497 100644 --- a/modules/dnsmasq/default.nix +++ b/modules/dnsmasq/default.nix @@ -1,14 +1,46 @@ { lib, pkgs, config, ...}: let inherit (lib) mkOption types; + inherit (pkgs) liminix; in { options = { system.service.dnsmasq = mkOption { - type = types.functionTo types.package; + type = liminix.lib.types.serviceDefn; }; }; config = { - system.service.dnsmasq = pkgs.callPackage ./service.nix {}; + system.service.dnsmasq = liminix.callService ./service.nix { + user = mkOption { + type = types.str; + default = "dnsmasq"; + }; + group = mkOption { + type = types.str; + default = "dnsmasq"; + }; + resolvconf = mkOption { + type = types.nullOr liminix.lib.types.service; + default = null; + }; + interface = mkOption { + type = liminix.lib.types.service; + default = null; + }; + upstreams = mkOption { + type = types.listOf types.str; + default = []; + }; + ranges = mkOption { + type = types.listOf types.str; + }; + domain = mkOption { + # this can be given multiple times so probably should be + # domains plural and list of string + description = "Domain name for DHCP service: causes the DHCP server to return the domain to any hosts which request it, and sets the domain which it is legal for DHCP-configured hosts to claim"; + type = types.str; + example = "example.com"; + }; + }; users.dnsmasq = { uid = 51; gid= 51; gecos = "DNS/DHCP service user"; dir = "/run/dnsmasq"; diff --git a/modules/dnsmasq/service.nix b/modules/dnsmasq/service.nix index 226d95c16..c446de2bf 100644 --- a/modules/dnsmasq/service.nix +++ b/modules/dnsmasq/service.nix @@ -4,46 +4,19 @@ , serviceFns , lib }: +{ + interface +, user +, domain +, group +, ranges +, upstreams +, resolvconf +}: let + name = "${interface.device}.dnsmasq"; inherit (liminix.services) longrun; inherit (lib) concatStringsSep; - inherit (liminix.lib) typeChecked; - inherit (lib) mkOption types; - - t = { - user = mkOption { - type = types.str; - default = "dnsmasq"; - }; - group = mkOption { - type = types.str; - default = "dnsmasq"; - }; - resolvconf = mkOption { - type = types.nullOr liminix.lib.types.service; - default = null; - }; - interface = mkOption { - type = liminix.lib.types.service; - default = null; - }; - upstreams = mkOption { - type = types.listOf types.str; - default = []; - }; - ranges = mkOption { - type = types.listOf types.str; - }; - domain = mkOption { - type = types.str; - }; - }; -in -params: -let - inherit (typeChecked "dnsmasq" t params) - interface user domain group ranges upstreams resolvconf; - name = "${interface.device}.dnsmasq"; in longrun { inherit name; diff --git a/pkgs/default.nix b/pkgs/default.nix index 0d03d0d23..c841d0c1e 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -2,7 +2,14 @@ callPackage , lib }: -{ +let + typeChecked = caller: type: value: + let + inherit (lib) types mergeDefinitions; + defs = [{ file = caller; inherit value; }]; + type' = types.submodule { options = type; }; + in (mergeDefinitions [] type' defs).mergedValue; +in { pseudofile = callPackage ./pseudofile {}; liminix = { services = callPackage ./liminix-tools/services {}; @@ -11,22 +18,29 @@ squashfs = callPackage ./liminix-tools/builders/squashfs.nix {}; kernel = callPackage ./kernel {}; }; + callService = path : parameters : + let pkg = callPackage path {}; + checkTypes = t : p : typeChecked (builtins.tostring path) t p; + in { + inherit parameters; + build = args : pkg (checkTypes parameters args); + }; lib = { - types = { - service = - let inherit (lib) types isDerivation hasAttr; - in types.package // { + types = + let inherit (lib) types isDerivation; + in { + service = types.package // { name = "service"; description = "s6-rc service"; - check = x: isDerivation x && hasAttr "serviceType" x; + check = x: isDerivation x && x ? serviceType; }; - }; - typeChecked = caller: type: value: - let - inherit (lib) types mergeDefinitions; - defs = [{ file = caller; inherit value; }]; - type' = types.submodule { options = type; }; - in (mergeDefinitions [] type' defs).mergedValue; + serviceDefn = types.attrs // { + name = "service-defn"; + description = "parametrisable s6-rc service definition"; + check = x: lib.isAttrs x && x ? parameters && x ? build; + }; + }; + inherit typeChecked; }; }; writeFennelScript = callPackage ./write-fennel-script {}; diff --git a/tests/pppoe/configuration.nix b/tests/pppoe/configuration.nix index af47d4098..0f485691e 100644 --- a/tests/pppoe/configuration.nix +++ b/tests/pppoe/configuration.nix @@ -41,7 +41,7 @@ in rec { }; services.dns = - config.system.service.dnsmasq { + config.system.service.dnsmasq.build { interface = services.lan4; ranges = ["192.168.19.10,192.168.19.253"]; domain = "fake.liminix.org";