1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 inherit (pkgs) ifplugd;
8
9 cfg = config.networking.interfaceMonitor;
10
11 # The ifplugd action script, which is called whenever the link
12 # status changes (i.e., a cable is plugged in or unplugged).
13 plugScript = pkgs.writeScript "ifplugd.action"
14 ''
15 #! ${pkgs.stdenv.shell}
16 iface="$1"
17 status="$2"
18 ${cfg.commands}
19 '';
20
21in
22
23{
24
25 ###### interface
26
27 options = {
28
29 networking.interfaceMonitor.enable = mkOption {
30 type = types.bool;
31 default = false;
32 description = ''
33 If <literal>true</literal>, monitor Ethernet interfaces for
34 cables being plugged in or unplugged. When this occurs, the
35 commands specified in
36 <option>networking.interfaceMonitor.commands</option> are
37 executed.
38 '';
39 };
40
41 networking.interfaceMonitor.beep = mkOption {
42 type = types.bool;
43 default = false;
44 description = ''
45 If <literal>true</literal>, beep when an Ethernet cable is
46 plugged in or unplugged.
47 '';
48 };
49
50 networking.interfaceMonitor.commands = mkOption {
51 type = types.lines;
52 default = "";
53 description = ''
54 Shell commands to be executed when the link status of an
55 interface changes. On invocation, the shell variable
56 <varname>iface</varname> contains the name of the interface,
57 while the variable <varname>status</varname> contains either
58 <literal>up</literal> or <literal>down</literal> to indicate
59 the new status.
60 '';
61 };
62
63 };
64
65
66 ###### implementation
67
68 config = mkIf cfg.enable {
69 systemd.services.ifplugd = {
70 description = "Network interface connectivity monitor";
71 after = [ "network-interfaces.target" ];
72 wantedBy = [ "multi-user.target" ];
73 script = ''
74 ${ifplugd}/sbin/ifplugd --no-daemon --no-startup --no-shutdown \
75 ${if config.networking.interfaceMonitor.beep then "" else "--no-beep"} \
76 --run ${plugScript}
77 '';
78 };
79
80 environment.systemPackages = [ ifplugd ];
81 };
82}