nginx: refactor upstream generation
This commit is contained in:
parent
85804fce8d
commit
18d3b34406
60
lib.nix
60
lib.nix
|
@ -17,4 +17,64 @@ rec {
|
||||||
l = firstListenerOfType r w.settings.worker_listeners;
|
l = firstListenerOfType r w.settings.worker_listeners;
|
||||||
in connectionInfo l;
|
in connectionInfo l;
|
||||||
|
|
||||||
|
mapWorkersToUpstreamsByType = workerInstances:
|
||||||
|
lib.pipe workerInstances [
|
||||||
|
lib.attrValues
|
||||||
|
|
||||||
|
# Index by worker type
|
||||||
|
(lib.foldl (acc: worker: acc // {
|
||||||
|
${worker.type} = (acc.${worker.type} or [ ]) ++ [ worker ];
|
||||||
|
}) { })
|
||||||
|
|
||||||
|
# Subindex by resource names, listener types, and convert to upstreams
|
||||||
|
(lib.mapAttrs (_: workers: lib.pipe workers [
|
||||||
|
(lib.concatMap (worker: worker.settings.worker_listeners))
|
||||||
|
lib.flatten
|
||||||
|
mapListenersToUpstreamsByType
|
||||||
|
]))
|
||||||
|
];
|
||||||
|
|
||||||
|
mapListenersToUpstreamsByType = listenerInstances:
|
||||||
|
lib.pipe listenerInstances [
|
||||||
|
# Index by resource names
|
||||||
|
(lib.concatMap (listener: lib.pipe listener [
|
||||||
|
(listener: let
|
||||||
|
allResourceNames = lib.pipe listener.resources [
|
||||||
|
(map (resource: resource.names))
|
||||||
|
lib.flatten
|
||||||
|
lib.unique
|
||||||
|
];
|
||||||
|
in if allResourceNames == [ ]
|
||||||
|
then { "empty" = listener; }
|
||||||
|
else lib.genAttrs allResourceNames (_: listener))
|
||||||
|
lib.attrsToList
|
||||||
|
]))
|
||||||
|
|
||||||
|
(lib.foldl (acc: listener: acc // {
|
||||||
|
${listener.name} = (acc.${listener.name} or [ ]) ++ [ listener.value ];
|
||||||
|
}) { })
|
||||||
|
|
||||||
|
# Index by listener type
|
||||||
|
(lib.mapAttrs (_:
|
||||||
|
(lib.foldl (acc: listener: acc // {
|
||||||
|
${listener.type} = (acc.${listener.type} or [ ]) ++ [ listener ];
|
||||||
|
}) { })
|
||||||
|
))
|
||||||
|
|
||||||
|
# Convert listeners to upstream URIs
|
||||||
|
(lib.mapAttrs (_:
|
||||||
|
(lib.mapAttrs (_: listeners:
|
||||||
|
lib.pipe listeners [
|
||||||
|
(lib.concatMap (listener:
|
||||||
|
if listener.path != null
|
||||||
|
then [ "unix:${listener.path}" ]
|
||||||
|
else (map (addr: "${addr}:${toString listener.port}") listener.bind_addresses)
|
||||||
|
))
|
||||||
|
# NOTE: Adding ` = { }` to every upstream might seem unnecessary in isolation,
|
||||||
|
# but it makes it easier to set upstreams in the nginx module.
|
||||||
|
(uris: lib.genAttrs uris (_: { }))
|
||||||
|
]
|
||||||
|
))
|
||||||
|
))
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,10 @@
|
||||||
let
|
let
|
||||||
cfg = config.services.matrix-synapse-next;
|
cfg = config.services.matrix-synapse-next;
|
||||||
|
|
||||||
getWorkersOfType = type: lib.filterAttrs (_: w: w.type == type) cfg.workers.instances;
|
matrix-lib = (import ../lib.nix { inherit lib; });
|
||||||
isListenerType = type: listener: lib.lists.any (r: lib.lists.any (n: n == type) r.names) listener.resources;
|
|
||||||
firstListenerOfType = type: worker: lib.lists.findFirst (isListenerType type) (throw "No federation endpoint on receiver") worker.settings.worker_listeners;
|
workerUpstreams = matrix-lib.mapWorkersToUpstreamsByType cfg.workers.instances;
|
||||||
wAddressOfType = type: w: lib.lists.findFirst (_: true) (throw "No address in receiver") (firstListenerOfType type w).bind_addresses;
|
listenerUpstreams = matrix-lib.mapListenersToUpstreamsByType cfg.settings.listeners;
|
||||||
wPortOfType = type: w: (firstListenerOfType type w).port;
|
|
||||||
wSocketAddressOfType = type: w: "${wAddressOfType type w}:${builtins.toString (wPortOfType type w)}";
|
|
||||||
generateSocketAddresses = type: workers: lib.mapAttrsToList (_: w: "${wSocketAddressOfType type w}") workers;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = lib.mkIf cfg.enableNginx {
|
config = lib.mkIf cfg.enableNginx {
|
||||||
|
@ -138,24 +135,17 @@ in
|
||||||
'';
|
'';
|
||||||
|
|
||||||
services.nginx.upstreams.synapse_master.servers = let
|
services.nginx.upstreams.synapse_master.servers = let
|
||||||
isMainListener = l: isListenerType "client" l && isListenerType "federation" l;
|
mainListeners = builtins.intersectAttrs
|
||||||
firstMainListener = lib.findFirst isMainListener
|
(listenerUpstreams.client.http or { })
|
||||||
(throw "No catch-all listener configured") cfg.settings.listeners;
|
(listenerUpstreams.federation.http or { });
|
||||||
address = lib.findFirst (_: true) (throw "No address in main listener") firstMainListener.bind_addresses;
|
in
|
||||||
port = firstMainListener.port;
|
assert lib.assertMsg (mainListeners != { })
|
||||||
socketAddress = "${address}:${builtins.toString port}";
|
"No catch-all listener configured, or listener is not bound to an address";
|
||||||
in {
|
mainListeners;
|
||||||
"${socketAddress}" = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
services.nginx.upstreams.synapse_worker_federation = {
|
services.nginx.upstreams.synapse_worker_federation = {
|
||||||
servers = let
|
servers = workerUpstreams.fed-receiver.federation.http or config.services.nginx.upstreams.synapse_master.servers;
|
||||||
fedReceivers = getWorkersOfType "fed-receiver";
|
|
||||||
socketAddresses = generateSocketAddresses "federation" fedReceivers;
|
|
||||||
in if fedReceivers != { } then
|
|
||||||
lib.genAttrs socketAddresses (_: { })
|
|
||||||
else config.services.nginx.upstreams.synapse_master.servers;
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
ip_hash;
|
ip_hash;
|
||||||
'';
|
'';
|
||||||
|
@ -163,12 +153,7 @@ in
|
||||||
|
|
||||||
|
|
||||||
services.nginx.upstreams.synapse_worker_initial_sync = {
|
services.nginx.upstreams.synapse_worker_initial_sync = {
|
||||||
servers = let
|
servers = workerUpstreams.initial-sync.client.http or config.services.nginx.upstreams.synapse_master.servers;
|
||||||
initialSyncers = getWorkersOfType "initial-sync";
|
|
||||||
socketAddresses = generateSocketAddresses "client" initialSyncers;
|
|
||||||
in if initialSyncers != { } then
|
|
||||||
lib.genAttrs socketAddresses (_: { })
|
|
||||||
else config.services.nginx.upstreams.synapse_master.servers;
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
hash $mxid_localpart consistent;
|
hash $mxid_localpart consistent;
|
||||||
'';
|
'';
|
||||||
|
@ -176,12 +161,7 @@ in
|
||||||
|
|
||||||
|
|
||||||
services.nginx.upstreams.synapse_worker_normal_sync = {
|
services.nginx.upstreams.synapse_worker_normal_sync = {
|
||||||
servers = let
|
servers = workerUpstreams.normal-sync.client.http or config.services.nginx.upstreams.synapse_master.servers;
|
||||||
normalSyncers = getWorkersOfType "normal-sync";
|
|
||||||
socketAddresses = generateSocketAddresses "client" normalSyncers;
|
|
||||||
in if normalSyncers != { } then
|
|
||||||
lib.genAttrs socketAddresses (_: { })
|
|
||||||
else config.services.nginx.upstreams.synapse_master.servers;
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
hash $mxid_localpart consistent;
|
hash $mxid_localpart consistent;
|
||||||
'';
|
'';
|
||||||
|
@ -189,12 +169,7 @@ in
|
||||||
|
|
||||||
|
|
||||||
services.nginx.upstreams.synapse_worker_user-dir = {
|
services.nginx.upstreams.synapse_worker_user-dir = {
|
||||||
servers = let
|
servers = workerUpstreams.user-dir.client.http or config.services.nginx.upstreams.synapse_master.servers;
|
||||||
workers = getWorkersOfType "user-dir";
|
|
||||||
socketAddresses = generateSocketAddresses "client" workers;
|
|
||||||
in if workers != { } then
|
|
||||||
lib.genAttrs socketAddresses (_: { })
|
|
||||||
else config.services.nginx.upstreams.synapse_master.servers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."${cfg.public_baseurl}" = {
|
services.nginx.virtualHosts."${cfg.public_baseurl}" = {
|
||||||
|
|
Loading…
Reference in New Issue