Migrate tailscalesd to uv and add flake packaging with a NixOS service module.

This commit is contained in:
Abel Luck 2026-03-05 15:37:04 +01:00
parent b195bd1e8f
commit d5201b471b
14 changed files with 2160 additions and 2242 deletions

View file

@ -0,0 +1,138 @@
{
config,
lib,
tailscalesdPackage ? null,
...
}:
let
inherit (lib)
mkEnableOption
mkIf
mkOption
types
;
cfg = config.services.tailscalesd;
execStart = lib.concatStringsSep " " (
[ (lib.getExe' cfg.package "tailscalesd") ] ++ map lib.escapeShellArg cfg.extraArgs
);
in
{
options.services.tailscalesd = {
enable = mkEnableOption "tailscalesd Prometheus HTTP service discovery daemon";
package = mkOption {
type = types.nullOr types.package;
default = tailscalesdPackage;
defaultText = "self.packages.<system>.tailscalesd";
description = "Package that provides the tailscalesd executable.";
};
user = mkOption {
type = types.str;
default = "tailscalesd";
description = "System user for the tailscalesd process.";
};
group = mkOption {
type = types.str;
default = "tailscalesd";
description = "System group for the tailscalesd process.";
};
environmentFile = mkOption {
type = types.nullOr types.str;
default = null;
example = "/run/secrets/tailscalesd.env";
description = "Optional EnvironmentFile with TAILSCALESD_* values, including secrets.";
};
environment = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Extra environment variables for tailscalesd.";
};
host = mkOption {
type = types.str;
default = "127.0.0.1";
description = "Bind address for tailscalesd.";
};
port = mkOption {
type = types.port;
default = 9242;
description = "Bind port for tailscalesd.";
};
interval = mkOption {
type = types.ints.positive;
default = 60;
description = "Polling interval in seconds.";
};
extraArgs = mkOption {
type = types.listOf types.str;
default = [ ];
description = "Extra CLI arguments appended to the tailscalesd command.";
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = "Open the service port in the host firewall.";
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = cfg.package != null;
message = "services.tailscalesd.package must be set when services.tailscalesd.enable = true.";
}
];
users.groups = mkIf (cfg.group == "tailscalesd") {
tailscalesd = { };
};
users.users = mkIf (cfg.user == "tailscalesd") {
tailscalesd = {
isSystemUser = true;
group = cfg.group;
};
};
networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [ cfg.port ];
systemd.services.tailscalesd = {
description = "tailscalesd";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
serviceConfig = {
Type = "simple";
User = cfg.user;
Group = cfg.group;
ExecStart = execStart;
Restart = "on-failure";
RestartSec = "5s";
NoNewPrivileges = true;
PrivateTmp = true;
ProtectHome = true;
ProtectSystem = "strict";
WorkingDirectory = "/var/lib/tailscalesd";
StateDirectory = "tailscalesd";
}
// lib.optionalAttrs (cfg.environmentFile != null) {
EnvironmentFile = cfg.environmentFile;
};
environment = cfg.environment // {
TAILSCALESD_HOST = cfg.host;
TAILSCALESD_PORT = toString cfg.port;
TAILSCALESD_INTERVAL = toString cfg.interval;
};
};
};
}