From 4e5fec8f3ba622dc814eaed6ed523cd08f155ec6 Mon Sep 17 00:00:00 2001 From: jholdstock Date: Thu, 30 May 2024 09:39:15 +0100 Subject: [PATCH] vspadmin: Write default config file. A new command in vspadmin writes the default config file for a new vspd deployment. The behaviour is removed from vspd and documentation has been updated to reflect the change. --- cmd/vspadmin/README.md | 12 +++++++++++- cmd/vspadmin/main.go | 40 +++++++++++++++++++++++++++++++++++++++- docs/deployment.md | 13 +++++++++---- internal/vspd/config.go | 19 ++++--------------- 4 files changed, 63 insertions(+), 21 deletions(-) diff --git a/cmd/vspadmin/README.md b/cmd/vspadmin/README.md index 0cee4dc3..e5727a74 100644 --- a/cmd/vspadmin/README.md +++ b/cmd/vspadmin/README.md @@ -26,5 +26,15 @@ used for collecting fees as a parameter. Example: ```no-highlight - go run ./cmd/vspadmin createdatabase +$ go run ./cmd/vspadmin createdatabase +``` + +### `writeconfig` + +Writes a config file with default values to the application home directory. + +Example: + +```no-highlight +$ go run ./cmd/vspadmin writeconfig ``` diff --git a/cmd/vspadmin/main.go b/cmd/vspadmin/main.go index 97aedfbd..1b6ef27b 100644 --- a/cmd/vspadmin/main.go +++ b/cmd/vspadmin/main.go @@ -13,11 +13,13 @@ import ( "github.com/decred/dcrd/hdkeychain/v3" "github.com/decred/vspd/database" "github.com/decred/vspd/internal/config" + "github.com/decred/vspd/internal/vspd" "github.com/jessevdk/go-flags" ) const ( - dbFilename = "vspd.db" + configFilename = "vspd.conf" + dbFilename = "vspd.db" ) type conf struct { @@ -72,6 +74,32 @@ func createDatabase(homeDir string, feeXPub string, network *config.Network) err return nil } +func writeConfig(homeDir string) error { + configFile := filepath.Join(homeDir, configFilename) + + // Return an error if the config file already exists. + if fileExists(configFile) { + return fmt.Errorf("config file already exists in %s", homeDir) + } + + // Ensure the directory exists. + err := os.MkdirAll(homeDir, 0700) + if err != nil { + return fmt.Errorf("failed to create directory: %w", err) + } + + // Write a config file with default values to the provided home directory. + preParser := flags.NewParser(&vspd.DefaultConfig, flags.None) + preIni := flags.NewIniParser(preParser) + err = preIni.WriteFile(configFile, + flags.IniIncludeComments|flags.IniIncludeDefaults) + if err != nil { + return fmt.Errorf("failed to create config file: %w", err) + } + + return nil +} + // run is the real main function for vspadmin. It is necessary to work around // the fact that deferred functions do not run when os.Exit() is called. func run() int { @@ -117,6 +145,16 @@ func run() int { log("New %s vspd database created in %s", network.Name, cfg.HomeDir) + case "writeconfig": + err = writeConfig(cfg.HomeDir) + if err != nil { + log("writeconfig failed: %v", err) + return 1 + } + + log("Config file with default values written to %s", cfg.HomeDir) + log("Edit the file and fill in values specific to your vspd deployment") + default: log("%q is not a valid command", remainingArgs[0]) return 1 diff --git a/docs/deployment.md b/docs/deployment.md index 01382753..689b5289 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -92,9 +92,13 @@ vspd. **Do not run a voting wallet on your webserver.** receiving `blockconnected` notifications, and for broadcasting and checking the status of fee transactions. -1. Run `vspd` with no arguments to write a default config file. Modify the - config file to set your dcrd and dcrwallet connection details, and any other - required customization. +1. Use [vspadmin](./cmd/vspadmin) to write a config file containing default + values. Modify the config file to set your dcrd and dcrwallet connection + details, and any other required customization. + + ```no-highlight + $ go run ./cmd/vspadmin writeconfig + ``` 1. Use [vspadmin](./cmd/vspadmin) to initialize a vpsd database. The xpub key to be used for collecting fees must be passed in as an argument. @@ -103,7 +107,8 @@ vspd. **Do not run a voting wallet on your webserver.** $ go run ./cmd/vspadmin createdatabase tpubVppjaMjp8GEW... ``` -1. Once the database is initialized, vspd can be started for normal operation. +1. Once the database is initialized and required fields in the config file have + been entered, vspd can be started for normal operation. 1. Configure nginx with SSL and set up reverse proxy to forward requests to the vspd process. nginx must also set the `X-Forwarded-For` header to make vspd diff --git a/internal/vspd/config.go b/internal/vspd/config.go index cd55db78..8dc65e6a 100644 --- a/internal/vspd/config.go +++ b/internal/vspd/config.go @@ -240,25 +240,14 @@ func LoadConfig() (*Config, error) { return nil, err } - // Create a default config file when one does not exist and the user did - // not specify an override. + // Load additional config from file. configFile := filepath.Join(cfg.HomeDir, configFilename) if !fileExists(configFile) { - preIni := flags.NewIniParser(preParser) - err = preIni.WriteFile(configFile, - flags.IniIncludeComments|flags.IniIncludeDefaults) - if err != nil { - return nil, fmt.Errorf("error creating a default "+ - "config file: %w", err) - } - fmt.Printf("Config file with default values written to %s\n", configFile) - - // File created, user now has to fill in values. Proceeding with the - // default file just causes errors. - os.Exit(0) + err := fmt.Errorf("config file does not exist at %s", configFile) + fmt.Fprintln(os.Stderr, err) + return nil, err } - // Load additional config from file. parser := flags.NewParser(&cfg, flags.None) err = flags.NewIniParser(parser).ParseFile(configFile)