Introduce default configuration file which is embedded into the binary.

Proper LoadConfig function with error status. Close #1
Separate InitLog function with error return.
This commit is contained in:
Kleissner
2021-02-28 14:46:16 +01:00
parent ea05439262
commit aca6d65044
5 changed files with 49 additions and 31 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,3 @@
*.exe
log.txt
*debug_bin
*.yaml

2
Config Default.yaml Normal file
View File

@@ -0,0 +1,2 @@
LogFile: Log.txt
SeedList: []

View File

@@ -7,11 +7,10 @@ Author: Peter Kleissner
package core
import (
"fmt"
_ "embed" // Required for embedding default Config file
"io/ioutil"
"log"
"os"
"strings"
"gopkg.in/yaml.v3"
)
@@ -19,8 +18,6 @@ import (
// Version is the current core library version
const Version = "0.1"
const configFile = "Settings.yaml"
var config struct {
LogFile string `yaml:"LogFile"` // Log file
@@ -40,34 +37,35 @@ type peerSeed struct {
Address []string `yaml:"Address"` // IP:Port
}
// loadConfig reads the YAML configuration file
func loadConfig() {
cfg, err := ioutil.ReadFile(configFile)
if err != nil && strings.Contains(err.Error(), "system cannot find the file specified") {
// Does not exist. Use default values.
config.LogFile = "Log.txt"
var configFile string
//go:embed "Config Default.yaml"
var defaultConfig []byte
// LoadConfig reads the YAML configuration file
// If an error is returned, the application shall exit.
// Status: 0 = Unknown error checking config file, 1 = Error reading config file, 2 = Error parsing config file, 3 = Success
func LoadConfig(filename string) (status int, err error) {
var configData []byte
configFile = filename
// check if the file is non existent or empty
stats, err := os.Stat(filename)
if err != nil && os.IsNotExist(err) || err == nil && stats.Size() == 0 {
configData = defaultConfig
} else if err != nil {
fmt.Printf("Configuration file '%s' could not be read. Error: %s\n", configFile, err.Error())
os.Exit(1)
} else {
// read existing config
err = yaml.Unmarshal(cfg, &config)
if err != nil {
fmt.Printf("Configuration file '%s' could not be read. Please make sure it contains valid YAML data. Error: %v\n", configFile, err.Error())
os.Exit(1)
}
return 0, err
} else if configData, err = ioutil.ReadFile(filename); err != nil {
return 1, err
}
// redirect all output to the log file
logFile, err := os.OpenFile(config.LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
// parse the config
err = yaml.Unmarshal(configData, &config)
if err != nil {
fmt.Printf("Error creating log file '%s': %v\n", config.LogFile, err)
return 2, err
}
// defer logFile.Close() // has to remain open until program closes
log.SetOutput(logFile)
log.Printf("---- Peernet Command-Line Client " + Version + " ----\n")
return 3, nil
}
func saveConfig() {
@@ -83,3 +81,17 @@ func saveConfig() {
return
}
}
// InitLog redirects subsequent log messages into the default log file specified in the configuration
func InitLog() (err error) {
logFile, err := os.OpenFile(config.LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
return err
}
//defer logFile.Close() // has to remain open until program closes
log.SetOutput(logFile)
log.Printf("---- Peernet Command-Line Client " + Version + " ----\n")
return nil
}

View File

@@ -6,8 +6,8 @@ Author: Peter Kleissner
package core
func init() {
loadConfig()
// Init initializes the client. The config must be loaded first!
func Init() {
initPeerID()
initMulticastIPv6()
initBroadcastIPv4()

View File

@@ -12,7 +12,7 @@ Current version: 0.1 (pre-alpha)
## Dependencies
Before compiling, make sure to download and update all 3rd party packages:
Go 1.16 or higher is required. Before compiling, make sure to download and update all 3rd party packages:
```
go get -u github.com/btcsuite/btcd/btcec
@@ -24,12 +24,17 @@ go get -u lukechampine.com/blake3
Peernet follows a "zeroconf" approach, meaning there is no manual configuration required. However, in certain cases such as providing root peers [1] that shall listen on a fixed IP and port, it is desirable to create a config file.
The name of the config file is hard-coded to `Settings.yaml`. If it does not exist, it will be created with default values. It uses the YAML format. Any public/private keys in the config are hex encoded. Here are some notable settings:
The name of the config file is passed to the function `LoadConfig`. If it does not exist, it will be created with the values from the file `Config Default.yaml`. It uses the YAML format. Any public/private keys in the config are hex encoded. Here are some notable settings:
* `PrivateKey` The users Private Key hex encoded. The users public key is derived from it.
* `ListenWorkers` defines the count of concurrent workers processing packets (decrypting them and then taking action). Default 2.
* `Listen` defines IP:Port combinations to listen on. If not specified, it will listen on all IPs. You can specify an IP but port 0 for auto port selection. IPv6 addresses must be in the format "[IPv6]:Port".
[1] Root peer = A peer operated by a known trusted entity. They allow to speed up the network including discovery of peers and data.
[1] Root peer = A peer operated by a known trusted entity. They allow to speed up the network including discovery of peers and data.
### Private Key
The Private Key is required to make any changes to the user's blockchain, including deleting, renaming, and adding files on Peernet, or nuking the blockchain. If the private key is lost, no write access will be possible. Users should always create a secure backup of their private key.
## Contributing