When running nix flake metadata, nix and git need writable cache directories. System service users have home set to /var/empty which is read-only, causing "cannot create directories" errors. Add StateDirectory and set HOME/XDG_CACHE_HOME environment variables to /var/lib/nixos-exporter when flake collector is enabled. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
136 lines
3.6 KiB
Nix
136 lines
3.6 KiB
Nix
{ self }:
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
cfg = config.services.prometheus.exporters.nixos;
|
|
in
|
|
{
|
|
options.services.prometheus.exporters.nixos = {
|
|
enable = lib.mkEnableOption "NixOS Prometheus exporter";
|
|
|
|
port = lib.mkOption {
|
|
type = lib.types.port;
|
|
default = 9971;
|
|
description = "Port to listen on.";
|
|
};
|
|
|
|
listenAddress = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "0.0.0.0";
|
|
description = "Address to listen on.";
|
|
};
|
|
|
|
flake = {
|
|
enable = lib.mkEnableOption "flake collector";
|
|
|
|
url = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "";
|
|
description = ''
|
|
Flake URL for revision comparison.
|
|
Required if flake collector is enabled.
|
|
'';
|
|
};
|
|
|
|
checkInterval = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "1h";
|
|
description = "Interval between remote flake checks.";
|
|
};
|
|
};
|
|
|
|
openFirewall = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = "Open the firewall for the exporter port.";
|
|
};
|
|
|
|
user = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "nixos-exporter";
|
|
description = "User to run the exporter as.";
|
|
};
|
|
|
|
group = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "nixos-exporter";
|
|
description = "Group to run the exporter as.";
|
|
};
|
|
|
|
package = lib.mkOption {
|
|
type = lib.types.package;
|
|
default = self.packages.${pkgs.system}.default;
|
|
description = "The nixos-exporter package to use.";
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
assertions = [
|
|
{
|
|
assertion = cfg.flake.enable -> cfg.flake.url != "";
|
|
message = "services.prometheus.exporters.nixos.flake.url must be set when flake collector is enabled";
|
|
}
|
|
];
|
|
|
|
users.users.${cfg.user} = {
|
|
isSystemUser = true;
|
|
group = cfg.group;
|
|
description = "NixOS exporter user";
|
|
};
|
|
|
|
users.groups.${cfg.group} = { };
|
|
|
|
systemd.services.prometheus-nixos-exporter = {
|
|
description = "Prometheus NixOS Exporter";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "network.target" ];
|
|
|
|
# nix is required for flake collector, git for git+https:// URLs
|
|
path = lib.mkIf cfg.flake.enable [
|
|
config.nix.package
|
|
pkgs.git
|
|
];
|
|
|
|
serviceConfig = {
|
|
User = cfg.user;
|
|
Group = cfg.group;
|
|
ExecStart = lib.concatStringsSep " " ([
|
|
"${cfg.package}/bin/nixos-exporter"
|
|
"--listen=${cfg.listenAddress}:${toString cfg.port}"
|
|
] ++ lib.optionals cfg.flake.enable [
|
|
"--collector.flake"
|
|
"--flake.url=${cfg.flake.url}"
|
|
"--flake.check-interval=${cfg.flake.checkInterval}"
|
|
]);
|
|
Restart = "on-failure";
|
|
RestartSec = "5s";
|
|
|
|
# Hardening
|
|
NoNewPrivileges = true;
|
|
ProtectSystem = "strict";
|
|
ProtectHome = true;
|
|
PrivateTmp = true;
|
|
PrivateDevices = true;
|
|
ProtectKernelTunables = true;
|
|
ProtectKernelModules = true;
|
|
ProtectControlGroups = true;
|
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
|
RestrictNamespaces = true;
|
|
RestrictRealtime = true;
|
|
RestrictSUIDSGID = true;
|
|
MemoryDenyWriteExecute = true;
|
|
LockPersonality = true;
|
|
} // lib.optionalAttrs cfg.flake.enable {
|
|
# nix and git need writable cache directories
|
|
StateDirectory = "nixos-exporter";
|
|
Environment = [
|
|
"HOME=/var/lib/nixos-exporter"
|
|
"XDG_CACHE_HOME=/var/lib/nixos-exporter/.cache"
|
|
];
|
|
};
|
|
};
|
|
|
|
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
|
|
};
|
|
}
|