nix-config/modules/iwd.nix

144 lines
4.2 KiB
Nix
Raw Normal View History

2023-12-27 00:44:45 +01:00
{
lib,
pkgs,
config,
...
2024-07-26 22:12:48 +02:00
}:
{
options.networking.wireless.iwd =
let
inherit (lib)
mkOption
literalExample
types
hasAttrByPath
;
in
{
networks = mkOption {
default = { };
example = literalExample ''
{ "karlsruhe.freifunk.net" = {};
};
'';
2023-12-27 00:44:45 +01:00
2024-07-26 22:12:48 +02:00
description = ''
Declarative configuration of wifi networks for
<citerefentry><refentrytitle>iwd</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
2023-12-27 00:44:45 +01:00
2024-07-26 22:12:48 +02:00
All networks will be stored in
<literal>/var/lib/iwd/&lt;name&gt;.&lt;type&gt;</literal>.
2023-12-27 00:44:45 +01:00
2024-07-26 22:12:48 +02:00
Since each network is stored in its own file, declarative networks can be used in an
environment with imperatively added networks via
<citerefentry><refentrytitle>iwctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
'';
2023-12-27 00:44:45 +01:00
2024-07-26 22:12:48 +02:00
type = types.attrsOf (
types.submodule (
{ config, ... }:
{
config.kind =
if
(hasAttrByPath [
"Security"
"Passphrase"
] config.settings)
then
"psk"
else if !(hasAttrByPath [ "Security" ] config.settings) then
"open"
else
"8021x";
2023-12-27 00:44:45 +01:00
2024-07-26 22:12:48 +02:00
options = {
kind = mkOption {
type = types.enum [
"open"
"psk"
"8021x"
];
description = "The type of network. This will determine the file ending. The module will try to determine this automatically so this should only be set when the heuristics fail.";
};
settings = mkOption {
type =
with types;
(attrsOf (
attrsOf (oneOf [
str
path
])
));
description = ''
Contents of the iwd config file for this network
The lowest level values should be files, that will be read into the config files
'';
default = { };
};
};
}
)
);
};
2023-12-27 00:44:45 +01:00
};
2024-07-26 22:12:48 +02:00
config =
let
inherit (lib)
mkIf
flip
mapAttrsToList
concatStringsSep
;
cfg = config.networking.wireless.iwd;
2023-12-27 00:44:45 +01:00
2024-07-26 22:12:48 +02:00
encoder = pkgs.writeScriptBin "encoder" ''
#! ${pkgs.runtimeShell} -e
2023-12-27 00:44:45 +01:00
2024-07-26 22:12:48 +02:00
# Extract file-ext from network names
ext="$(sed -re 's/.*\.(8021x|open|psk)$/\1/' <<< "$*")"
to_enc="$(sed -re "s/(.*)\.$ext/\1/g" <<< "$*")"
2023-12-27 00:44:45 +01:00
2024-07-26 22:12:48 +02:00
# Encode ssid (excluding file-extensio) as base64 if needed
[[ "$to_enc" =~ ^[[:alnum:]]+$ ]] && { echo "$to_enc.$ext"; exit 0; }
echo "=$(printf "$to_enc" | ${pkgs.unixtools.xxd}/bin/xxd -pu).$ext"
'';
in
2023-12-27 00:44:45 +01:00
mkIf cfg.enable {
2024-07-26 22:12:48 +02:00
systemd.services.iwd = mkIf (cfg.networks != { }) {
path = [ encoder ];
preStart =
let
dataDir = "/var/lib/iwd";
in
''
# Create config files for declaratively defined networks in the NixOS config.
${concatStringsSep "\n" (
flip mapAttrsToList cfg.networks (
network: config: ''
filename=${dataDir}/"$(encoder '${network}.${config.kind}')"
touch "$filename"
cat >$filename <<EOF
${concatStringsSep "\n" (
flip mapAttrsToList config.settings (
toplevel: config: ''
[${toplevel}]
${concatStringsSep "\n" (
flip mapAttrsToList config (
name: value: ''
${name}=$(<${value})
''
)
)}
''
)
)}
EOF
''
)
)}
'';
2023-12-27 00:44:45 +01:00
};
};
}