mirror of https://github.com/curusarn/resh
parent
439e60dab8
commit
bafb244588
@ -0,0 +1,46 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"os" |
||||
|
||||
"github.com/curusarn/resh/internal/cfg" |
||||
"github.com/curusarn/resh/internal/logger" |
||||
"go.uber.org/zap" |
||||
) |
||||
|
||||
// info passed during build
|
||||
var version string |
||||
var commit string |
||||
var developement bool |
||||
|
||||
func main() { |
||||
errDo := doConfigSetup() |
||||
config, errCfg := cfg.New() |
||||
logger, _ := logger.New("config-setup", config.LogLevel, developement) |
||||
defer logger.Sync() // flushes buffer, if any
|
||||
|
||||
if errDo != nil { |
||||
logger.Error("Config setup failed", zap.Error(errDo)) |
||||
// TODO: better error message for people
|
||||
fmt.Fprintf(os.Stderr, "ERROR: %v\n", errDo) |
||||
} |
||||
if errCfg != nil { |
||||
logger.Error("Error while getting configuration", zap.Error(errCfg)) |
||||
} |
||||
} |
||||
|
||||
func doConfigSetup() error { |
||||
err := cfg.Touch() |
||||
if err != nil { |
||||
return fmt.Errorf("could not touch config file: %w", err) |
||||
} |
||||
changes, err := cfg.Migrate() |
||||
if err != nil { |
||||
return fmt.Errorf("could not migrate config file version: %v", err) |
||||
} |
||||
if changes { |
||||
fmt.Printf("Config file format has changed - your config was updated to reflect the changes.\n") |
||||
} |
||||
return nil |
||||
} |
||||
@ -0,0 +1,110 @@ |
||||
package cfg |
||||
|
||||
import ( |
||||
"fmt" |
||||
"os" |
||||
|
||||
"github.com/BurntSushi/toml" |
||||
) |
||||
|
||||
// Touch config file
|
||||
func Touch() error { |
||||
path, err := getConfigPath() |
||||
if err != nil { |
||||
return fmt.Errorf("could not get config file path: %w", err) |
||||
} |
||||
file, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666) |
||||
if err != nil { |
||||
return fmt.Errorf("could not open/create config file: %w", err) |
||||
} |
||||
err = file.Close() |
||||
if err != nil { |
||||
return fmt.Errorf("could not close config file: %w", err) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// Migrate old config versions to current config version
|
||||
// returns true if any changes were made to the config
|
||||
func Migrate() (bool, error) { |
||||
path, err := getConfigPath() |
||||
if err != nil { |
||||
return false, fmt.Errorf("could not get config file path: %w", err) |
||||
} |
||||
configF, err := readConfig(path) |
||||
if err != nil { |
||||
return false, fmt.Errorf("could not read config: %w", err) |
||||
} |
||||
const current = "v1" |
||||
if configF.ConfigVersion != nil && *configF.ConfigVersion == current { |
||||
return false, nil |
||||
} |
||||
|
||||
if configF.ConfigVersion == nil { |
||||
configF, err = legacyToV1(configF) |
||||
if err != nil { |
||||
return true, fmt.Errorf("error converting config from version 'legacy' to 'v1': %w", err) |
||||
} |
||||
} |
||||
|
||||
if *configF.ConfigVersion != current { |
||||
return false, fmt.Errorf("unrecognized config version: '%s'", *configF.ConfigVersion) |
||||
} |
||||
err = writeConfig(configF, path) |
||||
if err != nil { |
||||
return true, fmt.Errorf("could not write migrated config: %w", err) |
||||
} |
||||
return true, nil |
||||
} |
||||
|
||||
func writeConfig(config *configFile, path string) error { |
||||
file, err := os.OpenFile(path, os.O_RDWR|os.O_TRUNC, 0666) |
||||
if err != nil { |
||||
return fmt.Errorf("could not open config for writing: %w", err) |
||||
} |
||||
defer file.Close() |
||||
err = toml.NewEncoder(file).Encode(config) |
||||
if err != nil { |
||||
return fmt.Errorf("could not encode config: %w", err) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func legacyToV1(config *configFile) (*configFile, error) { |
||||
if config.ConfigVersion != nil { |
||||
return nil, fmt.Errorf("config version is not 'legacy': '%s'", *config.ConfigVersion) |
||||
} |
||||
version := "v1" |
||||
newConf := configFile{ |
||||
ConfigVersion: &version, |
||||
} |
||||
// Remove defaults
|
||||
if config.Port != nil && *config.Port != 2627 { |
||||
newConf.Port = config.Port |
||||
} |
||||
if config.SesswatchPeriodSeconds != nil && *config.SesswatchPeriodSeconds != 120 { |
||||
newConf.SesswatchPeriodSeconds = config.SesswatchPeriodSeconds |
||||
} |
||||
if config.SesshistInitHistorySize != nil && *config.SesshistInitHistorySize != 1000 { |
||||
newConf.SesshistInitHistorySize = config.SesshistInitHistorySize |
||||
} |
||||
if config.BindControlR != nil && *config.BindControlR != true { |
||||
newConf.BindControlR = config.BindControlR |
||||
} |
||||
if config.Debug != nil && *config.Debug != false { |
||||
newConf.Debug = config.Debug |
||||
} |
||||
return &newConf, nil |
||||
} |
||||
|
||||
// func v1ToV2(config *configFile) (*configFile, error) {
|
||||
// if *config.ConfigVersion != "v1" {
|
||||
// return nil, fmt.Errorf("config version is not 'legacy': '%s'", *config.ConfigVersion)
|
||||
// }
|
||||
// version := "v2"
|
||||
// newConf := configFile{
|
||||
// ConfigVersion: &version,
|
||||
// // Here goes all config fields - no need to prune defaults like we do for legacy
|
||||
// }
|
||||
// return &newConf, nil
|
||||
// }
|
||||
Loading…
Reference in new issue