diff --git a/nix/modules/nixos.nix b/nix/modules/nixos.nix index 7df3b81..53de554 100644 --- a/nix/modules/nixos.nix +++ b/nix/modules/nixos.nix @@ -6,33 +6,117 @@ self: { }: let inherit (lib.modules) mkIf; inherit (lib.options) mkOption mkEnableOption; - inherit (lib.types) package; + 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 { - systemd.packages = [cfg.package]; + 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"; + ExecStart = "${cfg.package}/bin/pscand run --config /etc/pscand/pscand.toml"; Restart = "on-failure"; RestartSec = "5s"; - Environment = ["${cfg.package}/lib/pscand/scanners"]; # FIXME: make this configurable + Environment = "PSCAND_SCANNER_DIRS=${lib.concatStringsSep ":" cfg.scannerDirs}"; }; }; + + systemd.tmpfiles.rules = [ + "d ${cfg.logDir} 0755 root root -" + ]; }; }