···
9
+
inherit (lib.strings)
20
+
inherit (lib.meta) getExe;
22
+
inherit (lib.lists) singleton;
24
+
inherit (lib.attrsets) mapAttrsToList recursiveUpdate optionalAttrs;
26
+
inherit (lib.options) mkOption mkPackageOption mkEnableOption;
28
+
inherit (lib.modules)
29
+
mkRenamedOptionModule
35
+
inherit (lib.trivial) warnIf throwIf;
37
+
inherit (lib) types;
cfg = config.services.mattermost;
14
-
database = "postgres://${cfg.localDatabaseUser}:${cfg.localDatabasePassword}@localhost:5432/${cfg.localDatabaseName}?sslmode=disable&connect_timeout=10";
41
+
# The directory to store mutable data within dataDir.
42
+
mutableDataDir = "${cfg.dataDir}/data";
16
-
postgresPackage = config.services.postgresql.package;
44
+
# The plugin directory. Note that this is the *post-unpack* plugin directory,
45
+
# since Mattermost unpacks plugins to put them there. (Hence, mutable data.)
46
+
pluginDir = "${mutableDataDir}/plugins";
48
+
# Mattermost uses this as a staging directory to unpack plugins, among possibly other things.
49
+
# Ensure that it's inside mutableDataDir since it can get rather large.
50
+
tempDir = "${mutableDataDir}/tmp";
52
+
# Creates a database URI.
20
-
statePath ? cfg.statePath,
21
-
localDatabaseUser ? cfg.localDatabaseUser,
22
-
localDatabasePassword ? cfg.localDatabasePassword,
23
-
localDatabaseName ? cfg.localDatabaseName,
58
+
escapeUserAndPassword ? true,
27
-
if ! test -e ${escapeShellArg "${statePath}/.db-created"}; then
28
-
${lib.optionalString useSudo "${pkgs.sudo}/bin/sudo -u ${escapeShellArg config.services.postgresql.superUser} \\"}
29
-
${postgresPackage}/bin/psql postgres -c \
30
-
"CREATE ROLE ${localDatabaseUser} WITH LOGIN NOCREATEDB NOCREATEROLE ENCRYPTED PASSWORD '${localDatabasePassword}'"
31
-
${lib.optionalString useSudo "${pkgs.sudo}/bin/sudo -u ${escapeShellArg config.services.postgresql.superUser} \\"}
32
-
${postgresPackage}/bin/createdb \
33
-
--owner ${escapeShellArg localDatabaseUser} ${escapeShellArg localDatabaseName}
34
-
touch ${escapeShellArg "${statePath}/.db-created"}
66
+
nullToEmpty = val: if val == null then "" else toString val;
68
+
# Converts a list of URI attrs to a query string.
69
+
toQuery = mapAttrsToList (
70
+
name: value: if value == null then null else (escapeURL name) + "=" + (escapeURL (toString value))
73
+
schemePart = if scheme == null then "" else "${escapeURL scheme}://";
76
+
realUser = if escapeUserAndPassword then escapeURL user else user;
77
+
realPassword = if escapeUserAndPassword then escapeURL password else password;
79
+
if user == null && password == null then
81
+
else if user != null && password != null then
82
+
"${realUser}:${realPassword}"
83
+
else if user != null then
86
+
throw "Either user or username and password must be provided";
89
+
realHost = if escapeHost then escapeURL (nullToEmpty host) else nullToEmpty host;
91
+
if userPart == "" then realHost else "@" + realHost;
92
+
portPart = if port == null then "" else ":" + (toString port);
93
+
pathPart = if path == null then "" else "/" + path;
94
+
queryPart = if query == { } then "" else "?" + concatStringsSep "&" (toQuery query);
96
+
schemePart + userPart + hostPart + portPart + pathPart + queryPart;
100
+
hostIsPath = hasInfix "/" cfg.database.host;
102
+
if cfg.database.driver == "postgres" then
103
+
if cfg.database.peerAuth then
105
+
scheme = cfg.database.driver;
106
+
inherit (cfg.database) user;
107
+
path = escapeURL cfg.database.name;
109
+
host = cfg.database.socketPath;
110
+
} // cfg.database.extraConnectionOptions;
114
+
scheme = cfg.database.driver;
115
+
inherit (cfg.database) user password;
116
+
host = if hostIsPath then null else cfg.database.host;
117
+
port = if hostIsPath then null else cfg.database.port;
118
+
path = escapeURL cfg.database.name;
120
+
optionalAttrs hostIsPath { host = cfg.database.host; } // cfg.database.extraConnectionOptions;
122
+
else if cfg.database.driver == "mysql" then
123
+
if cfg.database.peerAuth then
126
+
inherit (cfg.database) user;
127
+
escapeUserAndPassword = false;
128
+
host = "unix(${cfg.database.socketPath})";
129
+
escapeHost = false;
130
+
path = escapeURL cfg.database.name;
131
+
query = cfg.database.extraConnectionOptions;
136
+
inherit (cfg.database) user password;
137
+
escapeUserAndPassword = false;
140
+
"unix(${cfg.database.host})"
142
+
"tcp(${cfg.database.host}:${toString cfg.database.port})";
143
+
escapeHost = false;
144
+
path = escapeURL cfg.database.name;
145
+
query = cfg.database.extraConnectionOptions;
148
+
throw "Invalid database driver: ${cfg.database.driver}";
mattermostPluginDerivations =
···
name = "${cfg.package.name}-plugins";
63
-
nativeBuildInputs = [
65
-
] ++ mattermostPluginDerivations;
175
+
nativeBuildInputs = [ autoPatchelfHook ] ++ mattermostPluginDerivations;
176
+
buildInputs = [ cfg.package ];
70
-
mkdir -p $out/data/plugins
escapeShellArgs (map (plugin: "${plugin}/share/plugin.tar.gz") mattermostPluginDerivations)
for plugin in "''${plugins[@]}"; do
75
-
hash="$(sha256sum "$plugin" | cut -d' ' -f1)"
183
+
hash="$(sha256sum "$plugin" | awk '{print $1}')"
tar -C "$hash" -xzf "$plugin"
79
-
GZIP_OPT=-9 tar -C "$hash" -cvzf "$out/data/plugins/$hash.tar.gz" .
187
+
GZIP_OPT=-9 tar -C "$hash" -cvzf "$out/$hash.tar.gz" .
···
mattermostConfWithoutPlugins = recursiveUpdate {
92
-
ServiceSettings.SiteURL = cfg.siteUrl;
93
-
ServiceSettings.ListenAddress = cfg.listenAddress;
200
+
ServiceSettings = {
201
+
SiteURL = cfg.siteUrl;
202
+
ListenAddress = "${cfg.host}:${toString cfg.port}";
203
+
LocalModeSocketLocation = cfg.socket.path;
204
+
EnableLocalMode = cfg.socket.enable;
TeamSettings.SiteName = cfg.siteName;
95
-
SqlSettings.DriverName = "postgres";
96
-
SqlSettings.DataSource = database;
97
-
PluginSettings.Directory = "${cfg.statePath}/plugins/server";
98
-
PluginSettings.ClientDirectory = "${cfg.statePath}/plugins/client";
207
+
SqlSettings.DriverName = cfg.database.driver;
208
+
SqlSettings.DataSource =
209
+
if cfg.database.fromEnvironment then
212
+
warnIf (!cfg.database.peerAuth && cfg.database.password != null) ''
213
+
Database password is set in Mattermost config! This password will end up in the Nix store.
215
+
You may be able to simply set the following, if the database is on the same host
216
+
and peer authentication is enabled:
218
+
services.mattermost.database.peerAuth = true;
220
+
Note that this is the default if you set system.stateVersion to 25.05 or later
221
+
and the database host is localhost.
223
+
Alternatively, you can write the following to ${
224
+
if cfg.environmentFile == null then "your environment file" else cfg.environmentFile
227
+
MM_SQLSETTINGS_DATASOURCE=${database}
229
+
Then set the following options:
230
+
services.mattermost.environmentFile = "<your environment file>";
231
+
services.mattermost.database.fromEnvironment = true;
233
+
FileSettings.Directory = cfg.dataDir;
234
+
PluginSettings.Directory = "${pluginDir}/server";
235
+
PluginSettings.ClientDirectory = "${pluginDir}/client";
236
+
LogSettings.FileLocation = cfg.logDir;
mattermostConf = recursiveUpdate mattermostConfWithoutPlugins (
102
-
lib.optionalAttrs (mattermostPlugins != null) {
240
+
if mattermostPlugins == null then
mattermostConfJSON = pkgs.writeText "mattermost-config.json" (builtins.toJSON mattermostConf);
255
+
(mkRenamedOptionModule
267
+
(mkRenamedOptionModule
271
+
"localDatabaseCreate"
280
+
(mkRenamedOptionModule
284
+
"localDatabasePassword"
293
+
(mkRenamedOptionModule
297
+
"localDatabaseUser"
306
+
(mkRenamedOptionModule
310
+
"localDatabaseName"
319
+
(mkRenamedOptionModule
331
+
(mkRenamedOptionModule
enable = mkEnableOption "Mattermost chat server";
package = mkPackageOption pkgs "mattermost" { };
120
-
statePath = mkOption {
122
-
default = "/var/lib/mattermost";
123
-
description = "Mattermost working directory";
···
description = "Name of this Mattermost site.";
140
-
listenAddress = mkOption {
143
-
example = "[::1]:8065";
367
+
default = "127.0.0.1";
368
+
example = "0.0.0.0";
370
+
Host or address that this Mattermost instance listens on.
378
+
Port for Mattermost server to listen on.
382
+
dataDir = mkOption {
384
+
default = "/var/lib/mattermost";
386
+
Mattermost working directory.
391
+
enable = mkEnableOption "Mattermost control socket";
395
+
default = "${cfg.dataDir}/mattermost.sock";
396
+
defaultText = ''''${config.mattermost.dataDir}/mattermost.sock'';
398
+
Default location for the Mattermost control socket used by `mmctl`.
402
+
export = mkEnableOption "Export socket control to system environment variables";
405
+
logDir = mkOption {
408
+
if versionAtLeast config.system.stateVersion "25.05" then
409
+
"/var/log/mattermost"
411
+
"${cfg.dataDir}/logs";
413
+
if versionAtLeast config.system.stateVersion "25.05" then "/var/log/mattermost"
414
+
else "''${config.services.mattermost.dataDir}/logs";
417
+
Mattermost log directory.
421
+
configDir = mkOption {
424
+
if versionAtLeast config.system.stateVersion "25.05" then
427
+
"${cfg.dataDir}/config";
429
+
if versionAtLeast config.system.stateVersion "25.05" then
432
+
"''${config.services.mattermost.dataDir}/config";
145
-
Address and port this Mattermost instance listens to.
435
+
Mattermost config directory.
···
176
-
extraConfig = mkOption {
177
-
type = types.attrs;
180
-
Additional configuration options as Nix attribute set in config.json schema.
185
-
type = types.listOf (
467
+
type = with types; listOf (either path package);
example = "[ ./com.github.moussetc.mattermost.plugin.giphy-2.0.0.tar.gz ]";
···
477
+
environment = mkOption {
478
+
type = with types; attrsOf (either int str);
481
+
Extra environment variables to export to the Mattermost process, in the systemd unit.
484
+
MM_SERVICESETTINGS_SITEURL = "http://example.com";
environmentFile = mkOption {
200
-
type = types.nullOr types.path;
489
+
type = with types; nullOr path;
Environment file (see {manpage}`systemd.exec(5)`
"EnvironmentFile=" section for the syntax) which sets config options
205
-
for mattermost (see [the mattermost documentation](https://docs.mattermost.com/configure/configuration-settings.html#environment-variables)).
494
+
for mattermost (see [the Mattermost documentation](https://docs.mattermost.com/configure/configuration-settings.html#environment-variables)).
Settings defined in the environment file will overwrite settings
set via nix or via the {option}`services.mattermost.extraConfig`
···
216
-
localDatabaseCreate = mkOption {
220
-
Create a local PostgreSQL database for Mattermost automatically.
506
+
driver = mkOption {
507
+
type = types.enum [
511
+
default = "postgres";
513
+
The database driver to use (Postgres or MySQL).
224
-
localDatabaseName = mkOption {
226
-
default = "mattermost";
228
-
Local Mattermost database name.
517
+
create = mkOption {
521
+
Create a local PostgreSQL or MySQL database for Mattermost automatically.
232
-
localDatabaseUser = mkOption {
234
-
default = "mattermost";
236
-
Local Mattermost database username.
525
+
peerAuth = mkOption {
527
+
default = versionAtLeast config.system.stateVersion "25.05" && cfg.database.host == "localhost";
529
+
versionAtLeast config.system.stateVersion "25.05" && config.services.mattermost.database.host == "localhost"
532
+
If set, will use peer auth instead of connecting to a Postgres server.
533
+
Use services.mattermost.database.socketPath to configure the socket path.
537
+
socketPath = mkOption {
540
+
if cfg.database.driver == "postgres" then "/run/postgresql" else "/run/mysqld/mysqld.sock";
542
+
if config.services.mattermost.database.driver == "postgres" then "/run/postgresql" else "/run/mysqld/mysqld.sock";
545
+
The database (Postgres or MySQL) socket path.
549
+
fromEnvironment = mkOption {
553
+
Use services.mattermost.environmentFile to configure the database instead of writing the database URI
554
+
to the Nix store. Useful if you use password authentication with peerAuth set to false.
560
+
default = "mattermost";
562
+
Local Mattermost database name.
568
+
default = "localhost";
569
+
example = "127.0.0.1";
571
+
Host to use for the database. Can also be set to a path if you'd like to connect
572
+
to a socket using a username and password.
578
+
default = if cfg.database.driver == "postgres" then 5432 else 3306;
580
+
if config.services.mattermost.database.type == "postgres" then 5432 else 3306
584
+
Port to use for the database.
590
+
default = "mattermost";
592
+
Local Mattermost database username.
596
+
password = mkOption {
598
+
default = "mmpgsecret";
600
+
Password for local Mattermost database user. If set and peerAuth is not true,
601
+
will cause a warning nagging you to use environmentFile instead since it will
602
+
end up in the Nix store.
240
-
localDatabasePassword = mkOption {
242
-
default = "mmpgsecret";
244
-
Password for local Mattermost database user.
606
+
extraConnectionOptions = mkOption {
607
+
type = with types; attrsOf (either int str);
609
+
if cfg.database.driver == "postgres" then
611
+
sslmode = "disable";
612
+
connect_timeout = 30;
614
+
else if cfg.database.driver == "mysql" then
616
+
charset = "utf8mb4,utf8";
617
+
writeTimeout = "30s";
618
+
readTimeout = "30s";
621
+
throw "Invalid database driver ${cfg.database.driver}";
623
+
if config.mattermost.database.driver == "postgres" then
625
+
sslmode = "disable";
626
+
connect_timeout = 30;
628
+
else if config.mattermost.database.driver == "mysql" then
630
+
charset = "utf8mb4,utf8";
631
+
writeTimeout = "30s";
632
+
readTimeout = "30s";
635
+
throw "Invalid database driver";
638
+
Extra options that are placed in the connection URI's query parameters.
···
659
+
settings = mkOption {
660
+
type = types.attrs;
663
+
Additional configuration options as Nix attribute set in config.json schema.
enable = mkEnableOption "Mattermost IRC bridge";
package = mkPackageOption pkgs "matterircd" { };
···
285
-
users.users = optionalAttrs (cfg.user == "mattermost") {
288
-
uid = config.ids.uids.mattermost;
289
-
home = cfg.statePath;
691
+
uid = mkIf (cfg.user == "mattermost") config.ids.uids.mattermost;
692
+
home = cfg.dataDir;
693
+
isSystemUser = true;
694
+
packages = [ cfg.package ];
293
-
users.groups = optionalAttrs (cfg.group == "mattermost") {
294
-
mattermost.gid = config.ids.gids.mattermost;
700
+
gid = mkIf (cfg.group == "mattermost") config.ids.gids.mattermost;
297
-
services.postgresql.enable = cfg.localDatabaseCreate;
704
+
services.postgresql = mkIf (cfg.database.driver == "postgres" && cfg.database.create) {
706
+
ensureDatabases = singleton cfg.database.name;
707
+
ensureUsers = singleton {
710
+
(cfg.database.peerAuth && (cfg.database.user != cfg.user || cfg.database.name != cfg.database.user))
712
+
Mattermost database peer auth is enabled and the user, database user, or database name mismatch.
713
+
Peer authentication will not work.
716
+
ensureDBOwnership = true;
299
-
# The systemd service will fail to execute the preStart hook
300
-
# if the WorkingDirectory does not exist
301
-
systemd.tmpfiles.settings."10-mattermost".${cfg.statePath}.d = { };
720
+
services.mysql = mkIf (cfg.database.driver == "mysql" && cfg.database.create) {
722
+
package = mkDefault pkgs.mariadb;
723
+
ensureDatabases = singleton cfg.database.name;
724
+
ensureUsers = singleton {
725
+
name = cfg.database.user;
726
+
ensurePermissions = {
727
+
"${cfg.database.name}.*" = "ALL PRIVILEGES";
732
+
collation-server = mkDefault "utf8mb4_general_ci";
733
+
init-connect = mkDefault "SET NAMES utf8mb4";
734
+
character-set-server = mkDefault "utf8mb4";
736
+
mysqld_safe = mysqld;
303
-
systemd.services.mattermost = {
741
+
variables = mkIf cfg.socket.export {
742
+
MMCTL_LOCAL = "true";
743
+
MMCTL_LOCAL_SOCKET_PATH = cfg.socket.path;
747
+
systemd.tmpfiles.rules =
749
+
"d ${cfg.dataDir} 0750 ${cfg.user} ${cfg.group} - -"
750
+
"d ${cfg.logDir} 0750 ${cfg.user} ${cfg.group} - -"
751
+
"d ${cfg.configDir} 0750 ${cfg.user} ${cfg.group} - -"
752
+
"d ${mutableDataDir} 0750 ${cfg.user} ${cfg.group} - -"
754
+
# Make sure tempDir exists and is not a symlink.
755
+
"R- ${tempDir} - - - - -"
756
+
"d= ${tempDir} 0750 ${cfg.user} ${cfg.group} - -"
758
+
# Ensure that pluginDir is a directory, as it could be a symlink on prior versions.
759
+
"r- ${pluginDir} - - - - -"
760
+
"d= ${pluginDir} 0750 ${cfg.user} ${cfg.group} - -"
762
+
# Ensure that the plugin directories exist.
763
+
"d= ${mattermostConf.PluginSettings.Directory} 0750 ${cfg.user} ${cfg.group} - -"
764
+
"d= ${mattermostConf.PluginSettings.ClientDirectory} 0750 ${cfg.user} ${cfg.group} - -"
766
+
# Link in some of the immutable data directories.
767
+
"L+ ${cfg.dataDir}/bin - - - - ${cfg.package}/bin"
768
+
"L+ ${cfg.dataDir}/fonts - - - - ${cfg.package}/fonts"
769
+
"L+ ${cfg.dataDir}/i18n - - - - ${cfg.package}/i18n"
770
+
"L+ ${cfg.dataDir}/templates - - - - ${cfg.package}/templates"
771
+
"L+ ${cfg.dataDir}/client - - - - ${cfg.package}/client"
774
+
if mattermostPlugins == null then
775
+
# Create the plugin tarball directory if it's a symlink.
777
+
"r- ${cfg.dataDir}/plugins - - - - -"
778
+
"d= ${cfg.dataDir}/plugins 0750 ${cfg.user} ${cfg.group} - -"
781
+
# Symlink the plugin tarball directory, removing anything existing.
782
+
[ "L+ ${cfg.dataDir}/plugins - - - - ${mattermostPlugins}" ]
785
+
systemd.services.mattermost = rec {
description = "Mattermost chat service";
wantedBy = [ "multi-user.target" ];
308
-
"postgresql.service"
789
+
[ "network.target" ]
790
+
(mkIf (cfg.database.driver == "postgres" && cfg.database.create) [ "postgresql.service" ])
791
+
(mkIf (cfg.database.driver == "mysql" && cfg.database.create) [ "mysql.service" ])
795
+
environment = mkMerge [
797
+
# Use tempDir as this can get rather large, especially if Mattermost unpacks a large number of plugins.
313
-
mkdir -p "${cfg.statePath}"/{data,config,logs,plugins}
314
-
mkdir -p "${cfg.statePath}/plugins"/{client,server}
315
-
ln -sf ${cfg.package}/{bin,fonts,i18n,templates,client} "${cfg.statePath}"
805
+
dataDir=${escapeShellArg cfg.dataDir}
806
+
configDir=${escapeShellArg cfg.configDir}
807
+
logDir=${escapeShellArg cfg.logDir}
808
+
package=${escapeShellArg cfg.package}
809
+
nixConfig=${escapeShellArg mattermostConfJSON}
317
-
+ lib.optionalString (mattermostPlugins != null) ''
318
-
rm -rf "${cfg.statePath}/data/plugins"
319
-
ln -sf ${mattermostPlugins}/data/plugins "${cfg.statePath}/data"
811
+
+ optionalString (versionAtLeast config.system.stateVersion "25.05") ''
812
+
# Migrate configs in the pre-25.05 directory structure.
813
+
oldConfig="$dataDir/config/config.json"
814
+
newConfig="$configDir/config.json"
815
+
if [ "$oldConfig" != "$newConfig" ] && [ -f "$oldConfig" ] && [ ! -f "$newConfig" ]; then
816
+
# Migrate the legacy config location to the new config location
817
+
echo "Moving legacy config at $oldConfig to $newConfig" >&2
818
+
mkdir -p "$configDir"
819
+
mv "$oldConfig" "$newConfig"
820
+
touch "$configDir/.initial-created"
824
+
oldLogs="$dataDir/logs"
826
+
if [ "$oldLogs" != "$newLogs" ] && [ -d "$oldLogs" ]; then
827
+
# Migrate the legacy log location to the new log location.
828
+
# Allow this to fail if there aren't any logs to move.
829
+
echo "Moving legacy logs at $oldLogs to $newLogs" >&2
830
+
mkdir -p "$newLogs"
831
+
mv "$oldLogs"/* "$newLogs" || true
321
-
+ lib.optionalString (!cfg.mutableConfig) ''
322
-
rm -f "${cfg.statePath}/config/config.json"
323
-
${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${cfg.package}/config/config.json ${mattermostConfJSON} > "${cfg.statePath}/config/config.json"
834
+
+ optionalString (!cfg.mutableConfig) ''
835
+
${getExe pkgs.jq} -s '.[0] * .[1]' "$package/config/config.json" "$nixConfig" > "$configDir/config.json"
325
-
+ lib.optionalString cfg.mutableConfig ''
326
-
if ! test -e "${cfg.statePath}/config/.initial-created"; then
327
-
rm -f ${cfg.statePath}/config/config.json
328
-
${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${cfg.package}/config/config.json ${mattermostConfJSON} > "${cfg.statePath}/config/config.json"
329
-
touch "${cfg.statePath}/config/.initial-created"
837
+
+ optionalString cfg.mutableConfig ''
838
+
if [ ! -e "$configDir/.initial-created" ]; then
839
+
${getExe pkgs.jq} -s '.[0] * .[1]' "$package/config/config.json" "$nixConfig" > "$configDir/config.json"
840
+
touch "$configDir/.initial-created"
332
-
+ lib.optionalString (cfg.mutableConfig && cfg.preferNixConfig) ''
333
-
new_config="$(${pkgs.jq}/bin/jq -s '.[0] * .[1]' "${cfg.statePath}/config/config.json" ${mattermostConfJSON})"
843
+
+ optionalString (cfg.mutableConfig && cfg.preferNixConfig) ''
844
+
echo "$(${getExe pkgs.jq} -s '.[0] * .[1]' "$configDir/config.json" "$nixConfig")" > "$configDir/config.json"
847
+
serviceConfig = mkMerge [
851
+
ExecStart = "${getExe cfg.package} --config ${cfg.configDir}/config.json";
858
+
Restart = "always";
860
+
LimitNOFILE = 49152;
861
+
LockPersonality = true;
862
+
NoNewPrivileges = true;
863
+
PrivateDevices = true;
865
+
PrivateUsers = true;
866
+
ProtectClock = true;
867
+
ProtectControlGroups = true;
868
+
ProtectHome = true;
869
+
ProtectHostname = true;
870
+
ProtectKernelLogs = true;
871
+
ProtectKernelModules = true;
872
+
ProtectKernelTunables = true;
873
+
ProtectProc = "invisible";
874
+
ProtectSystem = "strict";
875
+
RestrictNamespaces = true;
876
+
RestrictSUIDSGID = true;
877
+
EnvironmentFile = cfg.environmentFile;
878
+
WorkingDirectory = cfg.dataDir;
880
+
(mkIf (cfg.dataDir == "/var/lib/mattermost") {
881
+
StateDirectory = baseNameOf cfg.dataDir;
882
+
StateDirectoryMode = "0750";
884
+
(mkIf (cfg.logDir == "/var/log/mattermost") {
885
+
LogsDirectory = baseNameOf cfg.logDir;
886
+
LogsDirectoryMode = "0750";
888
+
(mkIf (cfg.configDir == "/etc/mattermost") {
889
+
ConfigurationDirectory = baseNameOf cfg.configDir;
890
+
ConfigurationDirectoryMode = "0750";
335
-
rm -f "${cfg.statePath}/config/config.json"
336
-
echo "$new_config" > "${cfg.statePath}/config/config.json"
338
-
+ lib.optionalString cfg.localDatabaseCreate (createDb { })
340
-
# Don't change permissions recursively on the data, current, and symlinked directories (see ln -sf command above).
341
-
# This dramatically decreases startup times for installations with a lot of files.
342
-
find . -maxdepth 1 -not -name data -not -name client -not -name templates -not -name i18n -not -name fonts -not -name bin -not -name . \
343
-
-exec chown "${cfg.user}:${cfg.group}" -R {} \; -exec chmod u+rw,g+r,o-rwx -R {} \;
894
+
unitConfig.JoinsNamespaceOf = mkMerge [
895
+
(mkIf (cfg.database.driver == "postgres" && cfg.database.create) [ "postgresql.service" ])
896
+
(mkIf (cfg.database.driver == "mysql" && cfg.database.create) [ "mysql.service" ])
345
-
chown "${cfg.user}:${cfg.group}" "${cfg.statePath}/data" .
346
-
chmod u+rw,g+r,o-rwx "${cfg.statePath}/data" .
902
+
# Make sure the URL doesn't have a trailing slash
903
+
assertion = !(hasSuffix "/" cfg.siteUrl);
905
+
services.mattermost.siteUrl should not have a trailing "/".
909
+
# Make sure this isn't a host/port pair
910
+
assertion = !(hasInfix ":" cfg.host && !(hasInfix "[" cfg.host) && !(hasInfix "]" cfg.host));
912
+
services.mattermost.host should not include a port. Use services.mattermost.host for the address
913
+
or hostname, and services.mattermost.port to specify the port separately.
350
-
PermissionsStartOnly = true;
353
-
ExecStart = "${cfg.package}/bin/mattermost";
354
-
WorkingDirectory = "${cfg.statePath}";
355
-
Restart = "always";
357
-
LimitNOFILE = "49152";
358
-
EnvironmentFile = cfg.environmentFile;
360
-
unitConfig.JoinsNamespaceOf = mkIf cfg.localDatabaseCreate "postgresql.service";
(mkIf cfg.matterircd.enable {
systemd.services.matterircd = {
···
370
-
ExecStart = "${cfg.matterircd.package}/bin/matterircd ${escapeShellArgs cfg.matterircd.parameters}";
925
+
ExecStart = "${getExe cfg.matterircd.package} ${escapeShellArgs cfg.matterircd.parameters}";
WorkingDirectory = "/tmp";
···
935
+
meta.maintainers = with lib.maintainers; [ numinit ];