self: { config, pkgs, lib, ... }: let inherit (lib.modules) mkIf; inherit (lib.options) mkOption mkEnableOption; inherit (lib.types) package bool str listOf attrsOf submodule int nullOr anything; cfg = config.services.pscand; settingsFormat = pkgs.formats.toml {}; configFile = settingsFormat.generate "pscand.toml" { scanner_dirs = cfg.scannerDirs; log_dir = cfg.logDir; ring_buffer_size = cfg.ringBufferSize; journal_enabled = cfg.journalEnabled; file_enabled = cfg.fileEnabled; scanners = lib.mapAttrs (_: scanner: { enabled = scanner.enabled; interval_secs = scanner.interval; extra = scanner.extra; }) cfg.scanners; }; in { options.services.pscand = { enable = mkEnableOption "Pluggable System Condition Monitoring Daemon"; package = mkOption { type = package; default = self.packages.${pkgs.hostPlatform.system.pscand}; defaultText = "self.packages.$${pkgs.hostPlatform.system}.pscand"; description = "The pscand package to use"; }; scannerDirs = mkOption { type = listOf str; default = ["${cfg.package}/lib/pscand/scanners"]; description = "Directories to load scanner plugins from"; }; logDir = mkOption { type = str; default = "/var/log/pscand"; description = "Directory for log files and heartbeat"; }; ringBufferSize = mkOption { type = int; default = 1000; description = "Number of log entries to keep in memory for crash recovery"; }; journal.enable = mkEnableOption "logging to Systemd journal"; file.enable = mkEnableOption "logging to file"; scanners = mkOption { type = attrsOf (submodule { options = { enabled = mkOption { type = bool; default = true; description = "Whether this scanner is enabled"; }; interval = mkOption { type = nullOr int; default = null; description = "Collection interval in seconds (null = use scanner default)"; }; extra = mkOption { type = attrsOf anything; default = {}; description = "Scanner-specific configuration options"; }; }; }); default = {}; description = "Per-scanner configuration settings"; example = { system = { enabled = true; interval = 5; }; sensor = { enabled = true; interval = 10; extra = {sensors = ["coretemp" "nvme"];}; }; power = { enabled = true; interval = 30; }; }; }; }; config = mkIf cfg.enable { environment.etc."pscand/pscand.toml".source = configFile; systemd.services.pscand = { wantedBy = ["multi-user.target"]; after = ["network.target"]; serviceConfig = { Type = "simple"; ExecStart = "${cfg.package}/bin/pscand run --config /etc/pscand/pscand.toml"; Restart = "on-failure"; RestartSec = "5s"; Environment = "PSCAND_SCANNER_DIRS=${lib.concatStringsSep ":" cfg.scannerDirs}"; }; }; systemd.tmpfiles.rules = [ "d ${cfg.logDir} 0755 root root -" ]; }; }