mattermost service: init

+231
+2
nixos/modules/misc/ids.nix
··· 274 274 gocd-agent = 251; 275 275 gocd-server = 252; 276 276 terraria = 253; 277 + mattermost = 254; 277 278 278 279 # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! 279 280 ··· 518 519 gocd-agent = 251; 519 520 gocd-server = 252; 520 521 terraria = 253; 522 + mattermost = 254; 521 523 522 524 # When adding a gid, make sure it doesn't match an existing 523 525 # uid. Users and groups with the same name should have equal
+1
nixos/modules/module-list.nix
··· 463 463 ./services/ttys/agetty.nix 464 464 ./services/ttys/gpm.nix 465 465 ./services/ttys/kmscon.nix 466 + ./services/web-apps/mattermost.nix 466 467 ./services/web-apps/pump.io.nix 467 468 ./services/web-apps/tt-rss.nix 468 469 ./services/web-servers/apache-httpd/default.nix
+228
nixos/modules/services/web-apps/mattermost.nix
··· 1 + { config, pkgs, lib, ... }: 2 + 3 + with lib; 4 + 5 + let 6 + 7 + cfg = config.services.mattermost; 8 + 9 + defaultConfig = builtins.fromJSON (readFile "${pkgs.mattermost}/config/config.json"); 10 + 11 + mattermostConf = foldl recursiveUpdate defaultConfig 12 + [ { ServiceSettings.SiteURL = cfg.siteUrl; 13 + ServiceSettings.ListenAddress = cfg.listenAddress; 14 + TeamSettings.SiteName = cfg.siteName; 15 + SqlSettings.DriverName = "postgres"; 16 + SqlSettings.DataSource = "postgres://${cfg.localDatabaseUser}:${cfg.localDatabasePassword}@localhost:5432/${cfg.localDatabaseName}?sslmode=disable&connect_timeout=10"; 17 + } 18 + cfg.extraConfig 19 + ]; 20 + 21 + mattermostConfJSON = pkgs.writeText "mattermost-config-raw.json" (builtins.toJSON mattermostConf); 22 + 23 + in 24 + 25 + { 26 + options = { 27 + services.mattermost = { 28 + enable = mkEnableOption "Mattermost chat platform"; 29 + 30 + statePath = mkOption { 31 + type = types.str; 32 + default = "/var/lib/mattermost"; 33 + description = "Mattermost working directory"; 34 + }; 35 + 36 + siteUrl = mkOption { 37 + type = types.str; 38 + example = "https://chat.example.com"; 39 + description = '' 40 + URL this Mattermost instance is reachable under, without trailing slash." 41 + ''; 42 + }; 43 + 44 + siteName = mkOption { 45 + type = types.str; 46 + default = "Mattermost"; 47 + description = "Name of this Mattermost site."; 48 + }; 49 + 50 + listenAddress = mkOption { 51 + type = types.str; 52 + default = ":8065"; 53 + example = "[::1]:8065"; 54 + description = '' 55 + Address and port this Mattermost instance listens to. 56 + ''; 57 + }; 58 + 59 + mutableConfig = mkOption { 60 + type = types.bool; 61 + default = false; 62 + description = '' 63 + Whether the Mattermost config.json is writeable by Mattermost. 64 + 65 + Most of the settings can be edited in the system console of 66 + Mattermost if this option is enabled. A template config using 67 + the options specified in services.mattermost will be generated 68 + but won't be overwritten on changes or rebuilds. 69 + 70 + If this option is disabled, changes in the system console won't 71 + be possible (default). If an config.json is present, it will be 72 + overwritten! 73 + ''; 74 + }; 75 + 76 + extraConfig = mkOption { 77 + type = types.attrs; 78 + default = { }; 79 + description = '' 80 + Addtional configuration options as Nix attribute set in config.json schema. 81 + ''; 82 + }; 83 + 84 + localDatabaseCreate = mkOption { 85 + type = types.bool; 86 + default = true; 87 + description = '' 88 + Create a local PostgreSQL database for Mattermost automatically. 89 + ''; 90 + }; 91 + 92 + localDatabaseName = mkOption { 93 + type = types.str; 94 + default = "mattermost"; 95 + description = '' 96 + Local Mattermost database name. 97 + ''; 98 + }; 99 + 100 + localDatabaseUser = mkOption { 101 + type = types.str; 102 + default = "mattermost"; 103 + description = '' 104 + Local Mattermost database username. 105 + ''; 106 + }; 107 + 108 + localDatabasePassword = mkOption { 109 + type = types.str; 110 + default = "mmpgsecret"; 111 + description = '' 112 + Password for local Mattermost database user. 113 + ''; 114 + }; 115 + 116 + user = mkOption { 117 + type = types.str; 118 + default = "mattermost"; 119 + description = '' 120 + User which runs the Mattermost service. 121 + ''; 122 + }; 123 + 124 + group = mkOption { 125 + type = types.str; 126 + default = "mattermost"; 127 + description = '' 128 + Group which runs the Mattermost service. 129 + ''; 130 + }; 131 + 132 + matterircd = { 133 + enable = mkEnableOption "Mattermost IRC bridge"; 134 + parameters = mkOption { 135 + type = types.listOf types.str; 136 + default = [ ]; 137 + example = [ "-mmserver chat.example.com" "-bind [::]:6667" ]; 138 + description = '' 139 + Set commandline parameters to pass to matterircd. See 140 + https://github.com/42wim/matterircd#usage for more information. 141 + ''; 142 + }; 143 + }; 144 + }; 145 + }; 146 + 147 + config = mkMerge [ 148 + (mkIf cfg.enable { 149 + users.extraUsers = optionalAttrs (cfg.user == "mattermost") (singleton { 150 + name = "mattermost"; 151 + group = cfg.group; 152 + uid = config.ids.uids.mattermost; 153 + home = cfg.statePath; 154 + }); 155 + 156 + users.extraGroups = optionalAttrs (cfg.group == "mattermost") (singleton { 157 + name = "mattermost"; 158 + gid = config.ids.gids.mattermost; 159 + }); 160 + 161 + services.postgresql.enable = cfg.localDatabaseCreate; 162 + 163 + # The systemd service will fail to execute the preStart hook 164 + # if the WorkingDirectory does not exist 165 + system.activationScripts.mattermost = '' 166 + mkdir -p ${cfg.statePath} 167 + ''; 168 + 169 + systemd.services.mattermost = { 170 + description = "Mattermost chat platform service"; 171 + wantedBy = [ "multi-user.target" ]; 172 + after = [ "network.target" "postgresql.service" ]; 173 + 174 + preStart = '' 175 + mkdir -p ${cfg.statePath}/{data,config,logs} 176 + ln -sf ${pkgs.mattermost}/{bin,fonts,i18n,templates,webapp} ${cfg.statePath} 177 + '' + lib.optionalString (!cfg.mutableConfig) '' 178 + ln -sf ${mattermostConfJSON} ${cfg.statePath}/config/config.json 179 + '' + lib.optionalString cfg.mutableConfig '' 180 + if ! test -e "${cfg.statePath}/config/.initial-created"; then 181 + rm -f ${cfg.statePath}/config/config.json 182 + cp ${mattermostConfJSON} ${cfg.statePath}/config/config.json 183 + touch ${cfg.statePath}/config/.initial-created 184 + fi 185 + '' + lib.optionalString cfg.localDatabaseCreate '' 186 + if ! test -e "${cfg.statePath}/.db-created"; then 187 + ${config.services.postgresql.package}/bin/psql postgres -c \ 188 + "CREATE ROLE ${cfg.localDatabaseUser} WITH LOGIN NOCREATEDB NOCREATEROLE NOCREATEUSER ENCRYPTED PASSWORD '${cfg.localDatabasePassword}'" 189 + ${config.services.postgresql.package}/bin/createdb \ 190 + --owner ${cfg.localDatabaseUser} ${cfg.localDatabaseName} 191 + touch ${cfg.statePath}/.db-created 192 + fi 193 + '' + '' 194 + chown ${cfg.user}:${cfg.group} -R ${cfg.statePath} 195 + chmod u+rw,g+r,o-rwx -R ${cfg.statePath} 196 + ''; 197 + 198 + serviceConfig = { 199 + PermissionsStartOnly = true; 200 + User = cfg.user; 201 + Group = cfg.group; 202 + ExecStart = "${pkgs.mattermost}/bin/mattermost-platform"; 203 + WorkingDirectory = "${cfg.statePath}"; 204 + PrivateTmp = true; 205 + Restart = "always"; 206 + RestartSec = "10"; 207 + LimitNOFILE = "49152"; 208 + }; 209 + }; 210 + }) 211 + (mkIf cfg.matterircd.enable { 212 + systemd.services.matterircd = { 213 + description = "Mattermost IRC bridge service"; 214 + wantedBy = [ "multi-user.target" ]; 215 + serviceConfig = { 216 + User = "nobody"; 217 + Group = "nogroup"; 218 + ExecStart = "${pkgs.matterircd.bin}/bin/matterircd ${concatStringsSep " " cfg.matterircd.parameters}"; 219 + WorkingDirectory = "/tmp"; 220 + PrivateTmp = true; 221 + Restart = "always"; 222 + RestartSec = "5"; 223 + }; 224 + }; 225 + }) 226 + ]; 227 + } 228 +