nixos/dnsmasq: Use attrs instead of plain text config

This should make it easier to configure in multiple places, override
defaults, etc.
This commit is contained in:
Robert Kovacsics 2022-10-14 19:08:38 +01:00
parent 9fad28e92d
commit 2c00429560
6 changed files with 86 additions and 22 deletions

View file

@ -128,6 +128,15 @@
sudo and sources the environment variables.
</para>
</listitem>
<listitem>
<para>
The <literal>dnsmasq</literal> service now takes configuration
via the <literal>services.dnsmasq.settings</literal> attribute
set. The option
<literal>services.dnsmasq.extraConfig</literal> will be
deprecated when NixOS 22.11 reaches end of life.
</para>
</listitem>
<listitem>
<para>
A new <literal>virtualisation.rosetta</literal> module was

View file

@ -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.

View file

@ -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";

View file

@ -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}" ];
};
};

View file

@ -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"
];
};

View file

@ -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 = ''