systant/nix/nixos-module.nix
ryan 4e46f3e0fc refactor: change to systemd user service
Systant is designed as a userspace controller rather than a system
daemon, so it makes more sense to run as a user service with access
to the user's environment, PATH, and session (for audio control, etc).

Changes:
- Remove user/group options (runs as current user)
- Use systemd.user.services instead of systemd.services
- Remove hardening options (not needed and would restrict access)
- Add package to environment.systemPackages

Enable with: systemctl --user enable --now systant

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 20:55:52 -08:00

87 lines
2.4 KiB
Nix

{ config, lib, pkgs, ... }:
let
cfg = config.systant;
settingsFormat = pkgs.formats.toml { };
configFile =
if cfg.configFile != null
then cfg.configFile
else if cfg.settings != { }
then settingsFormat.generate "systant-config.toml" cfg.settings
else null;
in
{
options.systant = {
enable = lib.mkEnableOption "systant system monitoring agent";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.systant;
defaultText = lib.literalExpression "pkgs.systant";
description = "The systant package to use.";
};
configFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Path to the systant configuration file (TOML).
If set, this takes precedence over the settings option.
'';
};
settings = lib.mkOption {
type = settingsFormat.type;
default = { };
description = ''
Configuration for systant in Nix attribute set form.
Will be converted to TOML. Ignored if configFile is set.
'';
example = lib.literalExpression ''
{
mqtt = {
broker = "mqtt://localhost:1883";
topicPrefix = "systant";
};
entities = {
cpu_usage = {
type = "sensor";
state_command = "awk '/^cpu / {u=$2+$4; t=$2+$4+$5; print int(u*100/t)}' /proc/stat";
unit = "%";
icon = "mdi:cpu-64-bit";
name = "CPU Usage";
};
};
homeassistant = {
discovery = true;
discoveryPrefix = "homeassistant";
};
}
'';
};
};
config = lib.mkIf cfg.enable {
# Make the package available system-wide
environment.systemPackages = [ cfg.package ];
# Systemd user service - runs in user session with user's environment
systemd.user.services.systant = {
description = "Systant system monitoring agent";
wantedBy = [ "default.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "simple";
ExecStart =
if configFile != null
then "${cfg.package}/bin/systant run --config ${configFile}"
else "${cfg.package}/bin/systant run";
Restart = "on-failure";
RestartSec = "5s";
};
};
};
}