diff --git a/nixos/modules/services/web-apps/mattermost.nix b/nixos/modules/services/web-apps/mattermost.nix index f5c2c356afce..a3127aed6925 100644 --- a/nixos/modules/services/web-apps/mattermost.nix +++ b/nixos/modules/services/web-apps/mattermost.nix @@ -6,23 +6,18 @@ let cfg = config.services.mattermost; - defaultConfig = builtins.fromJSON (builtins.replaceStrings [ "\\u0026" ] [ "&" ] - (readFile "${pkgs.mattermost}/config/config.json") - ); - database = "postgres://${cfg.localDatabaseUser}:${cfg.localDatabasePassword}@localhost:5432/${cfg.localDatabaseName}?sslmode=disable&connect_timeout=10"; - mattermostConf = foldl recursiveUpdate defaultConfig - [ { ServiceSettings.SiteURL = cfg.siteUrl; - ServiceSettings.ListenAddress = cfg.listenAddress; - TeamSettings.SiteName = cfg.siteName; - SqlSettings.DriverName = "postgres"; - SqlSettings.DataSource = database; - } - cfg.extraConfig - ]; + mattermostConf = recursiveUpdate + { ServiceSettings.SiteURL = cfg.siteUrl; + ServiceSettings.ListenAddress = cfg.listenAddress; + TeamSettings.SiteName = cfg.siteName; + SqlSettings.DriverName = "postgres"; + SqlSettings.DataSource = database; + } + cfg.extraConfig; - mattermostConfJSON = pkgs.writeText "mattermost-config-raw.json" (builtins.toJSON mattermostConf); + mattermostConfJSON = pkgs.writeText "mattermost-config.json" (builtins.toJSON mattermostConf); in @@ -77,6 +72,16 @@ in ''; }; + preferNixConfig = mkOption { + type = types.bool; + default = false; + description = '' + If both mutableConfig and this option are set, the Nix configuration + will take precedence over any settings configured in the server + console. + ''; + }; + extraConfig = mkOption { type = types.attrs; default = { }; @@ -180,14 +185,19 @@ in ln -sf ${pkgs.mattermost}/{bin,fonts,i18n,templates,client} ${cfg.statePath} '' + lib.optionalString (!cfg.mutableConfig) '' rm -f ${cfg.statePath}/config/config.json - cp ${mattermostConfJSON} ${cfg.statePath}/config/config.json + ${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${pkgs.mattermost}/config/config.json ${mattermostConfJSON} > ${cfg.statePath}/config/config.json ${pkgs.mattermost}/bin/mattermost config migrate ${cfg.statePath}/config/config.json ${database} '' + lib.optionalString cfg.mutableConfig '' if ! test -e "${cfg.statePath}/config/.initial-created"; then rm -f ${cfg.statePath}/config/config.json - cp ${mattermostConfJSON} ${cfg.statePath}/config/config.json + ${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${pkgs.mattermost}/config/config.json ${mattermostConfJSON} > ${cfg.statePath}/config/config.json touch ${cfg.statePath}/config/.initial-created fi + '' + lib.optionalString (cfg.mutableConfig && cfg.preferNixConfig) '' + newConfig="$(${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${cfg.statePath}/config/config.json ${mattermostConfJSON})" + + rm -f ${cfg.statePath}/config/config.json + echo "$newConfig" > ${cfg.statePath}/config/config.json '' + lib.optionalString cfg.localDatabaseCreate '' if ! test -e "${cfg.statePath}/.db-created"; then ${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} \ diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index db526df392b3..42f9c07703d5 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -261,6 +261,7 @@ in matomo = handleTest ./matomo.nix {}; matrix-appservice-irc = handleTest ./matrix-appservice-irc.nix {}; matrix-synapse = handleTest ./matrix-synapse.nix {}; + mattermost = handleTest ./mattermost.nix {}; mediawiki = handleTest ./mediawiki.nix {}; meilisearch = handleTest ./meilisearch.nix {}; memcached = handleTest ./memcached.nix {}; diff --git a/nixos/tests/mattermost.nix b/nixos/tests/mattermost.nix new file mode 100644 index 000000000000..116d15e1315e --- /dev/null +++ b/nixos/tests/mattermost.nix @@ -0,0 +1,116 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: +let + host = "smoke.test"; + port = "8065"; + url = "http://${host}:${port}"; + siteName = "NixOS Smoke Tests, Inc."; + + makeMattermost = mattermostConfig: + { config, ... }: { + environment.systemPackages = [ + pkgs.mattermost + pkgs.curl + pkgs.jq + ]; + networking.hosts = { + "127.0.0.1" = [ host ]; + }; + services.mattermost = lib.recursiveUpdate { + enable = true; + inherit siteName; + listenAddress = "0.0.0.0:${port}"; + siteUrl = url; + extraConfig = { + SupportSettings.AboutLink = "https://nixos.org"; + }; + } mattermostConfig; + }; +in +{ + name = "mattermost"; + + nodes = { + mutable = makeMattermost { + mutableConfig = true; + extraConfig.SupportSettings.HelpLink = "https://search.nixos.org"; + }; + mostlyMutable = makeMattermost { + mutableConfig = true; + preferNixConfig = true; + }; + immutable = makeMattermost { + mutableConfig = false; + extraConfig.SupportSettings.HelpLink = "https://search.nixos.org"; + }; + }; + + testScript = let + expectConfig = jqExpression: pkgs.writeShellScript "expect-config" '' + set -euo pipefail + echo "Expecting config to match: "${lib.escapeShellArg jqExpression} >&2 + curl ${lib.escapeShellArg url} >/dev/null + config="$(curl ${lib.escapeShellArg "${url}/api/v4/config/client?format=old"})" + echo "Config: $(echo "$config" | ${pkgs.jq}/bin/jq)" >&2 + [[ "$(echo "$config" | ${pkgs.jq}/bin/jq -r ${lib.escapeShellArg ".SiteName == $siteName and .Version == ($mattermostName / $sep)[-1] and (${jqExpression})"} --arg siteName ${lib.escapeShellArg siteName} --arg mattermostName ${lib.escapeShellArg pkgs.mattermost.name} --arg sep '-')" = "true" ]] + ''; + + setConfig = jqExpression: pkgs.writeShellScript "set-config" '' + set -euo pipefail + mattermostConfig=/var/lib/mattermost/config/config.json + newConfig="$(${pkgs.jq}/bin/jq -r ${lib.escapeShellArg jqExpression} $mattermostConfig)" + rm -f $mattermostConfig + echo "$newConfig" > "$mattermostConfig" + ''; + in + '' + start_all() + + ## Mutable node tests ## + mutable.wait_for_unit("mattermost.service") + mutable.wait_for_open_port(8065) + + # Get the initial config + mutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"''}") + + # Edit the config + mutable.succeed("${setConfig ''.SupportSettings.AboutLink = "https://mattermost.com"''}") + mutable.succeed("${setConfig ''.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"''}") + mutable.systemctl("restart mattermost.service") + mutable.wait_for_open_port(8065) + + # AboutLink and HelpLink should be changed + mutable.succeed("${expectConfig ''.AboutLink == "https://mattermost.com" and .HelpLink == "https://nixos.org/nixos/manual"''}") + + ## Mostly mutable node tests ## + mostlyMutable.wait_for_unit("mattermost.service") + mostlyMutable.wait_for_open_port(8065) + + # Get the initial config + mostlyMutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org"''}") + + # Edit the config + mostlyMutable.succeed("${setConfig ''.SupportSettings.AboutLink = "https://mattermost.com"''}") + mostlyMutable.succeed("${setConfig ''.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"''}") + mostlyMutable.systemctl("restart mattermost.service") + mostlyMutable.wait_for_open_port(8065) + + # AboutLink should be overridden by NixOS configuration; HelpLink should be what we set above + mostlyMutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://nixos.org/nixos/manual"''}") + + ## Immutable node tests ## + immutable.wait_for_unit("mattermost.service") + immutable.wait_for_open_port(8065) + + # Get the initial config + immutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"''}") + + # Edit the config + immutable.succeed("${setConfig ''.SupportSettings.AboutLink = "https://mattermost.com"''}") + immutable.succeed("${setConfig ''.SupportSettings.HelpLink = "https://nixos.org/nixos/manual"''}") + immutable.systemctl("restart mattermost.service") + immutable.wait_for_open_port(8065) + + # Our edits should be ignored on restart + immutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"''}") + ''; +})