diff --git a/pkg/cli/server/root.go b/pkg/cli/server/root.go index afdc1d1568..77f74e49d1 100644 --- a/pkg/cli/server/root.go +++ b/pkg/cli/server/root.go @@ -7,6 +7,7 @@ import ( "net/http" "os" "path" + "path/filepath" "regexp" "strconv" "strings" @@ -23,6 +24,7 @@ import ( "zotregistry.io/zot/pkg/api" "zotregistry.io/zot/pkg/api/config" "zotregistry.io/zot/pkg/api/constants" + "zotregistry.io/zot/pkg/common" extconf "zotregistry.io/zot/pkg/extensions/config" "zotregistry.io/zot/pkg/extensions/monitoring" zlog "zotregistry.io/zot/pkg/log" @@ -736,12 +738,36 @@ func LoadConfiguration(config *config.Config, configPath string) error { // we need another key delimiter. viperInstance := viper.NewWithOptions(viper.KeyDelimiter("::")) - viperInstance.SetConfigFile(configPath) + ext := filepath.Ext(configPath) - if err := viperInstance.ReadInConfig(); err != nil { - log.Error().Err(err).Msg("failed to read configuration") + /* if file extension is not supported, try everything + it's also possible that the filename is starting with a dot eg: ".config". */ + if !common.Contains(viper.SupportedExts, ext) { + ext = "" + } - return err + switch ext { + case "": + log.Info().Msg("config file with no extension, trying all supported config types") + + for _, configType := range viper.SupportedExts { + viperInstance.SetConfigType(configType) + viperInstance.SetConfigFile(configPath) + + err := viperInstance.ReadInConfig() + if err == nil { + break + } + + log.Debug().Err(err).Str("type", configType).Msg("failed to read configuration with no extension") + } + default: + viperInstance.SetConfigFile(configPath) + if err := viperInstance.ReadInConfig(); err != nil { + log.Error().Err(err).Str("path", configPath).Msg("failed to read configuration") + + return err + } } metaData := &mapstructure.Metadata{} diff --git a/pkg/cli/server/root_test.go b/pkg/cli/server/root_test.go index 98072c1717..0abce6798e 100644 --- a/pkg/cli/server/root_test.go +++ b/pkg/cli/server/root_test.go @@ -121,6 +121,37 @@ func TestVerify(t *testing.T) { So(err, ShouldNotBeNil) }) + Convey("Test verify config with no extension", t, func(c C) { + tmpfile, err := os.CreateTemp("", "zot-test*") + So(err, ShouldBeNil) + defer os.Remove(tmpfile.Name()) // clean up + content := []byte(`{"log":{}}`) + _, err = tmpfile.Write(content) + So(err, ShouldBeNil) + err = tmpfile.Close() + So(err, ShouldBeNil) + os.Args = []string{"cli_test", "verify", tmpfile.Name()} + err = cli.NewServerRootCmd().Execute() + So(err, ShouldNotBeNil) + }) + + Convey("Test verify config with dotted config name", t, func(c C) { + tmpfile, err := os.CreateTemp("", ".zot-test*") + So(err, ShouldBeNil) + defer os.Remove(tmpfile.Name()) // clean up + content := []byte(` +log: + level: debug +`) + _, err = tmpfile.Write(content) + So(err, ShouldBeNil) + err = tmpfile.Close() + So(err, ShouldBeNil) + os.Args = []string{"cli_test", "verify", tmpfile.Name()} + err = cli.NewServerRootCmd().Execute() + So(err, ShouldNotBeNil) + }) + Convey("Test verify CVE warn for remote storage", t, func(c C) { tmpfile, err := os.CreateTemp("", "zot-test*.json") So(err, ShouldBeNil)