mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Manager refactor, part 1 (#4298)
* Move BackupDatabase and AnonymiseDatabase to internal/manager * Rename config.Instance to config.Config * Rename FFMPEG * Rework manager and initialization process * Fix Makefile * Tweak phasher * Fix config races * Fix setup error not clearing
This commit is contained in:
@@ -6,84 +6,107 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/stashapp/stash/internal/build"
|
||||
"github.com/stashapp/stash/pkg/fsutil"
|
||||
"github.com/stashapp/stash/pkg/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
initOnce sync.Once
|
||||
instanceOnce sync.Once
|
||||
)
|
||||
|
||||
type flagStruct struct {
|
||||
configFilePath string
|
||||
cpuProfilePath string
|
||||
nobrowser bool
|
||||
helpFlag bool
|
||||
versionFlag bool
|
||||
}
|
||||
|
||||
func GetInstance() *Instance {
|
||||
instanceOnce.Do(func() {
|
||||
instance = &Instance{
|
||||
main: viper.New(),
|
||||
overrides: viper.New(),
|
||||
var flags flagStruct
|
||||
|
||||
func init() {
|
||||
pflag.IP("host", net.IPv4(0, 0, 0, 0), "ip address for the host")
|
||||
pflag.Int("port", 9999, "port to serve from")
|
||||
pflag.StringVarP(&flags.configFilePath, "config", "c", "", "config file to use")
|
||||
pflag.BoolVar(&flags.nobrowser, "nobrowser", false, "Don't open a browser window after launch")
|
||||
}
|
||||
|
||||
// Called at startup
|
||||
func Initialize() (*Config, error) {
|
||||
cfg := &Config{
|
||||
main: viper.New(),
|
||||
overrides: viper.New(),
|
||||
}
|
||||
|
||||
cfg.initOverrides()
|
||||
|
||||
err := cfg.initConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cfg.isNewSystem {
|
||||
if cfg.Validate() == nil {
|
||||
// system has been initialised by the environment
|
||||
cfg.isNewSystem = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if !cfg.isNewSystem {
|
||||
cfg.setExistingSystemDefaults()
|
||||
|
||||
err := cfg.SetInitialConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = cfg.Write()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = cfg.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
instance = cfg
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
// Called by tests to initialize an empty config
|
||||
func InitializeEmpty() *Config {
|
||||
cfg := &Config{
|
||||
main: viper.New(),
|
||||
overrides: viper.New(),
|
||||
}
|
||||
instance = cfg
|
||||
return instance
|
||||
}
|
||||
|
||||
func Initialize() (*Instance, error) {
|
||||
var err error
|
||||
initOnce.Do(func() {
|
||||
flags := initFlags()
|
||||
|
||||
if flags.helpFlag {
|
||||
pflag.Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if flags.versionFlag {
|
||||
fmt.Printf(build.VersionString() + "\n")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
overrides := makeOverrideConfig()
|
||||
|
||||
_ = GetInstance()
|
||||
instance.overrides = overrides
|
||||
instance.cpuProfilePath = flags.cpuProfilePath
|
||||
// instance.configUpdates = make(chan int)
|
||||
|
||||
if err = initConfig(instance, flags); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if instance.isNewSystem {
|
||||
if instance.Validate() == nil {
|
||||
// system has been initialised by the environment
|
||||
instance.isNewSystem = false
|
||||
}
|
||||
}
|
||||
|
||||
if !instance.isNewSystem {
|
||||
err = instance.setExistingSystemDefaults()
|
||||
if err == nil {
|
||||
err = instance.SetInitialConfig()
|
||||
}
|
||||
}
|
||||
})
|
||||
return instance, err
|
||||
func bindEnv(v *viper.Viper, key string) {
|
||||
if err := v.BindEnv(key); err != nil {
|
||||
panic(fmt.Sprintf("unable to set environment key (%v): %v", key, err))
|
||||
}
|
||||
}
|
||||
|
||||
func initConfig(instance *Instance, flags flagStruct) error {
|
||||
v := instance.main
|
||||
func (i *Config) initOverrides() {
|
||||
v := i.overrides
|
||||
|
||||
if err := v.BindPFlags(pflag.CommandLine); err != nil {
|
||||
logger.Infof("failed to bind flags: %v", err)
|
||||
}
|
||||
|
||||
v.SetEnvPrefix("stash") // will be uppercased automatically
|
||||
bindEnv(v, "host") // STASH_HOST
|
||||
bindEnv(v, "port") // STASH_PORT
|
||||
bindEnv(v, "external_host") // STASH_EXTERNAL_HOST
|
||||
bindEnv(v, "generated") // STASH_GENERATED
|
||||
bindEnv(v, "metadata") // STASH_METADATA
|
||||
bindEnv(v, "cache") // STASH_CACHE
|
||||
bindEnv(v, "stash") // STASH_STASH
|
||||
}
|
||||
|
||||
func (i *Config) initConfig() error {
|
||||
v := i.main
|
||||
|
||||
// The config file is called config. Leave off the file extension.
|
||||
v.SetConfigName("config")
|
||||
@@ -105,11 +128,11 @@ func initConfig(instance *Instance, flags flagStruct) error {
|
||||
|
||||
// if file does not exist, assume it is a new system
|
||||
if exists, _ := fsutil.FileExists(configFile); !exists {
|
||||
instance.isNewSystem = true
|
||||
i.isNewSystem = true
|
||||
|
||||
// ensure we can write to the file
|
||||
if err := fsutil.Touch(configFile); err != nil {
|
||||
return fmt.Errorf(`could not write to provided config path "%s": %s`, configFile, err.Error())
|
||||
return fmt.Errorf(`could not write to provided config path "%s": %v`, configFile, err)
|
||||
} else {
|
||||
// remove the file
|
||||
os.Remove(configFile)
|
||||
@@ -123,7 +146,7 @@ func initConfig(instance *Instance, flags flagStruct) error {
|
||||
// if not found, assume its a new system
|
||||
var notFoundErr viper.ConfigFileNotFoundError
|
||||
if errors.As(err, ¬FoundErr) {
|
||||
instance.isNewSystem = true
|
||||
i.isNewSystem = true
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
@@ -131,48 +154,3 @@ func initConfig(instance *Instance, flags flagStruct) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func initFlags() flagStruct {
|
||||
flags := flagStruct{}
|
||||
|
||||
pflag.IP("host", net.IPv4(0, 0, 0, 0), "ip address for the host")
|
||||
pflag.Int("port", 9999, "port to serve from")
|
||||
pflag.StringVarP(&flags.configFilePath, "config", "c", "", "config file to use")
|
||||
pflag.StringVar(&flags.cpuProfilePath, "cpuprofile", "", "write cpu profile to file")
|
||||
pflag.BoolVar(&flags.nobrowser, "nobrowser", false, "Don't open a browser window after launch")
|
||||
pflag.BoolVarP(&flags.helpFlag, "help", "h", false, "show this help text and exit")
|
||||
pflag.BoolVarP(&flags.versionFlag, "version", "v", false, "show version number and exit")
|
||||
|
||||
pflag.Parse()
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
func initEnvs(viper *viper.Viper) {
|
||||
viper.SetEnvPrefix("stash") // will be uppercased automatically
|
||||
bindEnv(viper, "host") // STASH_HOST
|
||||
bindEnv(viper, "port") // STASH_PORT
|
||||
bindEnv(viper, "external_host") // STASH_EXTERNAL_HOST
|
||||
bindEnv(viper, "generated") // STASH_GENERATED
|
||||
bindEnv(viper, "metadata") // STASH_METADATA
|
||||
bindEnv(viper, "cache") // STASH_CACHE
|
||||
bindEnv(viper, "stash") // STASH_STASH
|
||||
}
|
||||
|
||||
func bindEnv(viper *viper.Viper, key string) {
|
||||
if err := viper.BindEnv(key); err != nil {
|
||||
panic(fmt.Sprintf("unable to set environment key (%v): %v", key, err))
|
||||
}
|
||||
}
|
||||
|
||||
func makeOverrideConfig() *viper.Viper {
|
||||
viper := viper.New()
|
||||
|
||||
if err := viper.BindPFlags(pflag.CommandLine); err != nil {
|
||||
logger.Infof("failed to bind flags: %s", err.Error())
|
||||
}
|
||||
|
||||
initEnvs(viper)
|
||||
|
||||
return viper
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user