lol

nixos/mattermost: correct file upload directory

Fix compatibility with previous versions by making sure all the uploads
and plugins end up in the correct directory. Add a test for the exact
path we care about to ensure that it doesn't work "on accident."

Discovered while updating instances to unstable.

+36 -14
+21 -11
nixos/modules/services/web-apps/mattermost.nix
··· 41 41 # The directory to store mutable data within dataDir. 42 42 mutableDataDir = "${cfg.dataDir}/data"; 43 43 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"; 44 + # The plugin directory. Note that this is the *pre-unpack* plugin directory, 45 + # since Mattermost looks in mutableDataDir for a directory called "plugins". 46 + # If Mattermost is installed with plugins defined in a Nix configuration, the plugins 47 + # are symlinked here. Otherwise, this is a real directory and the tarballs are uploaded here. 48 + pluginTarballDir = "${mutableDataDir}/plugins"; 49 + 50 + # We need a different unpack directory for Mattermost to sync things to at launch, 51 + # since the above may be a symlink to the store. 52 + pluginUnpackDir = "${mutableDataDir}/.plugins"; 47 53 48 54 # Mattermost uses this as a staging directory to unpack plugins, among possibly other things. 49 55 # Ensure that it's inside mutableDataDir since it can get rather large. ··· 232 238 services.mattermost.environmentFile = "<your environment file>"; 233 239 services.mattermost.database.fromEnvironment = true; 234 240 '' database; 235 - FileSettings.Directory = cfg.dataDir; 236 - PluginSettings.Directory = "${pluginDir}/server"; 237 - PluginSettings.ClientDirectory = "${pluginDir}/client"; 241 + 242 + # Note that the plugin tarball directory is not configurable, and is expected to be in FileSettings.Directory/plugins. 243 + FileSettings.Directory = mutableDataDir; 244 + PluginSettings.Directory = "${pluginUnpackDir}/server"; 245 + PluginSettings.ClientDirectory = "${pluginUnpackDir}/client"; 246 + 238 247 LogSettings = { 239 248 FileLocation = cfg.logDir; 240 249 ··· 800 809 "R- ${tempDir} - - - - -" 801 810 "d= ${tempDir} 0750 ${cfg.user} ${cfg.group} - -" 802 811 803 - # Ensure that pluginDir is a directory, as it could be a symlink on prior versions. 812 + # Ensure that pluginUnpackDir is a directory. 804 813 # Don't remove or clean it out since it should be persistent, as this is where plugins are unpacked. 805 - "d= ${pluginDir} 0750 ${cfg.user} ${cfg.group} - -" 814 + "d= ${pluginUnpackDir} 0750 ${cfg.user} ${cfg.group} - -" 806 815 807 816 # Ensure that the plugin directories exist. 808 817 "d= ${mattermostConf.PluginSettings.Directory} 0750 ${cfg.user} ${cfg.group} - -" ··· 819 828 if cfg.pluginsBundle == null then 820 829 # Create the plugin tarball directory to allow plugin uploads. 821 830 [ 822 - "d= ${cfg.dataDir}/plugins 0750 ${cfg.user} ${cfg.group} - -" 831 + "d= ${pluginTarballDir} 0750 ${cfg.user} ${cfg.group} - -" 823 832 ] 824 833 else 825 834 # Symlink the plugin tarball directory, removing anything existing, since it's managed by Nix. 826 - [ "L+ ${cfg.dataDir}/plugins - - - - ${cfg.pluginsBundle}" ] 835 + [ "L+ ${pluginTarballDir} - - - - ${cfg.pluginsBundle}" ] 827 836 ); 828 837 829 838 systemd.services.mattermost = rec { ··· 867 876 # Logs too. 868 877 oldLogs="$dataDir/logs" 869 878 newLogs="$logDir" 870 - if [ "$oldLogs" != "$newLogs" ] && [ -d "$oldLogs" ]; then 879 + if [ "$oldLogs" != "$newLogs" ] && [ -d "$oldLogs" ] && [ ! -f "$newLogs/.initial-created" ]; then 871 880 # Migrate the legacy log location to the new log location. 872 881 # Allow this to fail if there aren't any logs to move. 873 882 echo "Moving legacy logs at $oldLogs to $newLogs" >&2 874 883 mkdir -p "$newLogs" 875 884 mv "$oldLogs"/* "$newLogs" || true 885 + touch "$newLogs/.initial-created" 876 886 fi 877 887 '' 878 888 + optionalString (!cfg.mutableConfig) ''
+15 -3
nixos/tests/mattermost/default.nix
··· 335 335 if [ "$actualPostAttachmentHash" != "$postAttachmentHash" ]; then 336 336 echo "Post attachment hash mismatched!" >&2 337 337 exit 1 338 - else 338 + fi 339 + 340 + # Make sure it's on the filesystem in the expected place 341 + fsPath="$(find /var/lib/mattermost/data -name "$(basename -- "$postAttachment")" -print -quit)" 342 + if [ -z "$fsPath" ] || [ ! -f "$fsPath" ]; then 343 + echo "Attachment didn't exist on the filesystem!" >&2 344 + exit 1 345 + fi 346 + 347 + # And that the hash matches. 348 + actualFsAttachmentHash="$(sha256sum "$fsPath" | awk '{print $1}')" 349 + if [ "$actualFsAttachmentHash" == "$postAttachmentHash" ]; then 339 350 echo "Post attachment hash was OK!" >&2 340 351 exit 0 352 + else 353 + echo "Attachment hash mismatched on disk!" >&2 354 + exit 1 341 355 fi 342 356 else 343 357 echo "Post didn't exist when it should have!" >&2 ··· 454 468 # Switch to the newer config and make sure the plugins directory is replaced with a directory, 455 469 # since it could have been a symlink on previous versions. 456 470 mostlyMutable.systemctl("stop mattermost.service") 457 - 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") 458 471 mostlyMutable.succeed('[ -L /var/lib/mattermost/data/plugins ] && [ -d /var/lib/mattermost/data/plugins ]') 459 472 switch_to_specialisation(mostlyMutable, mostlyMutableToplevel, "upgrade") 460 473 wait_mattermost_up(mostlyMutable) 461 - mostlyMutable.succeed('[ ! -L /var/lib/mattermost/data/plugins ] && [ -d /var/lib/mattermost/data/plugins ]') 462 474 463 475 # HelpLink should be changed, still, and the post should still exist 464 476 expect_config(mostlyMutable, esr, '.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"')