at 25.11-pre 6.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 utils, 6 ... 7}: 8 9let 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 ); 28in 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:password@mydomain.com: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}