grapevine/nix/modules/default/default.nix
Charles Hall 1cd12460d7
make systemd patient for startup
RocksDB compaction can take quite a while if it doesn't happen
regularly, which it doesn't, currently.
2025-04-06 15:46:27 -07:00

145 lines
4.3 KiB
Nix

inputs:
{ config
, lib
, pkgs
, ...
}:
let
inherit (lib) types;
cfg = config.services.grapevine;
configFile = format.generate "config.toml" cfg.settings;
validateConfig = file: pkgs.runCommand "grapevine-checked-config" {} ''
${lib.getExe cfg.package} check-config -sc ${lib.escapeShellArg file}
ln -s ${lib.escapeShellArg file} "$out"
'';
format = pkgs.formats.toml {};
in
{
options.services.grapevine = {
enable = lib.mkEnableOption "grapevine";
package = lib.mkPackageOption
inputs.self.packages.${pkgs.stdenv.hostPlatform.system}
"grapevine"
{
default = "default";
pkgsText = "inputs.grapevine.packages.\${pkgs.stdenv.hostPlatform.system}";
};
settings = lib.mkOption {
type = types.submodule {
freeformType = format.type;
options = {
conduit_compat = lib.mkOption {
type = types.bool;
description = ''
Whether to operate as a drop-in replacement for Conduit.
'';
default = false;
};
database.path = lib.mkOption {
type = types.nonEmptyStr;
readOnly = true;
description = ''
The path to store database files in.
Note that this is read-only because this module makes use of
systemd's `StateDirectory` option.
'';
default = if cfg.settings.conduit_compat
then "/var/lib/matrix-conduit/database"
else "/var/lib/grapevine/database";
};
media.backend = {
type = lib.mkOption {
type = types.nonEmptyStr;
readOnly = true;
description = ''
The media backend to use.
Note that this is read-only because `filesystem` is currently
the only valid option.
'';
default = "filesystem";
};
path = lib.mkOption {
type = types.nonEmptyStr;
readOnly = true;
description = ''
The path to store database files in.
Note that this is read-only because this module makes use of
systemd's `StateDirectory` option.
'';
default = if cfg.settings.conduit_compat
then "/var/lib/matrix-conduit/media"
else "/var/lib/grapevine/media";
};
};
listen = lib.mkOption {
type = types.listOf format.type;
description = ''
List of places to listen for incoming connections.
'';
default = [
{
type = "tcp";
address = "::1";
port = 6167;
}
];
};
};
};
default = {};
description = ''
The TOML configuration file is generated from this attribute set.
'';
};
};
config = lib.mkIf cfg.enable {
systemd.services.grapevine = {
description = "Grapevine (Matrix homeserver)";
wantedBy = [ "multi-user.target" ];
# Keep sorted
serviceConfig = {
DynamicUser = true;
ExecStart = "${lib.getExe cfg.package} serve --config ${validateConfig configFile}";
LockPersonality = true;
MemoryDenyWriteExecute = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
Restart = "on-failure";
RestartSec = 10;
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
RestrictNamespaces = true;
RestrictRealtime = true;
StartLimitBurst = 5;
StateDirectory = if cfg.settings.conduit_compat
then "matrix-conduit"
else "grapevine";
StateDirectoryMode = "0700";
SystemCallArchitectures = "native";
SystemCallFilter = [ "@system-service" "~@privileged" ];
TimeoutStartSec = "infinity";
Type = "notify";
UMask = "077";
User = if cfg.settings.conduit_compat
then "conduit"
else "grapevine";
};
};
};
}