nixos/mattermost: correct file upload directory (#400221)

Changed files
+36 -15
nixos
doc
manual
release-notes
modules
services
web-apps
tests
mattermost
-1
nixos/doc/manual/release-notes/rl-2505.section.md
···
- `services.mattermost.listenAddress` has been split into {option}`services.mattermost.host` and {option}`services.mattermost.port`. If your `listenAddress` contained a port, you will need to edit your configuration.
- Mattermost now supports peer authentication on both MySQL and Postgres database backends. Updating {option}`system.stateVersion` to 25.05 or later will result in peer authentication being used by default if the Mattermost server would otherwise be connecting to localhost. This is the recommended configuration.
- The Mattermost module will produce eval warnings if a database password would end up in the Nix store, and recommend alternatives such as peer authentication or using the environment file.
-
- Mattermost's entire test suite is now enabled by default, which will extend build time from sources by up to an hour. A `withoutTests` passthru has been added in case you want to skip it.
- We now support `mmctl` for Mattermost administration if both {option}`services.mattermost.socket.enable` and {option}`services.mattermost.socket.export` are set, which export the Mattermost control socket path into the system environment.
- A new `pkgs.mattermost.buildPlugin` function has been added, which allows plugins to be built from source, including webapp frontends with a supported package-lock.json. See the Mattermost NixOS test and [manual](https://nixos.org/manual/nixpkgs/unstable/#sec-mattermost-plugins-build) for an example.
- Note that the Mattermost module will create an account _without_ a well-known UID if the username differs from the default (`mattermost`). If you used Mattermost with a nonstandard username, you may want to review the module changes before upgrading.
···
- `services.mattermost.listenAddress` has been split into {option}`services.mattermost.host` and {option}`services.mattermost.port`. If your `listenAddress` contained a port, you will need to edit your configuration.
- Mattermost now supports peer authentication on both MySQL and Postgres database backends. Updating {option}`system.stateVersion` to 25.05 or later will result in peer authentication being used by default if the Mattermost server would otherwise be connecting to localhost. This is the recommended configuration.
- The Mattermost module will produce eval warnings if a database password would end up in the Nix store, and recommend alternatives such as peer authentication or using the environment file.
- We now support `mmctl` for Mattermost administration if both {option}`services.mattermost.socket.enable` and {option}`services.mattermost.socket.export` are set, which export the Mattermost control socket path into the system environment.
- A new `pkgs.mattermost.buildPlugin` function has been added, which allows plugins to be built from source, including webapp frontends with a supported package-lock.json. See the Mattermost NixOS test and [manual](https://nixos.org/manual/nixpkgs/unstable/#sec-mattermost-plugins-build) for an example.
- Note that the Mattermost module will create an account _without_ a well-known UID if the username differs from the default (`mattermost`). If you used Mattermost with a nonstandard username, you may want to review the module changes before upgrading.
+21 -11
nixos/modules/services/web-apps/mattermost.nix
···
# The directory to store mutable data within dataDir.
mutableDataDir = "${cfg.dataDir}/data";
-
# The plugin directory. Note that this is the *post-unpack* plugin directory,
-
# since Mattermost unpacks plugins to put them there. (Hence, mutable data.)
-
pluginDir = "${mutableDataDir}/plugins";
# Mattermost uses this as a staging directory to unpack plugins, among possibly other things.
# Ensure that it's inside mutableDataDir since it can get rather large.
···
services.mattermost.environmentFile = "<your environment file>";
services.mattermost.database.fromEnvironment = true;
'' database;
-
FileSettings.Directory = cfg.dataDir;
-
PluginSettings.Directory = "${pluginDir}/server";
-
PluginSettings.ClientDirectory = "${pluginDir}/client";
LogSettings = {
FileLocation = cfg.logDir;
···
"R- ${tempDir} - - - - -"
"d= ${tempDir} 0750 ${cfg.user} ${cfg.group} - -"
-
# Ensure that pluginDir is a directory, as it could be a symlink on prior versions.
# Don't remove or clean it out since it should be persistent, as this is where plugins are unpacked.
-
"d= ${pluginDir} 0750 ${cfg.user} ${cfg.group} - -"
# Ensure that the plugin directories exist.
"d= ${mattermostConf.PluginSettings.Directory} 0750 ${cfg.user} ${cfg.group} - -"
···
if cfg.pluginsBundle == null then
# Create the plugin tarball directory to allow plugin uploads.
[
-
"d= ${cfg.dataDir}/plugins 0750 ${cfg.user} ${cfg.group} - -"
]
else
# Symlink the plugin tarball directory, removing anything existing, since it's managed by Nix.
-
[ "L+ ${cfg.dataDir}/plugins - - - - ${cfg.pluginsBundle}" ]
);
systemd.services.mattermost = rec {
···
# Logs too.
oldLogs="$dataDir/logs"
newLogs="$logDir"
-
if [ "$oldLogs" != "$newLogs" ] && [ -d "$oldLogs" ]; then
# Migrate the legacy log location to the new log location.
# Allow this to fail if there aren't any logs to move.
echo "Moving legacy logs at $oldLogs to $newLogs" >&2
mkdir -p "$newLogs"
mv "$oldLogs"/* "$newLogs" || true
fi
''
+ optionalString (!cfg.mutableConfig) ''
···
# The directory to store mutable data within dataDir.
mutableDataDir = "${cfg.dataDir}/data";
+
# The plugin directory. Note that this is the *pre-unpack* plugin directory,
+
# since Mattermost looks in mutableDataDir for a directory called "plugins".
+
# If Mattermost is installed with plugins defined in a Nix configuration, the plugins
+
# are symlinked here. Otherwise, this is a real directory and the tarballs are uploaded here.
+
pluginTarballDir = "${mutableDataDir}/plugins";
+
+
# We need a different unpack directory for Mattermost to sync things to at launch,
+
# since the above may be a symlink to the store.
+
pluginUnpackDir = "${mutableDataDir}/.plugins";
# Mattermost uses this as a staging directory to unpack plugins, among possibly other things.
# Ensure that it's inside mutableDataDir since it can get rather large.
···
services.mattermost.environmentFile = "<your environment file>";
services.mattermost.database.fromEnvironment = true;
'' database;
+
+
# Note that the plugin tarball directory is not configurable, and is expected to be in FileSettings.Directory/plugins.
+
FileSettings.Directory = mutableDataDir;
+
PluginSettings.Directory = "${pluginUnpackDir}/server";
+
PluginSettings.ClientDirectory = "${pluginUnpackDir}/client";
+
LogSettings = {
FileLocation = cfg.logDir;
···
"R- ${tempDir} - - - - -"
"d= ${tempDir} 0750 ${cfg.user} ${cfg.group} - -"
+
# Ensure that pluginUnpackDir is a directory.
# Don't remove or clean it out since it should be persistent, as this is where plugins are unpacked.
+
"d= ${pluginUnpackDir} 0750 ${cfg.user} ${cfg.group} - -"
# Ensure that the plugin directories exist.
"d= ${mattermostConf.PluginSettings.Directory} 0750 ${cfg.user} ${cfg.group} - -"
···
if cfg.pluginsBundle == null then
# Create the plugin tarball directory to allow plugin uploads.
[
+
"d= ${pluginTarballDir} 0750 ${cfg.user} ${cfg.group} - -"
]
else
# Symlink the plugin tarball directory, removing anything existing, since it's managed by Nix.
+
[ "L+ ${pluginTarballDir} - - - - ${cfg.pluginsBundle}" ]
);
systemd.services.mattermost = rec {
···
# Logs too.
oldLogs="$dataDir/logs"
newLogs="$logDir"
+
if [ "$oldLogs" != "$newLogs" ] && [ -d "$oldLogs" ] && [ ! -f "$newLogs/.initial-created" ]; then
# Migrate the legacy log location to the new log location.
# Allow this to fail if there aren't any logs to move.
echo "Moving legacy logs at $oldLogs to $newLogs" >&2
mkdir -p "$newLogs"
mv "$oldLogs"/* "$newLogs" || true
+
touch "$newLogs/.initial-created"
fi
''
+ optionalString (!cfg.mutableConfig) ''
+15 -3
nixos/tests/mattermost/default.nix
···
if [ "$actualPostAttachmentHash" != "$postAttachmentHash" ]; then
echo "Post attachment hash mismatched!" >&2
exit 1
-
else
echo "Post attachment hash was OK!" >&2
exit 0
fi
else
echo "Post didn't exist when it should have!" >&2
···
# Switch to the newer config and make sure the plugins directory is replaced with a directory,
# since it could have been a symlink on previous versions.
mostlyMutable.systemctl("stop mattermost.service")
-
mostlyMutable.succeed(f"[ ! -L /var/lib/mattermost/data/plugins ] && rm -rf /var/lib/mattermost/data/plugins && ln -s {mostlyMutablePlugins} /var/lib/mattermost/data/plugins || true")
mostlyMutable.succeed('[ -L /var/lib/mattermost/data/plugins ] && [ -d /var/lib/mattermost/data/plugins ]')
switch_to_specialisation(mostlyMutable, mostlyMutableToplevel, "upgrade")
wait_mattermost_up(mostlyMutable)
-
mostlyMutable.succeed('[ ! -L /var/lib/mattermost/data/plugins ] && [ -d /var/lib/mattermost/data/plugins ]')
# HelpLink should be changed, still, and the post should still exist
expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')
···
if [ "$actualPostAttachmentHash" != "$postAttachmentHash" ]; then
echo "Post attachment hash mismatched!" >&2
exit 1
+
fi
+
+
# Make sure it's on the filesystem in the expected place
+
fsPath="$(find /var/lib/mattermost/data -name "$(basename -- "$postAttachment")" -print -quit)"
+
if [ -z "$fsPath" ] || [ ! -f "$fsPath" ]; then
+
echo "Attachment didn't exist on the filesystem!" >&2
+
exit 1
+
fi
+
+
# And that the hash matches.
+
actualFsAttachmentHash="$(sha256sum "$fsPath" | awk '{print $1}')"
+
if [ "$actualFsAttachmentHash" == "$postAttachmentHash" ]; then
echo "Post attachment hash was OK!" >&2
exit 0
+
else
+
echo "Attachment hash mismatched on disk!" >&2
+
exit 1
fi
else
echo "Post didn't exist when it should have!" >&2
···
# Switch to the newer config and make sure the plugins directory is replaced with a directory,
# since it could have been a symlink on previous versions.
mostlyMutable.systemctl("stop mattermost.service")
mostlyMutable.succeed('[ -L /var/lib/mattermost/data/plugins ] && [ -d /var/lib/mattermost/data/plugins ]')
switch_to_specialisation(mostlyMutable, mostlyMutableToplevel, "upgrade")
wait_mattermost_up(mostlyMutable)
# HelpLink should be changed, still, and the post should still exist
expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')