MM-28859 Add feature flag managment system using split.io and remove viper. (#15954)
* Add feature flag managment system using split.io and remove viper. * Fixing tests. * Attempt to fix postgres tests. * Fix watch filepath for advanced logging. * Review fixes. * Some error wrapping. * Remove unessisary store interface. * Desanitize SplitKey * Simplify. * Review feedback. * Rename split mlog adatper to split logger. * fsInner * Style. * Restore oldcfg test. * Downgrading non-actionable feature flag errors to warnings. Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
8bb772638c
Коммит
1aadd36644
@@ -11,7 +11,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/viper"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@@ -141,14 +140,12 @@ func configSubpathCmdF(command *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getConfigStore(command *cobra.Command) (config.Store, error) {
|
||||
func getConfigStore(command *cobra.Command) (*config.Store, error) {
|
||||
if err := utils.TranslationsPreInit(); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to initialize i18n")
|
||||
}
|
||||
|
||||
configDSN := viper.GetString("config")
|
||||
|
||||
configStore, err := config.NewStore(configDSN, false)
|
||||
configStore, err := config.NewStore(getConfigDSN(command, config.GetEnvironment()), false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to initialize config store")
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ func TestConfigValidate(t *testing.T) {
|
||||
tempFile, err := ioutil.TempFile("", "TestConfigValidate")
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(tempFile.Name())
|
||||
tempFile.Write([]byte("{"))
|
||||
|
||||
assert.Error(t, th.RunCommand(t, "--config", tempFile.Name(), "config", "validate"))
|
||||
th.CheckCommand(t, "config", "validate")
|
||||
|
||||
@@ -5,16 +5,14 @@ package commands
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost-server/v5/app"
|
||||
"github.com/mattermost/mattermost-server/v5/config"
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
"github.com/mattermost/mattermost-server/v5/utils"
|
||||
"github.com/mattermost/viper"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func InitDBCommandContextCobra(command *cobra.Command) (*app.App, error) {
|
||||
config := viper.GetString("config")
|
||||
|
||||
a, err := InitDBCommandContext(config)
|
||||
a, err := InitDBCommandContext(getConfigDSN(command, config.GetEnvironment()))
|
||||
|
||||
if err != nil {
|
||||
// Returning an error just prints the usage message, so actually panic
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/audit"
|
||||
"github.com/mattermost/mattermost-server/v5/config"
|
||||
"github.com/mattermost/mattermost-server/v5/mlog"
|
||||
"github.com/mattermost/viper"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -32,10 +32,8 @@ func jobserverCmdF(command *cobra.Command, args []string) error {
|
||||
noJobs, _ := command.Flags().GetBool("nojobs")
|
||||
noSchedule, _ := command.Flags().GetBool("noschedule")
|
||||
|
||||
config := viper.GetString("config")
|
||||
|
||||
// Initialize
|
||||
a, err := InitDBCommandContext(config)
|
||||
a, err := InitDBCommandContext(getConfigDSN(command, config.GetEnvironment()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -37,17 +37,21 @@ func TestPlugin(t *testing.T) {
|
||||
|
||||
fs, err := config.NewFileStore(th.ConfigPath(), false)
|
||||
require.Nil(t, err)
|
||||
require.NotNil(t, fs.Get().PluginSettings.PluginStates["testplugin"])
|
||||
assert.True(t, fs.Get().PluginSettings.PluginStates["testplugin"].Enable)
|
||||
fs.Close()
|
||||
cfsStore, err := config.NewStoreFromBacking(fs)
|
||||
require.Nil(t, err)
|
||||
require.NotNil(t, cfsStore.Get().PluginSettings.PluginStates["testplugin"])
|
||||
assert.True(t, cfsStore.Get().PluginSettings.PluginStates["testplugin"].Enable)
|
||||
cfsStore.Close()
|
||||
|
||||
output = th.CheckCommand(t, "plugin", "disable", "testplugin")
|
||||
assert.Contains(t, output, "Disabled plugin: testplugin")
|
||||
fs, err = config.NewFileStore(th.ConfigPath(), false)
|
||||
require.Nil(t, err)
|
||||
require.NotNil(t, fs.Get().PluginSettings.PluginStates["testplugin"])
|
||||
assert.False(t, fs.Get().PluginSettings.PluginStates["testplugin"].Enable)
|
||||
fs.Close()
|
||||
cfsStore, err = config.NewStoreFromBacking(fs)
|
||||
require.Nil(t, err)
|
||||
require.NotNil(t, cfsStore.Get().PluginSettings.PluginStates["testplugin"])
|
||||
assert.False(t, cfsStore.Get().PluginSettings.PluginStates["testplugin"].Enable)
|
||||
cfsStore.Close()
|
||||
|
||||
th.CheckCommand(t, "plugin", "list")
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/mattermost/viper"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -22,12 +21,8 @@ var RootCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.PersistentFlags().StringP("config", "c", "config.json", "Configuration file to use.")
|
||||
RootCmd.PersistentFlags().StringP("config", "c", "", "Configuration file to use.")
|
||||
RootCmd.PersistentFlags().Bool("disableconfigwatch", false, "When set config.json will not be loaded from disk when the file is changed.")
|
||||
RootCmd.PersistentFlags().Bool("platform", false, "This flag signifies that the user tried to start the command from the platform binary, so we can log a mssage")
|
||||
RootCmd.PersistentFlags().MarkHidden("platform")
|
||||
|
||||
viper.SetEnvPrefix("mm")
|
||||
viper.BindEnv("config")
|
||||
viper.BindPFlag("config", RootCmd.PersistentFlags().Lookup("config"))
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/mattermost/mattermost-server/v5/utils"
|
||||
"github.com/mattermost/mattermost-server/v5/web"
|
||||
"github.com/mattermost/mattermost-server/v5/wsapi"
|
||||
"github.com/mattermost/viper"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -36,8 +35,6 @@ func init() {
|
||||
}
|
||||
|
||||
func serverCmdF(command *cobra.Command, args []string) error {
|
||||
configDSN := viper.GetString("config")
|
||||
|
||||
disableConfigWatch, _ := command.Flags().GetBool("disableconfigwatch")
|
||||
usedPlatform, _ := command.Flags().GetBool("platform")
|
||||
|
||||
@@ -46,7 +43,7 @@ func serverCmdF(command *cobra.Command, args []string) error {
|
||||
if err := utils.TranslationsPreInit(); err != nil {
|
||||
return errors.Wrapf(err, "unable to load Mattermost translation files")
|
||||
}
|
||||
configStore, err := config.NewStore(configDSN, !disableConfigWatch)
|
||||
configStore, err := config.NewStore(getConfigDSN(command, config.GetEnvironment()), !disableConfigWatch)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to load configuration")
|
||||
}
|
||||
@@ -54,7 +51,7 @@ func serverCmdF(command *cobra.Command, args []string) error {
|
||||
return runServer(configStore, disableConfigWatch, usedPlatform, interruptChan)
|
||||
}
|
||||
|
||||
func runServer(configStore config.Store, disableConfigWatch bool, usedPlatform bool, interruptChan chan os.Signal) error {
|
||||
func runServer(configStore *config.Store, disableConfigWatch bool, usedPlatform bool, interruptChan chan os.Signal) error {
|
||||
// Setting the highest traceback level from the code.
|
||||
// This is done to print goroutines from all threads (see golang.org/issue/13161)
|
||||
// and also preserve a crash dump for later investigation.
|
||||
|
||||
@@ -57,13 +57,12 @@ func TestRunServerSuccess(t *testing.T) {
|
||||
th := SetupServerTest(t)
|
||||
defer th.TearDownServerTest()
|
||||
|
||||
configStore, err := config.NewMemoryStore()
|
||||
require.NoError(t, err)
|
||||
configStore := config.NewTestMemoryStore()
|
||||
|
||||
// Use non-default listening port in case another server instance is already running.
|
||||
*configStore.Get().ServiceSettings.ListenAddress = UnitTestListeningPort
|
||||
|
||||
err = runServer(configStore, th.disableConfigWatch, false, th.interruptChan)
|
||||
err := runServer(configStore, th.disableConfigWatch, false, th.interruptChan)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -108,8 +107,7 @@ func TestRunServerSystemdNotification(t *testing.T) {
|
||||
ch <- string(data)
|
||||
}(socketReader)
|
||||
|
||||
configStore, err := config.NewMemoryStore()
|
||||
require.NoError(t, err)
|
||||
configStore := config.NewTestMemoryStore()
|
||||
|
||||
// Use non-default listening port in case another server instance is already running.
|
||||
*configStore.Get().ServiceSettings.ListenAddress = UnitTestListeningPort
|
||||
@@ -132,12 +130,11 @@ func TestRunServerNoSystemd(t *testing.T) {
|
||||
os.Unsetenv("NOTIFY_SOCKET")
|
||||
defer os.Setenv("NOTIFY_SOCKET", originalSocket)
|
||||
|
||||
configStore, err := config.NewMemoryStore()
|
||||
require.NoError(t, err)
|
||||
configStore := config.NewTestMemoryStore()
|
||||
|
||||
// Use non-default listening port in case another server instance is already running.
|
||||
*configStore.Get().ServiceSettings.ListenAddress = UnitTestListeningPort
|
||||
|
||||
err = runServer(configStore, th.disableConfigWatch, false, th.interruptChan)
|
||||
err := runServer(configStore, th.disableConfigWatch, false, th.interruptChan)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/mlog"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// prettyPrintStruct will return a prettyPrint version of a given struct
|
||||
@@ -99,3 +100,19 @@ func printStringMap(value reflect.Value, tabVal int) string {
|
||||
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func getConfigDSN(command *cobra.Command, env map[string]string) string {
|
||||
configDSN, _ := command.Flags().GetString("config")
|
||||
|
||||
// Config not supplied in flag, check env
|
||||
if configDSN == "" {
|
||||
configDSN = env["MM_CONFIG"]
|
||||
}
|
||||
|
||||
// Config not supplied in env or flag use default
|
||||
if configDSN == "" {
|
||||
configDSN = "config.json"
|
||||
}
|
||||
|
||||
return configDSN
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user