frostfs-s3-lifecycler/cmd/s3-lifecycler/settings.go
Denis Kirillov 4e71fbeba6 [#1] Add basic repository structure
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2024-07-02 12:14:51 +03:00

161 lines
3 KiB
Go

package main
import (
"fmt"
"os"
"path"
"runtime"
"strings"
"time"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
const (
cfgPrometheusEnabled = "prometheus.enabled"
cfgPrometheusAddress = "prometheus.address"
cfgPprofEnabled = "pprof.enabled"
cfgPprofAddress = "pprof.address"
// Logger.
cfgLoggerLevel = "logger.level"
cfgLoggerDestination = "logger.destination"
// Command line args.
cmdHelp = "help"
cmdVersion = "version"
cmdConfig = "config"
cmdConfigDir = "config-dir"
)
const (
defaultShutdownTimeout = 15 * time.Second
componentName = "frostfs-s3-lifecycler"
)
func settings() *viper.Viper {
v := viper.New()
v.AutomaticEnv()
v.SetEnvPrefix(Prefix)
v.AllowEmptyEnv(true)
v.SetConfigType("yaml")
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
// flags setup:
flags := pflag.NewFlagSet("commandline", pflag.ExitOnError)
flags.SetOutput(os.Stdout)
flags.SortFlags = false
help := flags.BoolP(cmdHelp, "h", false, "show help")
version := flags.BoolP(cmdVersion, "v", false, "show version")
flags.StringArray(cmdConfig, nil, "config paths")
flags.String(cmdConfigDir, "", "config dir path")
// set defaults:
// logger:
v.SetDefault(cfgLoggerLevel, "debug")
v.SetDefault(cfgLoggerDestination, "stdout")
// services:
v.SetDefault(cfgPrometheusEnabled, false)
v.SetDefault(cfgPprofEnabled, false)
// Bind flags with configuration values.
if err := v.BindPFlags(flags); err != nil {
panic(err)
}
if err := flags.Parse(os.Args); err != nil {
panic(err)
}
switch {
case help != nil && *help:
printVersion()
flags.PrintDefaults()
os.Exit(0)
case version != nil && *version:
printVersion()
os.Exit(0)
}
if err := readInConfig(v); err != nil {
panic(err)
}
return v
}
func readInConfig(v *viper.Viper) error {
if v.IsSet(cmdConfig) {
if err := readConfig(v); err != nil {
return err
}
}
if v.IsSet(cmdConfigDir) {
if err := readConfigDir(v); err != nil {
return err
}
}
return nil
}
func readConfigDir(v *viper.Viper) error {
cfgSubConfigDir := v.GetString(cmdConfigDir)
entries, err := os.ReadDir(cfgSubConfigDir)
if err != nil {
return err
}
for _, entry := range entries {
if entry.IsDir() {
continue
}
ext := path.Ext(entry.Name())
if ext != ".yaml" && ext != ".yml" {
continue
}
if err = mergeConfig(v, path.Join(cfgSubConfigDir, entry.Name())); err != nil {
return err
}
}
return nil
}
func readConfig(v *viper.Viper) error {
for _, fileName := range v.GetStringSlice(cmdConfig) {
if err := mergeConfig(v, fileName); err != nil {
return err
}
}
return nil
}
func mergeConfig(v *viper.Viper, fileName string) error {
cfgFile, err := os.Open(fileName)
if err != nil {
return err
}
defer func() {
if err2 := cfgFile.Close(); err2 != nil {
panic(err2)
}
}()
err = v.MergeConfig(cfgFile)
return err
}
func printVersion() {
fmt.Printf("%s\nVersion: %s\nGoVersion: %s\n", componentName, Version, runtime.Version())
}