163 lines
4.3 KiB
Nix
163 lines
4.3 KiB
Nix
{ self }:
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
inherit (lib)
|
|
mkEnableOption
|
|
mkIf
|
|
mkOption
|
|
types
|
|
;
|
|
cfg = config.services.vibe-proxy;
|
|
statePath = "/var/lib/${cfg.stateDirectory}";
|
|
yaml = pkgs.formats.yaml { };
|
|
generatedSettings =
|
|
lib.recursiveUpdate
|
|
(
|
|
{
|
|
host = cfg.host;
|
|
port = cfg.port;
|
|
auth-dir = "${statePath}/auths";
|
|
}
|
|
// cfg.settings
|
|
)
|
|
{
|
|
host = cfg.host;
|
|
port = cfg.port;
|
|
};
|
|
generatedConfig = yaml.generate "vibe-proxy.yaml" generatedSettings;
|
|
runtimeConfig =
|
|
if cfg.configFile == null then "${statePath}/config.yaml" else toString cfg.configFile;
|
|
in
|
|
{
|
|
options.services.vibe-proxy = {
|
|
enable = mkEnableOption "Vibe Proxy";
|
|
|
|
package = mkOption {
|
|
type = types.package;
|
|
default = self.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
|
defaultText = lib.literalExpression "inputs.vibe-proxy.packages.${pkgs.stdenv.hostPlatform.system}.default";
|
|
description = "Vibe Proxy package to run.";
|
|
};
|
|
|
|
user = mkOption {
|
|
type = types.str;
|
|
default = "vibe-proxy";
|
|
description = "User account under which the service runs.";
|
|
};
|
|
|
|
group = mkOption {
|
|
type = types.str;
|
|
default = "vibe-proxy";
|
|
description = "Group under which the service runs.";
|
|
};
|
|
|
|
stateDirectory = mkOption {
|
|
type = types.str;
|
|
default = "vibe-proxy";
|
|
description = "Directory below /var/lib used for writable service state.";
|
|
};
|
|
|
|
host = mkOption {
|
|
type = types.str;
|
|
default = "127.0.0.1";
|
|
description = "Address on which the API listens.";
|
|
};
|
|
|
|
port = mkOption {
|
|
type = types.port;
|
|
default = 8317;
|
|
description = "TCP port on which the API listens.";
|
|
};
|
|
|
|
openFirewall = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = "Whether to open the main API port in the firewall.";
|
|
};
|
|
|
|
configFile = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = "Writable external configuration file. When null, settings generate the configuration on every service start.";
|
|
};
|
|
|
|
settings = mkOption {
|
|
type = yaml.type;
|
|
default = { };
|
|
description = "Declarative YAML configuration. Secrets in this option are written to the Nix store; use environmentFiles for secrets.";
|
|
};
|
|
|
|
environment = mkOption {
|
|
type = types.attrsOf types.str;
|
|
default = { };
|
|
description = "Non-secret environment variables for the service.";
|
|
};
|
|
|
|
environmentFiles = mkOption {
|
|
type = types.listOf types.path;
|
|
default = [ ];
|
|
description = "Environment files containing secrets such as MANAGEMENT_PASSWORD.";
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
users.groups = mkIf (cfg.group == "vibe-proxy") {
|
|
vibe-proxy = { };
|
|
};
|
|
users.users = mkIf (cfg.user == "vibe-proxy") {
|
|
vibe-proxy = {
|
|
isSystemUser = true;
|
|
inherit (cfg) group;
|
|
home = statePath;
|
|
};
|
|
};
|
|
|
|
networking.firewall.allowedTCPPorts = lib.optional cfg.openFirewall cfg.port;
|
|
|
|
systemd.services.vibe-proxy = {
|
|
description = "Vibe Proxy API";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "network-online.target" ];
|
|
wants = [ "network-online.target" ];
|
|
|
|
environment = {
|
|
HOME = statePath;
|
|
WRITABLE_PATH = statePath;
|
|
}
|
|
// cfg.environment;
|
|
|
|
preStart = ''
|
|
ln -sfn ${cfg.package}/share/vibe-proxy/config.example.yaml ${statePath}/config.example.yaml
|
|
''
|
|
+ lib.optionalString (cfg.configFile == null) ''
|
|
install -m 0600 ${generatedConfig} ${runtimeConfig}
|
|
'';
|
|
|
|
serviceConfig = {
|
|
User = cfg.user;
|
|
Group = cfg.group;
|
|
StateDirectory = cfg.stateDirectory;
|
|
StateDirectoryMode = "0700";
|
|
WorkingDirectory = statePath;
|
|
EnvironmentFile = cfg.environmentFiles;
|
|
ExecStart = "${lib.getExe cfg.package} --config ${lib.escapeShellArg runtimeConfig}";
|
|
Restart = "on-failure";
|
|
RestartSec = "5s";
|
|
UMask = "0077";
|
|
NoNewPrivileges = true;
|
|
PrivateTmp = true;
|
|
ProtectSystem = "strict";
|
|
ProtectHome = true;
|
|
ReadWritePaths = [
|
|
statePath
|
|
]
|
|
++ lib.optional (cfg.configFile != null) (builtins.dirOf cfg.configFile);
|
|
};
|
|
};
|
|
};
|
|
}
|