mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-12 20:55:31 +03:00
nixos/networkmanager: split modemmanager into a separate module (#316824)
This commit is contained in:
commit
a01b0bf2fe
4 changed files with 322 additions and 189 deletions
|
@ -30,6 +30,8 @@
|
|||
|
||||
- [MaryTTS](https://github.com/marytts/marytts), an open-source, multilingual text-to-speech synthesis system written in pure Java. Available as [services.marytts](options.html#opt-services.marytts).
|
||||
|
||||
- [networking.modemmanager](options.html#opt-networking.modemmanager) has been split out of [networking.networkmanager](options.html#opt-networking.networkmanager). NetworkManager still enables ModemManager by default, but options exist now to run NetworkManager without ModemManager.
|
||||
|
||||
- [Conduwuit](https://conduwuit.puppyirl.gay/), a federated chat server implementing the Matrix protocol, forked from Conduit. Available as [services.conduwuit](#opt-services.conduwuit.enable).
|
||||
|
||||
- [Traccar](https://www.traccar.org/), a modern GPS Tracking Platform. Available as [services.traccar](#opt-services.traccar.enable).
|
||||
|
|
|
@ -1137,6 +1137,7 @@
|
|||
./services/networking/miredo.nix
|
||||
./services/networking/mjpg-streamer.nix
|
||||
./services/networking/mmsd.nix
|
||||
./services/networking/modemmanager.nix
|
||||
./services/networking/monero.nix
|
||||
./services/networking/morty.nix
|
||||
./services/networking/mosquitto.nix
|
||||
|
|
97
nixos/modules/services/networking/modemmanager.nix
Normal file
97
nixos/modules/services/networking/modemmanager.nix
Normal file
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.networking.modemmanager;
|
||||
in
|
||||
{
|
||||
meta = {
|
||||
maintainers = lib.teams.freedesktop.members;
|
||||
};
|
||||
|
||||
options = with lib; {
|
||||
networking.modemmanager = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to use ModemManager to manage modem devices.
|
||||
This is usually used by some higher layer manager such as NetworkManager
|
||||
but can be used standalone especially if using a modem for non-IP
|
||||
connectivity (e.g. GPS).
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "modemmanager" { };
|
||||
|
||||
fccUnlockScripts = mkOption {
|
||||
type = types.listOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
description = "vid:pid of either the PCI or USB vendor and product ID";
|
||||
};
|
||||
path = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to the unlock script";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
default = [ ];
|
||||
example = literalExpression ''[{ id = "03f0:4e1d"; path = "''${pkgs.modemmanager}/share/ModemManager/fcc-unlock.available.d/03f0:4e1d"; }]'';
|
||||
description = ''
|
||||
List of FCC unlock scripts to enable on the system, behaving as described in
|
||||
https://modemmanager.org/docs/modemmanager/fcc-unlock/#integration-with-third-party-fcc-unlock-tools.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.etc = builtins.listToAttrs (
|
||||
map (
|
||||
e:
|
||||
lib.nameValuePair "ModemManager/fcc-unlock.d/${e.id}" {
|
||||
source = e.path;
|
||||
}
|
||||
) cfg.fccUnlockScripts
|
||||
);
|
||||
|
||||
systemd.services.ModemManager = {
|
||||
aliases = [ "dbus-org.freedesktop.ModemManager1.service" ];
|
||||
path = lib.optionals (cfg.fccUnlockScripts != [ ]) [
|
||||
pkgs.libqmi
|
||||
pkgs.libmbim
|
||||
];
|
||||
};
|
||||
|
||||
/*
|
||||
[modem-manager]
|
||||
Identity=unix-group:networkmanager
|
||||
Action=org.freedesktop.ModemManager*
|
||||
ResultAny=yes
|
||||
ResultInactive=no
|
||||
ResultActive=yes
|
||||
*/
|
||||
security.polkit.enable = true;
|
||||
security.polkit.extraConfig = ''
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (
|
||||
subject.isInGroup("networkmanager")
|
||||
&& action.id.indexOf("org.freedesktop.ModemManager") == 0
|
||||
)
|
||||
{ return polkit.Result.YES; }
|
||||
});
|
||||
'';
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
systemd.packages = [ cfg.package ];
|
||||
services.dbus.packages = [ cfg.package ];
|
||||
services.udev.packages = [ cfg.package ];
|
||||
};
|
||||
}
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
|
||||
|
@ -15,14 +20,10 @@ let
|
|||
plugins = "keyfile";
|
||||
inherit (cfg) dhcp dns;
|
||||
# If resolvconf is disabled that means that resolv.conf is managed by some other module.
|
||||
rc-manager =
|
||||
if config.networking.resolvconf.enable then "resolvconf"
|
||||
else "unmanaged";
|
||||
rc-manager = if config.networking.resolvconf.enable then "resolvconf" else "unmanaged";
|
||||
};
|
||||
keyfile = {
|
||||
unmanaged-devices =
|
||||
if cfg.unmanaged == [ ] then null
|
||||
else lib.concatStringsSep ";" cfg.unmanaged;
|
||||
unmanaged-devices = if cfg.unmanaged == [ ] then null else lib.concatStringsSep ";" cfg.unmanaged;
|
||||
};
|
||||
logging = {
|
||||
audit = config.security.audit.enable;
|
||||
|
@ -43,32 +44,29 @@ let
|
|||
ResultAny=yes
|
||||
ResultInactive=no
|
||||
ResultActive=yes
|
||||
|
||||
[modem-manager]
|
||||
Identity=unix-group:networkmanager
|
||||
Action=org.freedesktop.ModemManager*
|
||||
ResultAny=yes
|
||||
ResultInactive=no
|
||||
ResultActive=yes
|
||||
*/
|
||||
polkitConf = ''
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (
|
||||
subject.isInGroup("networkmanager")
|
||||
&& (action.id.indexOf("org.freedesktop.NetworkManager.") == 0
|
||||
|| action.id.indexOf("org.freedesktop.ModemManager") == 0
|
||||
))
|
||||
&& action.id.indexOf("org.freedesktop.NetworkManager.") == 0
|
||||
)
|
||||
{ return polkit.Result.YES; }
|
||||
});
|
||||
'';
|
||||
|
||||
ns = xs: pkgs.writeText "nameservers" (
|
||||
concatStrings (map (s: "nameserver ${s}\n") xs)
|
||||
);
|
||||
ns = xs: pkgs.writeText "nameservers" (concatStrings (map (s: "nameserver ${s}\n") xs));
|
||||
|
||||
overrideNameserversScript = pkgs.writeScript "02overridedns" ''
|
||||
#!/bin/sh
|
||||
PATH=${with pkgs; makeBinPath [ gnused gnugrep coreutils ]}
|
||||
PATH=${
|
||||
with pkgs;
|
||||
makeBinPath [
|
||||
gnused
|
||||
gnugrep
|
||||
coreutils
|
||||
]
|
||||
}
|
||||
tmp=$(mktemp)
|
||||
sed '/nameserver /d' /etc/resolv.conf > $tmp
|
||||
grep 'nameserver ' /etc/resolv.conf | \
|
||||
|
@ -84,7 +82,15 @@ let
|
|||
};
|
||||
|
||||
macAddressOptWifi = mkOption {
|
||||
type = types.either types.str (types.enum [ "permanent" "preserve" "random" "stable" "stable-ssid" ]);
|
||||
type = types.either types.str (
|
||||
types.enum [
|
||||
"permanent"
|
||||
"preserve"
|
||||
"random"
|
||||
"stable"
|
||||
"stable-ssid"
|
||||
]
|
||||
);
|
||||
default = "preserve";
|
||||
example = "00:11:22:33:44:55";
|
||||
description = ''
|
||||
|
@ -100,7 +106,14 @@ let
|
|||
};
|
||||
|
||||
macAddressOptEth = mkOption {
|
||||
type = types.either types.str (types.enum [ "permanent" "preserve" "random" "stable" ]);
|
||||
type = types.either types.str (
|
||||
types.enum [
|
||||
"permanent"
|
||||
"preserve"
|
||||
"random"
|
||||
"stable"
|
||||
]
|
||||
);
|
||||
default = "preserve";
|
||||
example = "00:11:22:33:44:55";
|
||||
description = ''
|
||||
|
@ -114,9 +127,9 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
packages = [
|
||||
pkgs.modemmanager
|
||||
pkgs.networkmanager
|
||||
packages =
|
||||
[
|
||||
cfg.package
|
||||
]
|
||||
++ cfg.plugins
|
||||
++ lib.optionals (!delegateWireless && !enableIwd) [
|
||||
|
@ -148,12 +161,18 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "networkmanager" { };
|
||||
|
||||
connectionConfig = mkOption {
|
||||
type = with types; attrsOf (nullOr (oneOf [
|
||||
type =
|
||||
with types;
|
||||
attrsOf (
|
||||
nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
]));
|
||||
])
|
||||
);
|
||||
default = { };
|
||||
description = ''
|
||||
Configuration for the [connection] section of NetworkManager.conf.
|
||||
|
@ -205,9 +224,7 @@ in
|
|||
check =
|
||||
p:
|
||||
lib.assertMsg
|
||||
(types.package.check p
|
||||
&& p ? networkManagerPlugin
|
||||
&& lib.isString p.networkManagerPlugin)
|
||||
(types.package.check p && p ? networkManagerPlugin && lib.isString p.networkManagerPlugin)
|
||||
''
|
||||
Package ‘${p.name}’, is not a NetworkManager plug-in.
|
||||
Those need to have a ‘networkManagerPlugin’ attribute.
|
||||
|
@ -223,7 +240,10 @@ in
|
|||
};
|
||||
|
||||
dhcp = mkOption {
|
||||
type = types.enum [ "dhcpcd" "internal" ];
|
||||
type = types.enum [
|
||||
"dhcpcd"
|
||||
"internal"
|
||||
];
|
||||
default = "internal";
|
||||
description = ''
|
||||
Which program (or internal library) should be used for DHCP.
|
||||
|
@ -231,7 +251,14 @@ in
|
|||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum [ "OFF" "ERR" "WARN" "INFO" "DEBUG" "TRACE" ];
|
||||
type = types.enum [
|
||||
"OFF"
|
||||
"ERR"
|
||||
"WARN"
|
||||
"INFO"
|
||||
"DEBUG"
|
||||
"TRACE"
|
||||
];
|
||||
default = "WARN";
|
||||
description = ''
|
||||
Set the default logging verbosity level.
|
||||
|
@ -262,7 +289,10 @@ in
|
|||
macAddress = macAddressOptWifi;
|
||||
|
||||
backend = mkOption {
|
||||
type = types.enum [ "wpa_supplicant" "iwd" ];
|
||||
type = types.enum [
|
||||
"wpa_supplicant"
|
||||
"iwd"
|
||||
];
|
||||
default = "wpa_supplicant";
|
||||
description = ''
|
||||
Specify the Wi-Fi backend used for the device.
|
||||
|
@ -289,7 +319,12 @@ in
|
|||
};
|
||||
|
||||
dns = mkOption {
|
||||
type = types.enum [ "default" "dnsmasq" "systemd-resolved" "none" ];
|
||||
type = types.enum [
|
||||
"default"
|
||||
"dnsmasq"
|
||||
"systemd-resolved"
|
||||
"none"
|
||||
];
|
||||
default = "default";
|
||||
description = ''
|
||||
Set the DNS (`resolv.conf`) processing mode.
|
||||
|
@ -304,7 +339,8 @@ in
|
|||
};
|
||||
|
||||
dispatcherScripts = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
type = types.listOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
|
@ -324,7 +360,8 @@ in
|
|||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
default = [ ];
|
||||
example = literalExpression ''
|
||||
[ {
|
||||
|
@ -358,28 +395,10 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
fccUnlockScripts = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
description = "vid:pid of either the PCI or USB vendor and product ID";
|
||||
};
|
||||
path = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to the unlock script";
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [ ];
|
||||
example = literalExpression ''[{ id = "03f0:4e1d"; path = "''${pkgs.modemmanager}/share/ModemManager/fcc-unlock.available.d/03f0:4e1d"; }]'';
|
||||
description = ''
|
||||
List of FCC unlock scripts to enable on the system, behaving as described in
|
||||
https://modemmanager.org/docs/modemmanager/fcc-unlock/#integration-with-third-party-fcc-unlock-tools.
|
||||
'';
|
||||
};
|
||||
ensureProfiles = {
|
||||
profiles = with lib.types; mkOption {
|
||||
profiles =
|
||||
with lib.types;
|
||||
mkOption {
|
||||
type = attrsOf (submodule {
|
||||
freeformType = ini.type;
|
||||
|
||||
|
@ -473,14 +492,13 @@ in
|
|||
+ settings.main.no-auto-default = "*";
|
||||
};
|
||||
```
|
||||
''
|
||||
)
|
||||
'')
|
||||
(mkRemovedOptionModule [ "networking" "networkmanager" "enableFccUnlock" ] ''
|
||||
This option was removed, because using bundled FCC unlock scripts is risky,
|
||||
might conflict with vendor-provided unlock scripts, and should
|
||||
be a conscious decision on a per-device basis.
|
||||
Instead it's recommended to use the
|
||||
`networking.networkmanager.fccUnlockScripts` option.
|
||||
`networking.modemmanager.fccUnlockScripts` option.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "networking" "networkmanager" "dynamicHosts" ] ''
|
||||
This option was removed because allowing (multiple) regular users to
|
||||
|
@ -493,9 +511,12 @@ in
|
|||
(mkRemovedOptionModule [ "networking" "networkmanager" "firewallBackend" ] ''
|
||||
This option was removed as NixOS is now using iptables-nftables-compat even when using iptables, therefore Networkmanager now uses the nftables backend unconditionally.
|
||||
'')
|
||||
(mkRenamedOptionModule
|
||||
[ "networking" "networkmanager" "fccUnlockScripts" ]
|
||||
[ "networking" "modemmanager" "fccUnlockScripts" ]
|
||||
)
|
||||
];
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
@ -512,7 +533,8 @@ in
|
|||
|
||||
hardware.wirelessRegulatoryDatabase = true;
|
||||
|
||||
environment.etc = {
|
||||
environment.etc =
|
||||
{
|
||||
"NetworkManager/NetworkManager.conf".source = configFile;
|
||||
|
||||
# The networkmanager-l2tp plugin expects /etc/ipsec.secrets to include /etc/ipsec.d/ipsec.nm-l2tp.secrets;
|
||||
|
@ -521,27 +543,28 @@ in
|
|||
include ipsec.d/ipsec.nm-l2tp.secrets
|
||||
'';
|
||||
}
|
||||
// builtins.listToAttrs (map
|
||||
(pkg: nameValuePair "NetworkManager/${pkg.networkManagerPlugin}" {
|
||||
// builtins.listToAttrs (
|
||||
map (
|
||||
pkg:
|
||||
nameValuePair "NetworkManager/${pkg.networkManagerPlugin}" {
|
||||
source = "${pkg}/lib/NetworkManager/${pkg.networkManagerPlugin}";
|
||||
})
|
||||
cfg.plugins)
|
||||
// builtins.listToAttrs (map
|
||||
(e: nameValuePair "ModemManager/fcc-unlock.d/${e.id}" {
|
||||
source = e.path;
|
||||
})
|
||||
cfg.fccUnlockScripts)
|
||||
// optionalAttrs (cfg.appendNameservers != [ ] || cfg.insertNameservers != [ ])
|
||||
{
|
||||
}
|
||||
) cfg.plugins
|
||||
)
|
||||
// optionalAttrs (cfg.appendNameservers != [ ] || cfg.insertNameservers != [ ]) {
|
||||
"NetworkManager/dispatcher.d/02overridedns".source = overrideNameserversScript;
|
||||
}
|
||||
// listToAttrs (lib.imap1
|
||||
(i: s:
|
||||
{
|
||||
name = "NetworkManager/dispatcher.d/${dispatcherTypesSubdirMap.${s.type}}03userscript${lib.fixedWidthNumber 4 i}";
|
||||
value = { mode = "0544"; inherit (s) source; };
|
||||
})
|
||||
cfg.dispatcherScripts);
|
||||
// listToAttrs (
|
||||
lib.imap1 (i: s: {
|
||||
name = "NetworkManager/dispatcher.d/${
|
||||
dispatcherTypesSubdirMap.${s.type}
|
||||
}03userscript${lib.fixedWidthNumber 4 i}";
|
||||
value = {
|
||||
mode = "0544";
|
||||
inherit (s) source;
|
||||
};
|
||||
}) cfg.dispatcherScripts
|
||||
);
|
||||
|
||||
environment.systemPackages = packages;
|
||||
|
||||
|
@ -590,17 +613,19 @@ in
|
|||
wantedBy = [ "network-online.target" ];
|
||||
};
|
||||
|
||||
systemd.services.ModemManager = {
|
||||
aliases = [ "dbus-org.freedesktop.ModemManager1.service" ];
|
||||
path = lib.optionals (cfg.fccUnlockScripts != []) [ pkgs.libqmi pkgs.libmbim ];
|
||||
};
|
||||
|
||||
systemd.services.NetworkManager-dispatcher = {
|
||||
wantedBy = [ "network.target" ];
|
||||
restartTriggers = [ configFile overrideNameserversScript ];
|
||||
restartTriggers = [
|
||||
configFile
|
||||
overrideNameserversScript
|
||||
];
|
||||
|
||||
# useful binaries for user-specified hooks
|
||||
path = [ pkgs.iproute2 pkgs.util-linux pkgs.coreutils ];
|
||||
path = [
|
||||
pkgs.iproute2
|
||||
pkgs.util-linux
|
||||
pkgs.coreutils
|
||||
];
|
||||
aliases = [ "dbus-org.freedesktop.nm-dispatcher.service" ];
|
||||
};
|
||||
|
||||
|
@ -609,16 +634,18 @@ in
|
|||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "network-online.target" ];
|
||||
after = [ "NetworkManager.service" ];
|
||||
script = let
|
||||
script =
|
||||
let
|
||||
path = id: "/run/NetworkManager/system-connections/${id}.nmconnection";
|
||||
in ''
|
||||
in
|
||||
''
|
||||
mkdir -p /run/NetworkManager/system-connections
|
||||
'' + lib.concatMapStringsSep "\n"
|
||||
(profile: ''
|
||||
''
|
||||
+ lib.concatMapStringsSep "\n" (profile: ''
|
||||
${pkgs.envsubst}/bin/envsubst -i ${ini.generate (lib.escapeShellArg profile.n) profile.v} > ${path (lib.escapeShellArg profile.n)}
|
||||
'') (lib.mapAttrsToList (n: v: { inherit n v; }) cfg.ensureProfiles.profiles)
|
||||
+ ''
|
||||
${pkgs.networkmanager}/bin/nmcli connection reload
|
||||
${cfg.package}/bin/nmcli connection reload
|
||||
'';
|
||||
serviceConfig = {
|
||||
EnvironmentFile = cfg.ensureProfiles.environmentFiles;
|
||||
|
@ -654,13 +681,18 @@ in
|
|||
})
|
||||
|
||||
{
|
||||
modemmanager.enable = lib.mkDefault true;
|
||||
|
||||
networkmanager.connectionConfig = {
|
||||
"ethernet.cloned-mac-address" = cfg.ethernet.macAddress;
|
||||
"wifi.cloned-mac-address" = cfg.wifi.macAddress;
|
||||
"wifi.powersave" =
|
||||
if cfg.wifi.powersave == null then null
|
||||
else if cfg.wifi.powersave then 3
|
||||
else 2;
|
||||
if cfg.wifi.powersave == null then
|
||||
null
|
||||
else if cfg.wifi.powersave then
|
||||
3
|
||||
else
|
||||
2;
|
||||
};
|
||||
}
|
||||
];
|
||||
|
@ -670,7 +702,8 @@ in
|
|||
security.polkit.enable = true;
|
||||
security.polkit.extraConfig = polkitConf;
|
||||
|
||||
services.dbus.packages = packages
|
||||
services.dbus.packages =
|
||||
packages
|
||||
++ optional cfg.enableStrongSwan pkgs.strongswanNM
|
||||
++ optional (cfg.dns == "dnsmasq") pkgs.dnsmasq;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue