treewide: add support for unix sockets

This commit is contained in:
Oystein Kristoffer Tveit 2024-01-13 18:18:21 +01:00
parent 19d50fae63
commit b8d7c76a7e
Signed by untrusted user: oysteikt
GPG Key ID: 9F2F7D8250F35146
2 changed files with 113 additions and 25 deletions

View File

@ -10,7 +10,9 @@ let
wcfgText = "config.services.matrix-synapse-next.workers";
format = pkgs.formats.yaml {};
matrix-synapse-common-config = format.generate "matrix-synapse-common-config.yaml" cfg.settings;
matrix-synapse-common-config = format.generate "matrix-synapse-common-config.yaml" (cfg.settings // {
listeners = map (lib.filterAttrsRecursive (_: v: v != null)) cfg.settings.listeners;
});
# TODO: Align better with the upstream module
wrapped = cfg.package.override {
@ -79,6 +81,15 @@ in
'';
};
socketDir = mkOption {
type = types.path;
default = "/run/matrix-synapse";
description = ''
The directory where matrix-synapse by default stores the sockets of
all listeners that bind to UNIX sockets.
'';
};
enableNginx = mkEnableOption "The synapse module managing nginx";
public_baseurl = mkOption {
@ -135,14 +146,42 @@ in
type = types.listOf (types.submodule {
options = {
port = mkOption {
type = types.port;
description = "The TCP port to bind to";
type = with types; nullOr types.port;
default = null;
description = ''
The TCP port to bind to.
::: {.note}
This option will be ignored if {option}`path` is set to a non-null value.
:::
'';
example = 8448;
};
path = mkOption {
type = with types; nullOr path;
default = null;
description = ''
The UNIX socket to bind to.
::: {.note}
This option will override {option}`bind_addresses` and {option}`port`
if set to a non-null value.
:::
'';
example = literalExpression ''''${${cfgText}.socketDir}/matrix-synapse.sock'';
};
bind_addresses = mkOption {
type = types.listOf types.str;
description = "A list of local addresses to listen on";
default = [ ];
description = ''
A list of local addresses to listen on.
::: {.note}
This option will be ignored if {option}`path` is set to a non-null value.
:::
'';
};
type = mkOption {
@ -201,16 +240,14 @@ in
# TODO: add defaultText
default = [
{
port = 8008;
bind_addresses = [ "127.0.0.1" ];
path = "${cfg.socketDir}/matrix-synapse.sock";
resources = [
{ names = [ "client" ]; compress = true; }
{ names = [ "federation" ]; compress = false; }
];
}
(mkIf (wcfg.instances != { }) {
port = 9093;
bind_addresses = [ "127.0.0.1" ];
path = "${cfg.socketDir}/matrix-synapse-replication.sock";
resources = [
{ names = [ "replication" ]; }
];
@ -352,6 +389,12 @@ in
};
config = mkIf cfg.enable {
assertions = [ ]
++ (map (l: {
assertion = l.path == null -> (l.bind_addresses != [ ] && l.port != null);
message = "Some listeners are missing either a socket path or a bind_address + port to listen on";
}) cfg.settings.listeners);
users.users.matrix-synapse = {
group = "matrix-synapse";
home = cfg.dataDir;
@ -396,6 +439,8 @@ in
Group = "matrix-synapse";
Slice = "system-matrix-synapse.slice";
WorkingDirectory = cfg.dataDir;
StateDirectory = "matrix-synapse";
RuntimeDirectory = "matrix-synapse";
ExecStart = let
flags = lib.cli.toGNUCommandLineShell {} {
config-path = [ matrix-synapse-common-config ] ++ cfg.extraConfigFiles;

View File

@ -86,10 +86,17 @@ in {
};
port = mkOption {
type = types.port;
type = with types; nullOr port;
default = null;
description = "The TCP port to bind to";
};
path = mkOption {
type = with types; nullOr path;
default = null;
description = "The UNIX socket to bind to";
};
bind_addresses = mkOption {
type = with types; listOf str;
description = "A list of local addresses to listen on";
@ -161,7 +168,7 @@ in {
};
in {
mainReplicationHost = mkOption {
type = types.str;
type = with types; nullOr str;
default = let
host = (matrix-lib.connectionInfo mainReplicationListener).host;
in
@ -174,18 +181,32 @@ in {
};
mainReplicationPort = mkOption {
type = types.port;
type = with types; nullOr port;
default = mainReplicationListener.port;
# TODO: add defaultText
description = "Port for the main synapse instance's replication listener";
};
mainReplicationPath = mkOption {
type = with types; nullOr path;
default = mainReplicationListener.path;
# TODO: add defaultText
description = "Path to the UNIX socket of the main synapse instance's replication listener";
};
defaultListenerAddress = mkOption {
type = types.str;
default = "127.0.0.1";
description = "The default listener address for the worker";
};
workersUsePath = mkOption {
type = types.bool;
description = "Whether to enable UNIX sockets for all automatically generated workers";
default = true;
example = false;
};
workerStartingPort = mkOption {
type = types.port;
description = "What port should the automatically configured workers start enumerating from";
@ -233,22 +254,32 @@ in {
};
config = {
assertions = [ ]
++ (lib.concatMap (worker:
(map (l: {
assertion = l.path == null -> (l.bind_addresses != [ ] && l.port != null);
message = "At least one worker listener is missing either a socket path or a bind_address + port to listen on";
}) worker.settings.worker_listeners)
) (lib.attrValues wcfg.instances));
services.matrix-synapse-next.settings = {
federation_sender_instances =
lib.genList (i: "auto-fed-sender${toString (i + 1)}") wcfg.federationSenders;
instance_map = (lib.mkIf (cfg.workers.instances != { }) ({
main = let
host = lib.head mainReplicationListener.bind_addresses;
in {
host = if builtins.elem host [ "0.0.0.0" "::"] then "127.0.0.1" else host;
port = mainReplicationListener.port;
main = if wcfg.mainReplicationPath != null then {
path = wcfg.mainReplicationPath;
} else {
host = wcfg.mainReplicationHost;
port = wcfg.mainReplicationPort;
};
} // genAttrs' (lib.lists.range 1 wcfg.eventPersisters)
(i: "auto-event-persist${toString i}")
(i: let
wRL = matrix-lib.firstListenerOfType "replication" wcfg.instances."auto-event-persist${toString i}".settings.worker_listeners;
in matrix-lib.connectionInfo wRL)));
in if wRL.path != null then {
inherit (wRL) path;
} else matrix-lib.connectionInfo wRL)));
stream_writers.events =
mkIf (wcfg.eventPersisters > 0)
@ -260,10 +291,15 @@ in {
services.matrix-synapse-next.workers.instances = let
sum = lib.foldl lib.add 0;
workerListenersWithMetrics = portOffset:
lib.singleton ({
port = wcfg.workerStartingPort + portOffset - 1;
})
workerListenersWithMetrics = portOffset: name:
[(if wcfg.workersUsePath
then {
path = "${cfg.socketDir}/matrix-synapse-worker-${name}.sock";
}
else {
port = wcfg.workerStartingPort + portOffset - 1;
}
)]
++ lib.optional wcfg.enableMetrics {
port = wcfg.metricsStartingPort + portOffset;
resources = [ { names = [ "metrics" ]; } ];
@ -274,7 +310,7 @@ in {
numberOfWorkers,
portOffset ? 0,
nameFn ? i: "auto-${type}${toString i}",
workerListenerFn ? i: workerListenersWithMetrics (portOffset + i)
workerListenerFn ? i: name: workerListenersWithMetrics (portOffset + i) name
}: genAttrs'
(lib.lists.range 1 numberOfWorkers)
nameFn
@ -282,7 +318,7 @@ in {
isAuto = true;
inherit type;
index = i;
settings.worker_listeners = workerListenerFn i;
settings.worker_listeners = workerListenerFn i (nameFn i);
});
workerInstances = {
@ -323,8 +359,13 @@ in {
systemd.services = let
workerList = lib.mapAttrsToList lib.nameValuePair wcfg.instances;
workerConfig = worker: format.generate "matrix-synapse-worker-${worker.name}-config.yaml"
(worker.value.settings // { worker_name = worker.name; });
workerConfig = worker:
format.generate "matrix-synapse-worker-${worker.name}-config.yaml"
(worker.value.settings // {
worker_name = worker.name;
worker_listeners =
map (lib.filterAttrsRecursive (_: v: v != null)) worker.value.settings.worker_listeners;
});
in builtins.listToAttrs (lib.flip map workerList (worker: {
name = "matrix-synapse-worker-${worker.name}";
value = {
@ -339,6 +380,8 @@ in {
Group = "matrix-synapse";
Slice = "system-matrix-synapse.slice";
WorkingDirectory = cfg.dataDir;
RuntimeDirectory = "matrix-synapse";
StateDirectory = "matrix-synapse";
ExecStartPre = pkgs.writers.writeBash "wait-for-synapse" ''
# From https://md.darmstadt.ccc.de/synapse-at-work
while ! systemctl is-active -q matrix-synapse.service; do