tendermint/config/config.go

183 lines
4.2 KiB
Go
Raw Normal View History

2014-06-06 11:57:22 -07:00
package config
import (
2014-07-01 14:50:24 -07:00
"encoding/json"
"errors"
2014-07-12 14:52:31 -07:00
"flag"
2014-07-01 14:50:24 -07:00
"fmt"
"io/ioutil"
2015-01-06 15:51:41 -08:00
"net"
2014-07-01 14:50:24 -07:00
"os"
"path/filepath"
"strings"
2014-06-06 11:57:22 -07:00
. "github.com/tendermint/tendermint/common"
)
2014-06-06 11:57:22 -07:00
2014-11-27 04:04:07 -08:00
//-----------------------------------------------------------------------------j
// Configuration types
2014-06-06 11:57:22 -07:00
type ConfigType struct {
2014-10-22 17:20:44 -07:00
Network string
LAddr string
SeedNode string
DB DBConfig
2014-11-27 04:04:07 -08:00
Alert AlertConfig
SMTP SMTPConfig
RPC RPCConfig
2014-06-06 11:57:22 -07:00
}
type DBConfig struct {
Backend string
Dir string
2014-06-06 11:57:22 -07:00
}
2014-11-27 04:04:07 -08:00
type AlertConfig struct {
MinInterval int
TwilioSid string
TwilioToken string
TwilioFrom string
TwilioTo string
EmailRecipients []string
}
type SMTPConfig struct {
User string
Password string
Host string
Port uint
}
type RPCConfig struct {
2015-01-06 15:51:41 -08:00
HTTPLAddr string
2014-11-27 04:04:07 -08:00
}
func (cfg *ConfigType) validate() error {
2014-08-10 16:35:08 -07:00
if cfg.Network == "" {
cfg.Network = defaultConfig.Network
}
if cfg.LAddr == "" {
cfg.LAddr = defaultConfig.LAddr
2014-07-01 14:50:24 -07:00
}
2014-10-22 17:20:44 -07:00
if cfg.SeedNode == "" {
cfg.SeedNode = defaultConfig.SeedNode
2014-07-01 14:50:24 -07:00
}
if cfg.DB.Backend == "" {
return errors.New("DB.Backend must be set")
2014-07-01 14:50:24 -07:00
}
2015-01-06 15:51:41 -08:00
if cfg.RPC.HTTPLAddr == "" {
fmt.Println("Set RPC.HTTPLAddr to \"0.0.0.0:8888\" in your config.json to enable the RPC API server.")
} else {
_, port, err := net.SplitHostPort(cfg.RPC.HTTPLAddr)
if err != nil {
return errors.New(Fmt("RPC.HTTPLAddr is invalid. %v", err))
}
if port == "" || port == "0" {
return errors.New("RPC.HTTPLAddr is invalid. Port number must be defined")
}
}
2014-07-01 14:50:24 -07:00
return nil
2014-06-06 11:57:22 -07:00
}
func (cfg *ConfigType) bytes() []byte {
2014-07-08 15:33:26 -07:00
configBytes, err := json.MarshalIndent(cfg, "", "\t")
2014-07-01 14:50:24 -07:00
if err != nil {
panic(err)
}
return configBytes
2014-06-06 11:57:22 -07:00
}
func (cfg *ConfigType) write(configFile string) {
2014-07-01 14:50:24 -07:00
if strings.Index(configFile, "/") != -1 {
err := os.MkdirAll(filepath.Dir(configFile), 0700)
if err != nil {
panic(err)
}
}
err := ioutil.WriteFile(configFile, cfg.bytes(), 0600)
if err != nil {
panic(err)
}
2014-06-06 11:57:22 -07:00
}
//-----------------------------------------------------------------------------
var rootDir string
var defaultConfig ConfigType
func init() {
// Get RootDir
rootDir = os.Getenv("TMROOT")
if rootDir == "" {
rootDir = os.Getenv("HOME") + "/.tendermint"
}
// Compute defaultConfig
defaultConfig = ConfigType{
Network: "tendermint_testnet0",
LAddr: "0.0.0.0:0",
SeedNode: "",
DB: DBConfig{
Backend: "leveldb",
Dir: DataDir(),
},
Alert: AlertConfig{},
SMTP: SMTPConfig{},
RPC: RPCConfig{
2015-01-06 15:51:41 -08:00
HTTPLAddr: "0.0.0.0:0",
},
}
}
func ConfigFile() string { return rootDir + "/config.json" }
func GenesisFile() string { return rootDir + "/genesis.json" }
func AddrBookFile() string { return rootDir + "/addrbook.json" }
func PrivValidatorFile() string { return rootDir + "/priv_validator.json" }
func DataDir() string { return rootDir + "/data" }
2014-12-31 22:13:49 -08:00
// The actual global config singleton object.
var Config ConfigType
func parseFlags(flags *flag.FlagSet, args []string) (printHelp bool) {
flags.BoolVar(&printHelp, "help", false, "Print this help message.")
flags.StringVar(&Config.LAddr, "laddr", Config.LAddr, "Listen address. (0.0.0.0:0 means any interface, any port)")
flags.StringVar(&Config.SeedNode, "seed", Config.SeedNode, "Address of seed node")
2015-01-06 15:51:41 -08:00
flags.StringVar(&Config.RPC.HTTPLAddr, "rpc_http_laddr", Config.RPC.HTTPLAddr, "RPC listen address. (0.0.0.0:0 means any interface, any port)")
flags.Parse(args)
return
}
func ParseFlags(args []string) {
configFile := ConfigFile()
// try to read configuration from file. if missing, write default
configBytes, err := ioutil.ReadFile(configFile)
if err != nil {
defaultConfig.write(configFile)
fmt.Println("Config file written to config.json. Please edit & run again")
os.Exit(1)
return
}
// try to parse configuration. on error, die
Config = ConfigType{}
err = json.Unmarshal(configBytes, &Config)
if err != nil {
2015-01-06 15:51:41 -08:00
Exit(Fmt("Invalid configuration file %s:\n%v\n", configFile, err))
}
err = Config.validate()
if err != nil {
2015-01-06 15:51:41 -08:00
Exit(Fmt("Invalid configuration file %s:\n%v\n", configFile, err))
}
// try to parse arg flags, which can override file configuration.
flags := flag.NewFlagSet("main", flag.ExitOnError)
printHelp := parseFlags(flags, args)
if printHelp {
flags.PrintDefaults()
os.Exit(0)
}
}