| 
									
										
										
										
											2014-04-14 16:26:48 +02:00
										 |  |  | { config, lib, pkgs, ... }: | 
					
						
							| 
									
										
										
										
											2011-07-13 17:47:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 16:26:48 +02:00
										 |  |  | with lib; | 
					
						
							| 
									
										
										
										
											2011-07-13 17:47:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |   host = config.networking.hostName or "unknown" | 
					
						
							|  |  |  |        + optionalString (config.networking.domain != null) ".${config.networking.domain}"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-13 17:47:34 +00:00
										 |  |  |   cfg = config.services.smartd; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |   nm = cfg.notifications.mail; | 
					
						
							|  |  |  |   nw = cfg.notifications.wall; | 
					
						
							|  |  |  |   nx = cfg.notifications.x11; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   smartdNotify = pkgs.writeScript "smartd-notify.sh" ''
 | 
					
						
							| 
									
										
										
										
											2018-03-01 14:38:53 -05:00
										 |  |  |     #! ${pkgs.runtimeShell} | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |     ${optionalString nm.enable ''
 | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-11-13 12:52:02 -05:00
										 |  |  |       ${pkgs.coreutils}/bin/cat << EOF | 
					
						
							| 
									
										
										
										
											2020-06-24 20:47:44 +02:00
										 |  |  |       From: smartd on ${host} <${nm.sender}> | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |       To: undisclosed-recipients:; | 
					
						
							| 
									
										
										
										
											2020-08-16 20:48:42 +02:00
										 |  |  |       Subject: $SMARTD_SUBJECT | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       $SMARTD_FULLMESSAGE | 
					
						
							|  |  |  |       EOF | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ${pkgs.smartmontools}/sbin/smartctl -a -d "$SMARTD_DEVICETYPE" "$SMARTD_DEVICE" | 
					
						
							|  |  |  |       } | ${nm.mailer} -i "${nm.recipient}" | 
					
						
							|  |  |  |     ''}
 | 
					
						
							|  |  |  |     ${optionalString nw.enable ''
 | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-11-13 12:52:02 -05:00
										 |  |  |       ${pkgs.coreutils}/bin/cat << EOF | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |       Problem detected with disk: $SMARTD_DEVICESTRING | 
					
						
							|  |  |  |       Warning message from smartd is: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       $SMARTD_MESSAGE | 
					
						
							|  |  |  |       EOF | 
					
						
							| 
									
										
										
										
											2020-11-24 10:29:28 -05:00
										 |  |  |       } | ${pkgs.util-linux}/bin/wall 2>/dev/null | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |     ''}
 | 
					
						
							|  |  |  |     ${optionalString nx.enable ''
 | 
					
						
							|  |  |  |       export DISPLAY=${nx.display} | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-11-13 12:52:02 -05:00
										 |  |  |       ${pkgs.coreutils}/bin/cat << EOF | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |       Problem detected with disk: $SMARTD_DEVICESTRING | 
					
						
							|  |  |  |       Warning message from smartd is: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       $SMARTD_FULLMESSAGE | 
					
						
							|  |  |  |       EOF | 
					
						
							|  |  |  |       } | ${pkgs.xorg.xmessage}/bin/xmessage -file - 2>/dev/null & | 
					
						
							|  |  |  |     ''}
 | 
					
						
							|  |  |  |   '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   notifyOpts = optionalString (nm.enable || nw.enable || nx.enable) | 
					
						
							|  |  |  |     ("-m <nomailer> -M exec ${smartdNotify} " + optionalString cfg.notifications.test "-M test "); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   smartdConf = pkgs.writeText "smartd.conf" ''
 | 
					
						
							|  |  |  |     # Autogenerated smartd startup config file | 
					
						
							|  |  |  |     DEFAULT ${notifyOpts}${cfg.defaults.monitored} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ${concatMapStringsSep "\n" (d: "${d.device} ${d.options}") cfg.devices} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ${optionalString cfg.autodetect | 
					
						
							|  |  |  |        "DEVICESCAN ${notifyOpts}${cfg.defaults.autodetected}"} | 
					
						
							|  |  |  |   '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |   smartdDeviceOpts = { ... }: { | 
					
						
							| 
									
										
										
										
											2013-03-10 01:19:44 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       device = mkOption { | 
					
						
							|  |  |  |         example = "/dev/sda"; | 
					
						
							| 
									
										
										
										
											2013-10-30 14:53:06 +01:00
										 |  |  |         type = types.str; | 
					
						
							| 
									
										
										
										
											2013-03-10 01:19:44 +01:00
										 |  |  |         description = "Location of the device."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       options = mkOption { | 
					
						
							|  |  |  |         default = ""; | 
					
						
							|  |  |  |         example = "-d sat"; | 
					
						
							| 
									
										
										
										
											2013-10-30 14:53:06 +01:00
										 |  |  |         type = types.separatedString " "; | 
					
						
							| 
									
										
										
										
											2013-10-28 16:14:15 +01:00
										 |  |  |         description = "Options that determine how smartd monitors the device."; | 
					
						
							| 
									
										
										
										
											2013-03-10 01:19:44 +01:00
										 |  |  |       }; | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-10 01:19:44 +01:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-14 14:42:22 +08:00
										 |  |  | in | 
					
						
							| 
									
										
										
										
											2011-07-13 17:47:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-14 14:42:22 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-07-13 17:47:34 +00:00
										 |  |  |   ###### interface | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   options = { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     services.smartd = { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |       enable = mkEnableOption "smartd daemon from <literal>smartmontools</literal> package"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       autodetect = mkOption { | 
					
						
							|  |  |  |         default = true; | 
					
						
							| 
									
										
										
										
											2011-07-13 17:47:34 +00:00
										 |  |  |         type = types.bool; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |           Whenever smartd should monitor all devices connected to the | 
					
						
							|  |  |  |           machine at the time it's being started (the default). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           Set to false to monitor the devices listed in | 
					
						
							|  |  |  |           <option>services.smartd.devices</option> only. | 
					
						
							| 
									
										
										
										
											2011-07-13 17:47:34 +00:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-04 22:43:30 -05:00
										 |  |  |       extraOptions = mkOption { | 
					
						
							|  |  |  |         default = []; | 
					
						
							|  |  |  |         type = types.listOf types.str; | 
					
						
							|  |  |  |         example = ["-A /var/log/smartd/" "--interval=3600"]; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           Extra command-line options passed to the <literal>smartd</literal> | 
					
						
							|  |  |  |           daemon on startup. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           (See <literal>man 8 smartd</literal>.) | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |       notifications = { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         mail = { | 
					
						
							|  |  |  |           enable = mkOption { | 
					
						
							|  |  |  |             default = config.services.mail.sendmailSetuidWrapper != null; | 
					
						
							|  |  |  |             type = types.bool; | 
					
						
							|  |  |  |             description = "Whenever to send e-mail notifications."; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-24 20:47:44 +02:00
										 |  |  |           sender = mkOption { | 
					
						
							|  |  |  |             default = "root"; | 
					
						
							|  |  |  |             example = "example@domain.tld"; | 
					
						
							|  |  |  |             type = types.str; | 
					
						
							|  |  |  |             description = ''
 | 
					
						
							|  |  |  |               Sender of the notification messages. | 
					
						
							| 
									
										
										
										
											2020-08-05 16:07:58 -07:00
										 |  |  |               Acts as the value of <literal>email</literal> in the emails' <literal>From: ... </literal> field. | 
					
						
							| 
									
										
										
										
											2020-06-24 20:47:44 +02:00
										 |  |  |             '';
 | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |           recipient = mkOption { | 
					
						
							|  |  |  |             default = "root"; | 
					
						
							| 
									
										
										
										
											2015-08-17 17:52:45 +00:00
										 |  |  |             type = types.str; | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |             description = "Recipient of the notification messages."; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           mailer = mkOption { | 
					
						
							| 
									
										
										
										
											2017-01-29 04:11:01 -06:00
										 |  |  |             default = "/run/wrappers/bin/sendmail"; | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |             type = types.path; | 
					
						
							|  |  |  |             description = ''
 | 
					
						
							|  |  |  |               Sendmail-compatible binary to be used to send the messages. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               You should probably enable | 
					
						
							|  |  |  |               <option>services.postfix</option> or some other MTA for | 
					
						
							|  |  |  |               this to work. | 
					
						
							|  |  |  |             '';
 | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         wall = { | 
					
						
							|  |  |  |           enable = mkOption { | 
					
						
							|  |  |  |             default = true; | 
					
						
							|  |  |  |             type = types.bool; | 
					
						
							|  |  |  |             description = "Whenever to send wall notifications to all users."; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         x11 = { | 
					
						
							|  |  |  |           enable = mkOption { | 
					
						
							|  |  |  |             default = config.services.xserver.enable; | 
					
						
							|  |  |  |             type = types.bool; | 
					
						
							|  |  |  |             description = "Whenever to send X11 xmessage notifications."; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           display = mkOption { | 
					
						
							|  |  |  |             default = ":${toString config.services.xserver.display}"; | 
					
						
							| 
									
										
										
										
											2015-08-17 17:52:45 +00:00
										 |  |  |             type = types.str; | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |             description = "DISPLAY to send X11 notifications to."; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test = mkOption { | 
					
						
							|  |  |  |           default = false; | 
					
						
							|  |  |  |           type = types.bool; | 
					
						
							|  |  |  |           description = "Whenever to send a test notification on startup."; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       defaults = { | 
					
						
							|  |  |  |         monitored = mkOption { | 
					
						
							|  |  |  |           default = "-a"; | 
					
						
							|  |  |  |           type = types.separatedString " "; | 
					
						
							|  |  |  |           example = "-a -o on -s (S/../.././02|L/../../7/04)"; | 
					
						
							|  |  |  |           description = ''
 | 
					
						
							|  |  |  |             Common default options for explicitly monitored (listed in | 
					
						
							|  |  |  |             <option>services.smartd.devices</option>) devices. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             The default value turns on monitoring of all the things (see | 
					
						
							|  |  |  |             <literal>man 5 smartd.conf</literal>). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             The example also turns on SMART Automatic Offline Testing on | 
					
						
							|  |  |  |             startup, and schedules short self-tests daily, and long | 
					
						
							|  |  |  |             self-tests weekly. | 
					
						
							|  |  |  |           '';
 | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         autodetected = mkOption { | 
					
						
							|  |  |  |           default = cfg.defaults.monitored; | 
					
						
							|  |  |  |           type = types.separatedString " "; | 
					
						
							|  |  |  |           description = ''
 | 
					
						
							|  |  |  |             Like <option>services.smartd.defaults.monitored</option>, but for the | 
					
						
							|  |  |  |             autodetected devices. | 
					
						
							|  |  |  |           '';
 | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2012-10-05 22:02:47 -07:00
										 |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-21 19:32:15 +00:00
										 |  |  |       devices = mkOption { | 
					
						
							|  |  |  |         default = []; | 
					
						
							| 
									
										
										
										
											2013-03-10 01:19:44 +01:00
										 |  |  |         example = [ { device = "/dev/sda"; } { device = "/dev/sdb"; options = "-d sat"; } ]; | 
					
						
							| 
									
										
										
										
											2017-12-04 22:43:30 -05:00
										 |  |  |         type = with types; listOf (submodule smartdDeviceOpts); | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |         description = "List of devices to monitor."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-13 17:47:34 +00:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ###### implementation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   config = mkIf cfg.enable { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-16 17:03:48 +00:00
										 |  |  |     assertions = [ { | 
					
						
							|  |  |  |       assertion = cfg.autodetect || cfg.devices != []; | 
					
						
							|  |  |  |       message = "smartd can't run with both disabled autodetect and an empty list of devices to monitor."; | 
					
						
							|  |  |  |     } ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 12:33:18 +01:00
										 |  |  |     systemd.services.smartd = { | 
					
						
							| 
									
										
										
										
											2012-12-27 09:50:40 +01:00
										 |  |  |       description = "S.M.A.R.T. Daemon"; | 
					
						
							|  |  |  |       wantedBy = [ "multi-user.target" ]; | 
					
						
							| 
									
										
										
										
											2017-12-04 22:43:30 -05:00
										 |  |  |       serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd ${lib.concatStringsSep " " cfg.extraOptions} --no-fork --configfile=${smartdConf}"; | 
					
						
							| 
									
										
										
										
											2012-12-27 09:50:40 +01:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-07-13 17:47:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |