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
70 jobs.ifplugd =
71 { description = "Network interface connectivity monitor";
72
73 startOn = "started network-interfaces";
74 stopOn = "stopping network-interfaces";
75
76 exec =
77 ''
78 ${ifplugd}/sbin/ifplugd --no-daemon --no-startup --no-shutdown \
79 ${if config.networking.interfaceMonitor.beep then "" else "--no-beep"} \
80 --run ${plugScript}
81 '';
82 };
83
84 environment.systemPackages = [ ifplugd ];
85
86 };
87
88}