From 2c0042956018b6b0dbe41195362afacf704b7214 Mon Sep 17 00:00:00 2001 From: Robert Kovacsics Date: Fri, 14 Oct 2022 19:08:38 +0100 Subject: [PATCH] nixos/dnsmasq: Use attrs instead of plain text config This should make it easier to configure in multiple places, override defaults, etc. --- .../from_md/release-notes/rl-2305.section.xml | 9 ++ .../manual/release-notes/rl-2305.section.md | 5 ++ nixos/modules/services/networking/dnsmasq.nix | 86 +++++++++++++++---- nixos/tests/dnscrypt-proxy2.nix | 2 +- nixos/tests/kubernetes/dns.nix | 2 +- nixos/tests/schleuder.nix | 4 +- 6 files changed, 86 insertions(+), 22 deletions(-) diff --git a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml index 0fd0382998c2..6605fd1bc982 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml @@ -128,6 +128,15 @@ sudo and sources the environment variables. + + + The dnsmasq service now takes configuration + via the services.dnsmasq.settings attribute + set. The option + services.dnsmasq.extraConfig will be + deprecated when NixOS 22.11 reaches end of life. + + A new virtualisation.rosetta module was diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index 39550d44733a..1ff28867b40e 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -43,6 +43,11 @@ In addition to numerous new and upgraded packages, this release has the followin - `services.mastodon` gained a tootctl wrapped named `mastodon-tootctl` similar to `nextcloud-occ` which can be executed from any user and switches to the configured mastodon user with sudo and sources the environment variables. +- The `dnsmasq` service now takes configuration via the + `services.dnsmasq.settings` attribute set. The option + `services.dnsmasq.extraConfig` will be deprecated when NixOS 22.11 reaches + end of life. + - A new `virtualisation.rosetta` module was added to allow running `x86_64` binaries through [Rosetta](https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment) inside virtualised NixOS guests on Apple silicon. This feature works by default with the [UTM](https://docs.getutm.app/) virtualisation [package](https://search.nixos.org/packages?channel=unstable&show=utm&from=0&size=1&sort=relevance&type=packages&query=utm). - Resilio sync secret keys can now be provided using a secrets file at runtime, preventing these secrets from ending up in the Nix store. diff --git a/nixos/modules/services/networking/dnsmasq.nix b/nixos/modules/services/networking/dnsmasq.nix index cfc37b74b9a9..4886654e8c03 100644 --- a/nixos/modules/services/networking/dnsmasq.nix +++ b/nixos/modules/services/networking/dnsmasq.nix @@ -7,15 +7,27 @@ let dnsmasq = pkgs.dnsmasq; stateDir = "/var/lib/dnsmasq"; + # True values are just put as `name` instead of `name=true`, and false values + # are turned to comments (false values are expected to be overrides e.g. + # mkForce) + formatKeyValue = + name: value: + if value == true + then name + else if value == false + then "# setting `${name}` explicitly set to false" + else generators.mkKeyValueDefault { } "=" name value; + + settingsFormat = pkgs.formats.keyValue { + mkKeyValue = formatKeyValue; + listsAsDuplicateKeys = true; + }; + + # Because formats.generate is outputting a file, we use of conf-file. Once + # `extraConfig` is deprecated we can just use + # `dnsmasqConf = format.generate "dnsmasq.conf" cfg.settings` dnsmasqConf = pkgs.writeText "dnsmasq.conf" '' - dhcp-leasefile=${stateDir}/dnsmasq.leases - ${optionalString cfg.resolveLocalQueries '' - conf-file=/etc/dnsmasq-conf.conf - resolv-file=/etc/dnsmasq-resolv.conf - ''} - ${flip concatMapStrings cfg.servers (server: '' - server=${server} - '')} + conf-file=${settingsFormat.generate "dnsmasq.conf" cfg.settings} ${cfg.extraConfig} ''; @@ -23,6 +35,10 @@ in { + imports = [ + (mkRenamedOptionModule [ "services" "dnsmasq" "servers" ] [ "services" "dnsmasq" "settings" "server" ]) + ]; + ###### interface options = { @@ -46,15 +62,6 @@ in ''; }; - servers = mkOption { - type = types.listOf types.str; - default = []; - example = [ "8.8.8.8" "8.8.4.4" ]; - description = lib.mdDoc '' - The DNS servers which dnsmasq should query. - ''; - }; - alwaysKeepRunning = mkOption { type = types.bool; default = false; @@ -63,12 +70,49 @@ in ''; }; + settings = mkOption { + type = types.submodule { + + freeformType = settingsFormat.type; + + options.server = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "8.8.8.8" "8.8.4.4" ]; + description = lib.mdDoc '' + The DNS servers which dnsmasq should query. + ''; + }; + + }; + default = { }; + description = lib.mdDoc '' + Configuration of dnsmasq. Lists get added one value per line (empty + lists and false values don't get added, though false values get + turned to comments). Gets merged with + + { + dhcp-leasefile = "${stateDir}/dnsmasq.leases"; + conf-file = optional cfg.resolveLocalQueries "/etc/dnsmasq-conf.conf"; + resolv-file = optional cfg.resolveLocalQueries "/etc/dnsmasq-resolv.conf"; + } + ''; + example = literalExpression '' + { + domain-needed = true; + dhcp-range = [ "192.168.0.2,192.168.0.254" ]; + } + ''; + }; + extraConfig = mkOption { type = types.lines; default = ""; description = lib.mdDoc '' Extra configuration directives that should be added to `dnsmasq.conf`. + + This option is deprecated, please use {option}`settings` instead. ''; }; @@ -81,6 +125,14 @@ in config = mkIf cfg.enable { + warnings = lib.optional (cfg.extraConfig != "") "Text based config is deprecated, dnsmasq now supports `services.dnsmasq.settings` for an attribute-set based config"; + + services.dnsmasq.settings = { + dhcp-leasefile = mkDefault "${stateDir}/dnsmasq.leases"; + conf-file = mkDefault (optional cfg.resolveLocalQueries "/etc/dnsmasq-conf.conf"); + resolv-file = mkDefault (optional cfg.resolveLocalQueries "/etc/dnsmasq-resolv.conf"); + }; + networking.nameservers = optional cfg.resolveLocalQueries "127.0.0.1"; diff --git a/nixos/tests/dnscrypt-proxy2.nix b/nixos/tests/dnscrypt-proxy2.nix index 4435d77bbf3b..a75a745d3553 100644 --- a/nixos/tests/dnscrypt-proxy2.nix +++ b/nixos/tests/dnscrypt-proxy2.nix @@ -26,7 +26,7 @@ in { }; services.dnsmasq.enable = true; - services.dnsmasq.servers = [ "127.0.0.1#${toString localProxyPort}" ]; + services.dnsmasq.settings.server = [ "127.0.0.1#${toString localProxyPort}" ]; }; }; diff --git a/nixos/tests/kubernetes/dns.nix b/nixos/tests/kubernetes/dns.nix index 6299b7ff988a..1b7145eb5d5e 100644 --- a/nixos/tests/kubernetes/dns.nix +++ b/nixos/tests/kubernetes/dns.nix @@ -69,7 +69,7 @@ let extraConfiguration = { config, pkgs, lib, ... }: { environment.systemPackages = [ pkgs.bind.host ]; services.dnsmasq.enable = true; - services.dnsmasq.servers = [ + services.dnsmasq.settings.server = [ "/cluster.local/${config.services.kubernetes.addons.dns.clusterIp}#53" ]; }; diff --git a/nixos/tests/schleuder.nix b/nixos/tests/schleuder.nix index a9e4cc325bc7..e57ef66bb8f9 100644 --- a/nixos/tests/schleuder.nix +++ b/nixos/tests/schleuder.nix @@ -82,9 +82,7 @@ import ./make-test-python.nix { # Since we don't have internet here, use dnsmasq to provide MX records from /etc/hosts services.dnsmasq = { enable = true; - extraConfig = '' - selfmx - ''; + settings.selfmx = true; }; networking.extraHosts = ''