Skip to content

Commit 810f3b8

Browse files
authored
nixos/synapse-auto-compressor: init (NixOS#383168)
2 parents 713ae59 + 0b48303 commit 810f3b8

File tree

3 files changed

+167
-0
lines changed

3 files changed

+167
-0
lines changed

nixos/doc/manual/release-notes/rl-2505.section.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@
155155

156156
- [PDS](https://github.com/bluesky-social/pds), Personal Data Server for [bsky](https://bsky.social/). Available as [services.pds](option.html#opt-services.pds).
157157

158+
- [synapse-auto-compressor](https://github.com/matrix-org/rust-synapse-compress-state?tab=readme-ov-file#automated-tool-synapse_auto_compressor), a rust-based matrix-synapse state compressor for postgresql. Available as [services.synapse-auto-compressor](#opt-services.synapse-auto-compressor.enable).
159+
158160
- [mqtt-exporter](https://github.com/kpetremann/mqtt-exporter/), a Prometheus exporter for exposing messages from MQTT. Available as [services.prometheus.exporters.mqtt](#opt-services.prometheus.exporters.mqtt.enable).
159161

160162
- [nvidia-gpu](https://github.com/utkuozdemir/nvidia_gpu_exporter), a Prometheus exporter that scrapes `nvidia-smi` for GPU metrics. Available as [services.prometheus.exporters.nvidia-gpu](#opt-services.prometheus.exporters.nvidia-gpu.enable).

nixos/modules/module-list.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,7 @@
752752
./services/matrix/mx-puppet-discord.nix
753753
./services/matrix/pantalaimon.nix
754754
./services/matrix/synapse.nix
755+
./services/matrix/synapse-auto-compressor.nix
755756
./services/misc/airsonic.nix
756757
./services/misc/amazon-ssm-agent.nix
757758
./services/misc/ananicy.nix
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
{
2+
config,
3+
lib,
4+
pkgs,
5+
utils,
6+
...
7+
}:
8+
9+
let
10+
cfg = config.services.synapse-auto-compressor;
11+
synapseConfig = config.services.matrix-synapse;
12+
postgresEnabled = config.services.postgresql.enable;
13+
synapseUsesPostgresql = synapseConfig.settings.database.name == "psycopg2";
14+
synapseUsesLocalPostgresql =
15+
let
16+
args = synapseConfig.settings.database.args;
17+
in
18+
synapseUsesPostgresql
19+
&& postgresEnabled
20+
&& (
21+
!(args ? host)
22+
|| (builtins.elem args.host [
23+
"localhost"
24+
"127.0.0.1"
25+
"::1"
26+
])
27+
);
28+
in
29+
{
30+
options = {
31+
services.synapse-auto-compressor = {
32+
enable = lib.mkEnableOption "synapse-auto-compressor";
33+
package = lib.mkPackageOption pkgs "rust-synapse-state-compress" { };
34+
postgresUrl = lib.mkOption {
35+
default =
36+
let
37+
args = synapseConfig.settings.database.args;
38+
in
39+
if synapseConfig.enable then
40+
''postgresql://${args.user}${lib.optionalString (args ? password) (":" + args.password)}@${
41+
lib.escapeURL (if (args ? host) then args.host else "/run/postgresql")
42+
}${lib.optionalString (args ? port) (":" + args.port)}/${args.database}''
43+
else
44+
null;
45+
defaultText = lib.literalExpression ''
46+
let
47+
synapseConfig = config.services.matrix-synapse;
48+
args = synapseConfig.settings.database.args;
49+
in
50+
if synapseConfig.enable then
51+
'''postgresql://''${args.user}''${lib.optionalString (args ? password) (":" + args.password)}@''${
52+
lib.escapeURL (if (args ? host) then args.host else "/run/postgresql")
53+
}''${lib.optionalString (args ? port) (":" + args.port)}''${args.database}'''
54+
else
55+
null;
56+
'';
57+
type = lib.types.str;
58+
example = "postgresql://username:[email protected]:port/database";
59+
description = ''
60+
Connection string to postgresql in the
61+
[rust `postgres` crate config format](https://docs.rs/postgres/latest/postgres/config/struct.Config.html).
62+
The module will attempt to build a URL-style connection string out of the `services.matrix-synapse.settings.database.args`
63+
if a local synapse is enabled.
64+
'';
65+
};
66+
startAt = lib.mkOption {
67+
default = "weekly";
68+
type = with lib.types; either str (listOf str);
69+
description = "How often to run this service in systemd calendar syntax (see {manpage}`systemd.time(7)`)";
70+
example = "daily";
71+
};
72+
73+
settings = {
74+
chunk_size = lib.mkOption {
75+
type = lib.types.int;
76+
default = 500;
77+
description = ''
78+
The number of state groups to work on at once. All of the entries from `state_groups_state` are requested
79+
from the database for state groups that are worked on. Therefore small chunk sizes may be needed on
80+
machines with low memory.
81+
82+
Note: if the compressor fails to find space savings on the chunk as a whole
83+
(which may well happen in rooms with lots of backfill in) then the entire chunk is skipped.
84+
'';
85+
};
86+
chunks_to_compress = lib.mkOption {
87+
type = lib.types.int;
88+
default = 100;
89+
description = ''
90+
`chunks_to_compress` chunks of size `chunk_size` will be compressed. The higher this number is set to,
91+
the longer the compressor will run for.
92+
'';
93+
};
94+
levels = lib.mkOption {
95+
type = with lib.types; listOf int;
96+
default = [
97+
100
98+
50
99+
25
100+
];
101+
description = ''
102+
Sizes of each new level in the compression algorithm, as a comma-separated list. The first entry in
103+
the list is for the lowest, most granular level, with each subsequent entry being for the next highest
104+
level. The number of entries in the list determines the number of levels that will be used. The sum of
105+
the sizes of the levels affects the performance of fetching the state from the database, as the sum of
106+
the sizes is the upper bound on the number of iterations needed to fetch a given set of state.
107+
'';
108+
};
109+
};
110+
};
111+
};
112+
config = lib.mkIf cfg.enable {
113+
assertions = [
114+
{
115+
assertion = synapseConfig.enable && synapseUsesPostgresql;
116+
message = "`services.synapse-auto-compressor` requires local synapse to use postgresql as a database backend";
117+
}
118+
];
119+
systemd.services.synapse-auto-compressor = {
120+
description = "synapse-auto-compressor";
121+
requires = lib.optionals synapseUsesLocalPostgresql [
122+
"postgresql.service"
123+
];
124+
inherit (cfg) startAt;
125+
serviceConfig = {
126+
Type = "oneshot";
127+
DynamicUser = true;
128+
User = "matrix-synapse";
129+
PrivateTmp = true;
130+
ExecStart = utils.escapeSystemdExecArgs [
131+
"${cfg.package}/bin/synapse_auto_compressor"
132+
"-p"
133+
cfg.postgresUrl
134+
"-c"
135+
cfg.settings.chunk_size
136+
"-n"
137+
cfg.settings.chunks_to_compress
138+
"-l"
139+
(lib.concatStringsSep "," (builtins.map builtins.toString cfg.settings.levels))
140+
];
141+
LockPersonality = true;
142+
MemoryDenyWriteExecute = true;
143+
NoNewPrivileges = true;
144+
PrivateDevices = true;
145+
PrivateMounts = true;
146+
PrivateUsers = true;
147+
RemoveIPC = true;
148+
RestrictNamespaces = true;
149+
RestrictRealtime = true;
150+
RestrictSUIDSGID = true;
151+
ProcSubset = "pid";
152+
ProtectProc = "invisible";
153+
ProtectSystem = "strict";
154+
ProtectHome = true;
155+
ProtectHostname = true;
156+
ProtectClock = true;
157+
ProtectKernelTunables = true;
158+
ProtectKernelModules = true;
159+
ProtectKernelLogs = true;
160+
ProtectControlGroups = true;
161+
};
162+
};
163+
};
164+
}

0 commit comments

Comments
 (0)