Skip to content

Commit

Permalink
CLI: add database flag; improve systemd db check (#17993)
Browse files Browse the repository at this point in the history
  • Loading branch information
naltatis authored Jan 21, 2025
1 parent e8630e6 commit 8f8bc0e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 28 deletions.
10 changes: 8 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ import (
const (
rebootDelay = 15 * time.Minute // delayed reboot on error
serviceDB = "/var/lib/evcc/evcc.db"
userDB = "~/.evcc/evcc.db"
)

var (
log = util.NewLogger("main")
cfgFile string
log = util.NewLogger("main")
cfgFile string
cfgDatabase string

ignoreEmpty = "" // ignore empty keys
ignoreLogs = []string{"log"} // ignore log messages, including warn/error
Expand All @@ -63,6 +65,7 @@ func init() {

// global options
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "Config file (default \"~/evcc.yaml\" or \"/etc/evcc.yaml\")")
rootCmd.PersistentFlags().StringVarP(&cfgDatabase, "database", "d", "", "Database location (default \"~/.evcc/evcc.db\")")
rootCmd.PersistentFlags().BoolP("help", "h", false, "Help")
rootCmd.PersistentFlags().Bool(flagHeaders, false, flagHeadersDescription)
rootCmd.PersistentFlags().Bool(flagIgnoreDatabase, false, flagIgnoreDatabaseDescription)
Expand Down Expand Up @@ -97,6 +100,9 @@ func initConfig() {

viper.SetConfigName("evcc")
}
if cfgDatabase != "" {
viper.Set("Database.Dsn", cfgDatabase)
}

viper.SetEnvPrefix("evcc")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
Expand Down
61 changes: 35 additions & 26 deletions cmd/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ var conf = globalconfig.All{
},
Database: globalconfig.DB{
Type: "sqlite",
Dsn: "~/.evcc/evcc.db",
Dsn: "",
},
}

Expand All @@ -81,22 +81,6 @@ func nameValid(name string) error {
return nil
}

func tokenDanger(conf []config.Named) bool {
problematic := []string{"tesla", "psa", "opel", "citroen", "ds", "peugeot"}

for _, cc := range conf {
if slices.Contains(problematic, cc.Type) {
return true
}
template, ok := cc.Other["template"].(string)
if ok && cc.Type == "template" && slices.Contains(problematic, template) {
return true
}
}

return false
}

func loadConfigFile(conf *globalconfig.All, checkDB bool) error {
err := viper.ReadInConfig()

Expand All @@ -112,17 +96,33 @@ func loadConfigFile(conf *globalconfig.All, checkDB bool) error {
}
}

// check service database
if _, err := os.Stat(serviceDB); err == nil && checkDB && conf.Database.Dsn != serviceDB && tokenDanger(conf.Vehicles) {
log.FATAL.Fatal(`
// user did not specify a database path
if conf.Database.Dsn == "" {
// check if service database exists
if _, err := os.Stat(serviceDB); err == nil && checkDB {
// service database found, ask user what to do
sudo := ""
if !isWritable(serviceDB) {
sudo = "sudo "
}
log.FATAL.Fatal(`
Found systemd service database at "` + serviceDB + `", evcc has been invoked with no explicit database path.
Running the same config with multiple databases can lead to expiring vehicle tokens.
If you want to use the existing service database run the following command:
` + sudo + `evcc --database ` + serviceDB + `
If you want to create a new user-space database run the following command:
Found systemd service database at "` + serviceDB + `", evcc has been invoked with database "` + conf.Database.Dsn + `".
Running evcc with vehicles configured in evcc.yaml may lead to expiring the yaml configuration's vehicle tokens.
This is due to the fact, that the token refresh will be saved to the local instead of the service's database.
If you have vehicles with touchy tokens like PSA or Tesla, make sure to remove vehicle configuration from the yaml file.
evcc --database ~/.evcc/evcc.db
If you know what you're doing, you can skip the database check with the --ignore-db flag.
`)
}

If you know what you're doing, you can run evcc ignoring the service database with the --ignore-db flag.
`)
// default to user database
conf.Database.Dsn = userDB
}

// parse log levels after reading config
Expand All @@ -133,6 +133,15 @@ If you know what you're doing, you can run evcc ignoring the service database wi
return err
}

func isWritable(filePath string) bool {
file, err := os.OpenFile(filePath, os.O_WRONLY, 0666)
if err != nil {
return false
}
file.Close()
return true
}

func configureCircuits(conf []config.Named) error {
// migrate settings
if settings.Exists(keys.Circuits) {
Expand Down

0 comments on commit 8f8bc0e

Please sign in to comment.