1 { config, lib, pkgs, ... }:
3 inherit (lib) maintainers;
4 inherit (lib.meta) getExe;
5 inherit (lib.modules) mkIf mkMerge;
6 inherit (lib.options) literalExpression mkEnableOption mkOption mkPackageOption;
7 inherit (lib.types) bool enum nullOr port str submodule;
9 cfg = config.services.scrutiny;
10 # Define the settings format used for this program
11 settingsFormat = pkgs.formats.yaml { };
16 enable = mkEnableOption "Scrutiny, a web application for drive monitoring";
18 package = mkPackageOption pkgs "scrutiny" { };
20 openFirewall = mkEnableOption "opening the default ports in the firewall for Scrutiny";
22 influxdb.enable = mkOption {
26 Enables InfluxDB on the host system using the `services.influxdb2` NixOS module
29 If you already have InfluxDB configured, or wish to connect to an external InfluxDB
30 instance, disable this option.
36 Scrutiny settings to be rendered into the configuration file.
38 See https://github.com/AnalogJ/scrutiny/blob/master/example.scrutiny.yaml.
42 freeformType = settingsFormat.type;
44 options.web.listen.port = mkOption {
47 description = "Port for web application to listen on.";
50 options.web.listen.host = mkOption {
53 description = "Interface address for web application to bind to.";
56 options.web.listen.basepath = mkOption {
59 example = "/scrutiny";
61 If Scrutiny will be behind a path prefixed reverse proxy, you can override this
62 value to serve Scrutiny on a subpath.
66 options.log.level = mkOption {
67 type = enum [ "INFO" "DEBUG" ];
69 description = "Log level for Scrutiny.";
72 options.web.influxdb.scheme = mkOption {
75 description = "URL scheme to use when connecting to InfluxDB.";
78 options.web.influxdb.host = mkOption {
81 description = "IP or hostname of the InfluxDB instance.";
84 options.web.influxdb.port = mkOption {
87 description = "The port of the InfluxDB instance.";
90 options.web.influxdb.tls.insecure_skip_verify = mkEnableOption "skipping TLS verification when connecting to InfluxDB";
92 options.web.influxdb.token = mkOption {
95 description = "Authentication token for connecting to InfluxDB.";
98 options.web.influxdb.org = mkOption {
101 description = "InfluxDB organisation under which to store data.";
104 options.web.influxdb.bucket = mkOption {
107 description = "InfluxDB bucket in which to store data.";
113 enable = mkEnableOption "the Scrutiny metrics collector" // {
114 default = cfg.enable;
115 defaultText = lib.literalExpression "config.services.scrutiny.enable";
118 package = mkPackageOption pkgs "scrutiny-collector" { };
120 schedule = mkOption {
124 How often to run the collector in systemd calendar format.
128 settings = mkOption {
130 Collector settings to be rendered into the collector configuration file.
132 See https://github.com/AnalogJ/scrutiny/blob/master/example.collector.yaml.
136 freeformType = settingsFormat.type;
138 options.host.id = mkOption {
141 description = "Host ID for identifying/labelling groups of disks";
144 options.api.endpoint = mkOption {
146 default = "http://${cfg.settings.web.listen.host}:${toString cfg.settings.web.listen.port}";
147 defaultText = literalExpression ''"http://''${config.services.scrutiny.settings.web.listen.host}:''${config.services.scrutiny.settings.web.listen.port}"'';
148 description = "Scrutiny app API endpoint for sending metrics to.";
151 options.log.level = mkOption {
152 type = enum [ "INFO" "DEBUG" ];
154 description = "Log level for Scrutiny collector.";
164 services.influxdb2.enable = cfg.influxdb.enable;
166 networking.firewall = mkIf cfg.openFirewall {
167 allowedTCPPorts = [ cfg.settings.web.listen.port ];
170 systemd.services.scrutiny = {
171 description = "Hard Drive S.M.A.R.T Monitoring, Historical Trends & Real World Failure Thresholds";
172 wantedBy = [ "multi-user.target" ];
173 after = [ "network.target" ] ++ lib.optional cfg.influxdb.enable "influxdb2.service";
174 wants = lib.optional cfg.influxdb.enable "influxdb2.service";
176 SCRUTINY_VERSION = "1";
177 SCRUTINY_WEB_DATABASE_LOCATION = "/var/lib/scrutiny/scrutiny.db";
178 SCRUTINY_WEB_SRC_FRONTEND_PATH = "${cfg.package}/share/scrutiny";
182 ExecStart = "${getExe cfg.package} start --config ${settingsFormat.generate "scrutiny.yaml" cfg.settings}";
184 StateDirectory = "scrutiny";
185 StateDirectoryMode = "0750";
189 (mkIf cfg.collector.enable {
193 "-A /var/log/smartd/"
199 services.scrutiny-collector = {
200 description = "Scrutiny Collector Service";
201 after = lib.optional cfg.enable "scrutiny.service";
202 wants = lib.optional cfg.enable "scrutiny.service";
204 COLLECTOR_VERSION = "1";
205 COLLECTOR_API_ENDPOINT = cfg.collector.settings.api.endpoint;
209 ExecStart = "${getExe cfg.collector.package} run --config ${settingsFormat.generate "scrutiny-collector.yaml" cfg.collector.settings}";
211 startAt = cfg.collector.schedule;
214 timers.scrutiny-collector.timerConfig.Persistent = true;
219 meta.maintainers = [ maintainers.jnsgruk ];