lol

nixos/dnsmasq: Use attrs instead of plain text config

This should make it easier to configure in multiple places, override
defaults, etc.

+86 -22
+9
nixos/doc/manual/from_md/release-notes/rl-2305.section.xml
··· 130 130 </listitem> 131 131 <listitem> 132 132 <para> 133 + The <literal>dnsmasq</literal> service now takes configuration 134 + via the <literal>services.dnsmasq.settings</literal> attribute 135 + set. The option 136 + <literal>services.dnsmasq.extraConfig</literal> will be 137 + deprecated when NixOS 22.11 reaches end of life. 138 + </para> 139 + </listitem> 140 + <listitem> 141 + <para> 133 142 A new <literal>virtualisation.rosetta</literal> module was 134 143 added to allow running <literal>x86_64</literal> binaries 135 144 through
+5
nixos/doc/manual/release-notes/rl-2305.section.md
··· 43 43 44 44 - `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. 45 45 46 + - The `dnsmasq` service now takes configuration via the 47 + `services.dnsmasq.settings` attribute set. The option 48 + `services.dnsmasq.extraConfig` will be deprecated when NixOS 22.11 reaches 49 + end of life. 50 + 46 51 - 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). 47 52 48 53 - Resilio sync secret keys can now be provided using a secrets file at runtime, preventing these secrets from ending up in the Nix store.
+69 -17
nixos/modules/services/networking/dnsmasq.nix
··· 7 7 dnsmasq = pkgs.dnsmasq; 8 8 stateDir = "/var/lib/dnsmasq"; 9 9 10 + # True values are just put as `name` instead of `name=true`, and false values 11 + # are turned to comments (false values are expected to be overrides e.g. 12 + # mkForce) 13 + formatKeyValue = 14 + name: value: 15 + if value == true 16 + then name 17 + else if value == false 18 + then "# setting `${name}` explicitly set to false" 19 + else generators.mkKeyValueDefault { } "=" name value; 20 + 21 + settingsFormat = pkgs.formats.keyValue { 22 + mkKeyValue = formatKeyValue; 23 + listsAsDuplicateKeys = true; 24 + }; 25 + 26 + # Because formats.generate is outputting a file, we use of conf-file. Once 27 + # `extraConfig` is deprecated we can just use 28 + # `dnsmasqConf = format.generate "dnsmasq.conf" cfg.settings` 10 29 dnsmasqConf = pkgs.writeText "dnsmasq.conf" '' 11 - dhcp-leasefile=${stateDir}/dnsmasq.leases 12 - ${optionalString cfg.resolveLocalQueries '' 13 - conf-file=/etc/dnsmasq-conf.conf 14 - resolv-file=/etc/dnsmasq-resolv.conf 15 - ''} 16 - ${flip concatMapStrings cfg.servers (server: '' 17 - server=${server} 18 - '')} 30 + conf-file=${settingsFormat.generate "dnsmasq.conf" cfg.settings} 19 31 ${cfg.extraConfig} 20 32 ''; 21 33 22 34 in 23 35 24 36 { 37 + 38 + imports = [ 39 + (mkRenamedOptionModule [ "services" "dnsmasq" "servers" ] [ "services" "dnsmasq" "settings" "server" ]) 40 + ]; 25 41 26 42 ###### interface 27 43 ··· 46 62 ''; 47 63 }; 48 64 49 - servers = mkOption { 50 - type = types.listOf types.str; 51 - default = []; 52 - example = [ "8.8.8.8" "8.8.4.4" ]; 53 - description = lib.mdDoc '' 54 - The DNS servers which dnsmasq should query. 55 - ''; 56 - }; 57 - 58 65 alwaysKeepRunning = mkOption { 59 66 type = types.bool; 60 67 default = false; ··· 63 70 ''; 64 71 }; 65 72 73 + settings = mkOption { 74 + type = types.submodule { 75 + 76 + freeformType = settingsFormat.type; 77 + 78 + options.server = mkOption { 79 + type = types.listOf types.str; 80 + default = [ ]; 81 + example = [ "8.8.8.8" "8.8.4.4" ]; 82 + description = lib.mdDoc '' 83 + The DNS servers which dnsmasq should query. 84 + ''; 85 + }; 86 + 87 + }; 88 + default = { }; 89 + description = lib.mdDoc '' 90 + Configuration of dnsmasq. Lists get added one value per line (empty 91 + lists and false values don't get added, though false values get 92 + turned to comments). Gets merged with 93 + 94 + { 95 + dhcp-leasefile = "${stateDir}/dnsmasq.leases"; 96 + conf-file = optional cfg.resolveLocalQueries "/etc/dnsmasq-conf.conf"; 97 + resolv-file = optional cfg.resolveLocalQueries "/etc/dnsmasq-resolv.conf"; 98 + } 99 + ''; 100 + example = literalExpression '' 101 + { 102 + domain-needed = true; 103 + dhcp-range = [ "192.168.0.2,192.168.0.254" ]; 104 + } 105 + ''; 106 + }; 107 + 66 108 extraConfig = mkOption { 67 109 type = types.lines; 68 110 default = ""; 69 111 description = lib.mdDoc '' 70 112 Extra configuration directives that should be added to 71 113 `dnsmasq.conf`. 114 + 115 + This option is deprecated, please use {option}`settings` instead. 72 116 ''; 73 117 }; 74 118 ··· 80 124 ###### implementation 81 125 82 126 config = mkIf cfg.enable { 127 + 128 + warnings = lib.optional (cfg.extraConfig != "") "Text based config is deprecated, dnsmasq now supports `services.dnsmasq.settings` for an attribute-set based config"; 129 + 130 + services.dnsmasq.settings = { 131 + dhcp-leasefile = mkDefault "${stateDir}/dnsmasq.leases"; 132 + conf-file = mkDefault (optional cfg.resolveLocalQueries "/etc/dnsmasq-conf.conf"); 133 + resolv-file = mkDefault (optional cfg.resolveLocalQueries "/etc/dnsmasq-resolv.conf"); 134 + }; 83 135 84 136 networking.nameservers = 85 137 optional cfg.resolveLocalQueries "127.0.0.1";
+1 -1
nixos/tests/dnscrypt-proxy2.nix
··· 26 26 }; 27 27 28 28 services.dnsmasq.enable = true; 29 - services.dnsmasq.servers = [ "127.0.0.1#${toString localProxyPort}" ]; 29 + services.dnsmasq.settings.server = [ "127.0.0.1#${toString localProxyPort}" ]; 30 30 }; 31 31 }; 32 32
+1 -1
nixos/tests/kubernetes/dns.nix
··· 69 69 extraConfiguration = { config, pkgs, lib, ... }: { 70 70 environment.systemPackages = [ pkgs.bind.host ]; 71 71 services.dnsmasq.enable = true; 72 - services.dnsmasq.servers = [ 72 + services.dnsmasq.settings.server = [ 73 73 "/cluster.local/${config.services.kubernetes.addons.dns.clusterIp}#53" 74 74 ]; 75 75 };
+1 -3
nixos/tests/schleuder.nix
··· 82 82 # Since we don't have internet here, use dnsmasq to provide MX records from /etc/hosts 83 83 services.dnsmasq = { 84 84 enable = true; 85 - extraConfig = '' 86 - selfmx 87 - ''; 85 + settings.selfmx = true; 88 86 }; 89 87 90 88 networking.extraHosts = ''