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}