From 174b3404063c5821a1852435a0113a792beb7bb4 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Sun, 11 Apr 2021 19:29:29 -0600 Subject: [PATCH] nixos/mattermost: add preferNixConfig option and tests One use case for Mattermost configuration is doing a "mostly mutable" configuration where NixOS module options take priority over Mattermost's config JSON. Add a preferNixConfig option that prefers configured Nix options over what's configured in Mattermost config if mutableConfig is set. Remove the reliance on readFile (it's flake incompatible) and use jq instead. Merge Mattermost configs together on Mattermost startup, depending on configured module options. Write tests for mutable, mostly mutable, and immutable configurations. --- .../modules/services/web-apps/mattermost.nix | 42 ++++--- nixos/tests/all-tests.nix | 1 + nixos/tests/mattermost.nix | 116 ++++++++++++++++++ 3 files changed, 143 insertions(+), 16 deletions(-) create mode 100644 nixos/tests/mattermost.nix 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"''}") + ''; +})