From 756360ed8f2e057352208461e6f5ec724877aef9 Mon Sep 17 00:00:00 2001 From: Silas Davis <silas@monax.io> Date: Mon, 8 Jan 2018 18:17:25 +0000 Subject: [PATCH] CLI: switch to mow.cli package for CLI UI (because better), introduce spec and configure commands (providing chain making and logging configuration), and make 'burrow serve' the root command. Use a single marshallable config structs, introduce cascade of config sources for file-based, environment-based canonical configuration. Signed-off-by: Silas Davis <silas@monax.io> --- cmd/burrow.go | 93 ----------- cmd/burrow/main.go | 272 +++++++++++++++++++++++++++++-- cmd/serve.go | 238 --------------------------- config/config.go | 227 +++++--------------------- config/config_test.go | 29 +--- config/dump_config_test.go | 34 ---- config/module.go | 32 ---- config/templates.go | 325 ------------------------------------- config/viper.go | 58 ------- definitions/do.go | 87 ---------- server/server.go | 1 - 11 files changed, 310 insertions(+), 1086 deletions(-) delete mode 100644 cmd/burrow.go delete mode 100644 cmd/serve.go delete mode 100644 config/dump_config_test.go delete mode 100644 config/module.go delete mode 100644 config/templates.go delete mode 100644 config/viper.go delete mode 100644 definitions/do.go diff --git a/cmd/burrow.go b/cmd/burrow.go deleted file mode 100644 index 6fb48466..00000000 --- a/cmd/burrow.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package commands - -import ( - "os" - "strconv" - - "github.com/spf13/cobra" - - "github.com/hyperledger/burrow/definitions" - "github.com/hyperledger/burrow/version" -) - -var BurrowCmd = &cobra.Command{ - Use: "burrow", - Short: "burrow is the node server of a burrow chain", - Long: `burrow is the node server of a burrow chain. burrow combines -a modular consensus engine and application manager to run a chain to suit -your needs. - -Made with <3 by Monax Industries. - -Complete documentation is available at https://monax.io/docs -` + "\nVERSION:\n " + version.GetSemanticVersionString(), - Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, -} - -func Execute() { - do := definitions.NewDo() - AddGlobalFlags(do) - AddCommands(do) - BurrowCmd.Execute() -} - -func AddGlobalFlags(do *definitions.Do) { - BurrowCmd.PersistentFlags().BoolVarP(&do.Verbose, "verbose", "v", - defaultVerbose(), - "verbose output; more output than no output flags; less output than debug level; default respects $BURROW_VERBOSE") - BurrowCmd.PersistentFlags().BoolVarP(&do.Debug, "debug", "d", defaultDebug(), - "debug level output; the most output available for burrow; if it is too chatty use verbose flag; default respects $BURROW_DEBUG") -} - -func AddCommands(do *definitions.Do) { - BurrowCmd.AddCommand(buildServeCommand(do)) -} - -//------------------------------------------------------------------------------ -// Defaults - -// defaultVerbose is set to false unless the BURROW_VERBOSE environment -// variable is set to a parsable boolean. -func defaultVerbose() bool { - return setDefaultBool("BURROW_VERBOSE", false) -} - -// defaultDebug is set to false unless the BURROW_DEBUG environment -// variable is set to a parsable boolean. -func defaultDebug() bool { - return setDefaultBool("BURROW_DEBUG", false) -} - -// setDefaultBool returns the provided default value if the environment variable -// is not set or not parsable as a bool. -func setDefaultBool(environmentVariable string, defaultValue bool) bool { - value := os.Getenv(environmentVariable) - if value != "" { - if parsedValue, err := strconv.ParseBool(value); err == nil { - return parsedValue - } - } - return defaultValue -} - -func setDefaultString(envVar, def string) string { - env := os.Getenv(envVar) - if env != "" { - return env - } - return def -} diff --git a/cmd/burrow/main.go b/cmd/burrow/main.go index e5133ab8..21330205 100644 --- a/cmd/burrow/main.go +++ b/cmd/burrow/main.go @@ -1,23 +1,263 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package main import ( - commands "github.com/hyperledger/burrow/cmd" + "fmt" + "os" + + "strings" + + "github.com/hyperledger/burrow/config" + "github.com/hyperledger/burrow/config/source" + "github.com/hyperledger/burrow/genesis" + "github.com/hyperledger/burrow/genesis/spec" + "github.com/hyperledger/burrow/keys" + logging_config "github.com/hyperledger/burrow/logging/config" + "github.com/hyperledger/burrow/logging/config/presets" + "github.com/hyperledger/burrow/logging/loggers" + "github.com/jawher/mow.cli" ) func main() { - commands.Execute() + burrow := cli.App("burrow", "The EVM smart contract machine with Tendermint consensus") + + genesisOpt := burrow.StringOpt("g genesis", "", + "Use the specified genesis JSON file rather than a key in the main config, use - to read from STDIN") + + configOpt := burrow.StringOpt("c config", "", + "Use the a specified burrow config TOML file") + + burrow.Spec = "[--config=<config file>] [--genesis=<genesis json file>]" + + burrow.Action = func() { + conf := new(config.BurrowConfig) + err := source.EachOf( + burrowConfigProvider(*configOpt), + source.FirstOf( + genesisDocProvider(*genesisOpt, false), + // Try working directory + genesisDocProvider(config.DefaultGenesisDocJSONFileName, true)), + ).Apply(conf) + if err != nil { + fatalf("could not obtain config: %v", err) + } + + kern, err := conf.Kernel() + if err != nil { + fatalf("could not create Burrow kernel: %v", err) + } + + err = kern.Boot() + if err != nil { + fatalf("could not boot Burrow kernel: %v", err) + } + kern.WaitForShutdown() + } + + burrow.Command("spec", + "Build a GenesisSpec that acts as a template for a GenesisDoc and the configure command", + func(cmd *cli.Cmd) { + tomlOpt := cmd.BoolOpt("t toml", false, "Emit GenesisSpec as TOML rather than the "+ + "default JSON") + + participantsOpt := cmd.IntOpt("p participant-accounts", 1, "Number of preset Participant type accounts") + + fullOpt := cmd.IntOpt("f full-accounts", 1, "Number of preset Full type accounts") + + cmd.Spec = "[--participant-accounts] [--full-accounts] [--toml]" + + cmd.Action = func() { + specs := make([]spec.GenesisSpec, 0, *participantsOpt+*fullOpt) + for i := 0; i < *participantsOpt; i++ { + specs = append(specs, spec.ParticipantAccount(i)) + } + for i := 0; i < *fullOpt; i++ { + specs = append(specs, spec.FullAccount(i)) + } + genesisSpec := spec.MergeGenesisSpecs(specs...) + if *tomlOpt { + os.Stdout.WriteString(source.TOMLString(genesisSpec)) + } else { + os.Stdout.WriteString(source.JSONString(genesisSpec)) + } + } + }) + + burrow.Command("configure", + "Create Burrow configuration by consuming a GenesisDoc or GenesisSpec, creating keys, and emitting the config", + func(cmd *cli.Cmd) { + genesisSpecOpt := cmd.StringOpt("s genesis-spec", "", + "A GenesisSpec to use as a template for a GenesisDoc that will be created along with keys") + + tomlInOpt := cmd.BoolOpt("t toml-in", false, "Consume GenesisSpec/GenesisDoc as TOML "+ + "rather than the JSON default") + + keysUrlOpt := cmd.StringOpt("k keys-url", "", fmt.Sprintf("Provide keys URL, default: %s", + keys.DefaultKeysConfig().URL)) + + jsonOutOpt := cmd.BoolOpt("j json-out", false, "Emit config in JSON rather than TOML "+ + "suitable for further processing or forming a separate genesis.json GenesisDoc") + + genesisDocOpt := cmd.StringOpt("g genesis-doc", "", "GenesisDoc JSON to embed in config") + + validatorIndexOpt := cmd.IntOpt("v validator-index", -1, + "Validator index (in validators list - GenesisSpec or GenesisDoc) from which to set ValidatorAddress") + + loggingOpt := cmd.StringOpt("l logging", "", + "Comma separated list of logging instructions which form a 'program' which is a depth-first "+ + "pre-order of instructions that will build the root logging sink. See 'burrow help' for more information.") + + describeLoggingOpt := cmd.BoolOpt("describe-logging", false, + "Print an exhaustive list of logging instructions available with the --logging option") + + cmd.Spec = "[--keys-url=<keys URL>] [--genesis-spec=<GenesisSpec file> | --genesis-doc=<GenesisDoc file>] " + + "[--validator-index=<index>] [--toml-in] [--json-out] [--logging=<logging program>] [--describe-logging]" + + cmd.Action = func() { + conf := config.DefaultBurrowConfig() + + if *configOpt != "" { + // If explicitly given a config file use it as a base: + err := source.FromTOMLFile(*configOpt, conf) + if err != nil { + fatalf("could not read base config file (as TOML): %v", err) + } + } + + if *describeLoggingOpt { + fmt.Printf("Usage:\n burrow configure -l INSTRUCTION[,...]\n\nBuilds a logging " + + "configuration by constructing a tree of logging sinks assembled from preset instructions " + + "that generate the tree while traversing it.\n\nLogging Instructions:\n") + for _, instruction := range presets.Instructons() { + fmt.Printf(" %-15s\t%s\n", instruction.Name(), instruction.Description()) + } + fmt.Printf("\nExample Usage:\n burrow configure -l include-any,info,stderr\n") + return + } + + if *keysUrlOpt != "" { + conf.Keys.URL = *keysUrlOpt + } + + if *genesisSpecOpt != "" { + genesisSpec := new(spec.GenesisSpec) + err := fromFile(*genesisSpecOpt, *tomlInOpt, genesisSpec) + if err != nil { + fatalf("could not read GenesisSpec: %v", err) + } + keyClient := keys.NewBurrowKeyClient(conf.Keys.URL, loggers.NewNoopInfoTraceLogger()) + conf.GenesisDoc, err = genesisSpec.GenesisDoc(keyClient) + if err != nil { + fatalf("could not realise GenesisSpec: %v", err) + } + } else if *genesisDocOpt != "" { + genesisDoc := new(genesis.GenesisDoc) + err := fromFile(*genesisSpecOpt, *tomlInOpt, genesisDoc) + if err != nil { + fatalf("could not read GenesisSpec: %v", err) + } + conf.GenesisDoc = genesisDoc + } + + if *validatorIndexOpt > -1 { + if conf.GenesisDoc == nil { + fatalf("Unable to set ValidatorAddress from provided validator-index since no " + + "GenesisDoc/GenesisSpec provided.") + } + if len(conf.GenesisDoc.Validators) < *validatorIndexOpt { + fatalf("validator-index of %v given but only %v validators specified in GenesisDoc", + *validatorIndexOpt, len(conf.GenesisDoc.Validators)) + } + conf.ValidatorAddress = &conf.GenesisDoc.Validators[*validatorIndexOpt].Address + } else if conf.GenesisDoc != nil && len(conf.GenesisDoc.Validators) > 0 { + // Pick first validator otherwise - might want to change this when we support non-validating node + conf.ValidatorAddress = &conf.GenesisDoc.Validators[0].Address + } + + if *loggingOpt != "" { + ops := strings.Split(*loggingOpt, ",") + sinkConfig, err := presets.BuildSinkConfig(ops...) + if err != nil { + fatalf("could not build logging configuration: %v\n\nTo see possible logging " + + "instructions run:\n burrow configure --describe-logging", err) + } + conf.Logging = &logging_config.LoggingConfig{ + RootSink: sinkConfig, + } + } + + if *jsonOutOpt { + os.Stdout.WriteString(conf.JSONString()) + } else { + os.Stdout.WriteString(conf.TOMLString()) + } + } + }) + + burrow.Command("help", + "Get more detailed or exhaustive options of selected commands or flags.", + func(cmd *cli.Cmd) { + + cmd.Spec = "[--participant-accounts] [--full-accounts] [--toml]" + + cmd.Action = func() { + } + }) + burrow.Run(os.Args) +} + +// Print informational output to Stderr +func printf(format string, args ...interface{}) { + fmt.Fprintf(os.Stderr, format+"\n", args...) +} + +func fatalf(format string, args ...interface{}) { + fmt.Fprintf(os.Stderr, format+"\n", args...) + os.Exit(1) +} + +func burrowConfigProvider(configFile string) source.ConfigProvider { + return source.FirstOf( + // Will fail if file doesn't exist, but still skipped it configFile == "" + source.TOMLFile(configFile, false), + source.Environment(config.DefaultBurrowConfigJSONEnvironmentVariable), + // Try working directory + source.TOMLFile(config.DefaultBurrowConfigTOMLFileName, true), + source.Default(config.DefaultBurrowConfig())) +} + +func genesisDocProvider(genesisFile string, skipNonExistent bool) source.ConfigProvider { + return source.NewConfigProvider(fmt.Sprintf("genesis file at %s", genesisFile), + source.ShouldSkipFile(genesisFile, skipNonExistent), + func(baseConfig interface{}) error { + conf, ok := baseConfig.(*config.BurrowConfig) + if !ok { + return fmt.Errorf("config passed was not BurrowConfig") + } + if conf.GenesisDoc != nil { + return fmt.Errorf("sourcing GenesisDoc from file, but GenesisDoc was defined earlier " + + "in config cascade, only specify GenesisDoc in one place") + } + genesisDoc := new(genesis.GenesisDoc) + err := source.FromJSONFile(genesisFile, genesisDoc) + if err != nil { + return err + } + conf.GenesisDoc = genesisDoc + return nil + }) +} + +func fromFile(file string, toml bool, conf interface{}) (err error) { + if toml { + err = source.FromTOMLFile(file, conf) + if err != nil { + fatalf("could not read GenesisSpec: %v", err) + } + } else { + err = source.FromJSONFile(file, conf) + if err != nil { + fatalf("could not read GenesisSpec: %v", err) + } + } + return } diff --git a/cmd/serve.go b/cmd/serve.go deleted file mode 100644 index 7f951f3b..00000000 --- a/cmd/serve.go +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package commands - -import ( - "fmt" - "os" - "os/signal" - "path" - "syscall" - - "github.com/hyperledger/burrow/core" - "github.com/hyperledger/burrow/definitions" - "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/logging/lifecycle" - vm "github.com/hyperledger/burrow/manager/burrow-mint/evm" - "github.com/hyperledger/burrow/util" - - "github.com/hyperledger/burrow/config" - "github.com/spf13/cobra" -) - -const ( - DefaultConfigBasename = "config" - DefaultConfigType = "toml" -) - -var DefaultConfigFilename = fmt.Sprintf("%s.%s", - DefaultConfigBasename, - DefaultConfigType) - -// build the serve subcommand -func buildServeCommand(do *definitions.Do) *cobra.Command { - cmd := &cobra.Command{ - Use: "serve", - Short: "burrow serve starts a burrow node with client API enabled by default.", - Long: `burrow serve starts a burrow node with client API enabled by default. -The burrow node is modularly configured for the consensus engine and application -manager. The client API can be disabled.`, - Example: fmt.Sprintf(`$ burrow serve -- will start the burrow node based on the configuration file "%s" in the current working directory -$ burrow serve --work-dir <path-to-working-directory> -- will start the burrow node based on the configuration file "%s" in the provided working directory -$ burrow serve --chain-id <CHAIN_ID> -- will overrule the configuration entry assert_chain_id`, - DefaultConfigFilename, DefaultConfigFilename), - PreRun: func(cmd *cobra.Command, args []string) { - // if WorkDir was not set by a flag or by $BURROW_WORKDIR - // NOTE [ben]: we can consider an `Explicit` flag that eliminates - // the use of any assumptions while starting burrow - if do.WorkDir == "" { - if currentDirectory, err := os.Getwd(); err != nil { - panic(fmt.Sprintf("No directory provided and failed to get current "+ - "working directory: %v", err)) - os.Exit(1) - } else { - do.WorkDir = currentDirectory - } - } - if !util.IsDir(do.WorkDir) { - panic(fmt.Sprintf("Provided working directory %s is not a directory", - do.WorkDir)) - os.Exit(1) - } - }, - Run: ServeRunner(do), - } - addServeFlags(do, cmd) - return cmd -} - -func addServeFlags(do *definitions.Do, serveCmd *cobra.Command) { - serveCmd.PersistentFlags().StringVarP(&do.ChainId, "chain-id", "c", - defaultChainId(), "specify the chain id to use for assertion against the genesis file or the existing state. If omitted, and no id is set in $CHAIN_ID, then assert_chain_id is used from the configuration file.") - serveCmd.PersistentFlags().StringVarP(&do.WorkDir, "work-dir", "w", - defaultWorkDir(), "specify the working directory for the chain to run. If omitted, and no path set in $BURROW_WORKDIR, the current working directory is taken.") - serveCmd.PersistentFlags().StringVarP(&do.DataDir, "data-dir", "", - defaultDataDir(), "specify the data directory. If omitted and not set in $BURROW_DATADIR, <working_directory>/data is taken.") - serveCmd.PersistentFlags().BoolVarP(&do.DisableRpc, "disable-rpc", "", - defaultDisableRpc(), "indicate for the RPC to be disabled. If omitted the RPC is enabled by default, unless (deprecated) $BURROW_API is set to false.") -} - -//------------------------------------------------------------------------------ -// functions -func NewCoreFromDo(do *definitions.Do) (*core.Core, error) { - // load the genesis file path - do.GenesisFile = path.Join(do.WorkDir, - do.Config.GetString("chain.genesis_file")) - - err := config.AssertConfigCompatibleWithRuntime(do.Config) - if err != nil { - return nil, err - } - - if do.Config.GetString("chain.genesis_file") == "" { - return nil, fmt.Errorf("The config value chain.genesis_file is empty, " + - "but should be set to the location of the genesis.json file.") - } - // Ensure data directory is set and accessible - if err := do.InitialiseDataDirectory(); err != nil { - return nil, fmt.Errorf("Failed to initialise data directory (%s): %v", do.DataDir, err) - } - - loggerConfig, err := core.LoadLoggingConfigFromDo(do) - if err != nil { - return nil, fmt.Errorf("Failed to load logging config: %s", err) - } - - logger, err := lifecycle.NewLoggerFromLoggingConfig(loggerConfig) - if err != nil { - return nil, fmt.Errorf("Failed to build logger from logging config: %s", err) - } - // Create a root logger to pass through to dependencies - logger = logging.WithScope(logger, "Serve") - // Capture all logging from tendermint/tendermint and tendermint/go-* - // dependencies - lifecycle.CaptureTendermintLog15Output(logger) - // And from stdlib go log - lifecycle.CaptureStdlibLogOutput(logger) - - // if do.ChainId is not yet set, load chain_id for assertion from configuration file - - if do.ChainId == "" { - if do.ChainId = do.Config.GetString("chain.assert_chain_id"); do.ChainId == "" { - return nil, fmt.Errorf("The config chain.assert_chain_id is empty, " + - "but should be set to the chain_id of the chain we are trying to run.") - } - } - - logging.Msg(logger, "Loading configuration for serve command", - "chainId", do.ChainId, - "workingDirectory", do.WorkDir, - "dataDirectory", do.DataDir, - "genesisFile", do.GenesisFile) - - consensusConfig, err := core.LoadConsensusModuleConfig(do) - if err != nil { - return nil, fmt.Errorf("Failed to load consensus module configuration: %s.", err) - } - - managerConfig, err := core.LoadApplicationManagerModuleConfig(do) - if err != nil { - return nil, fmt.Errorf("Failed to load application manager module configuration: %s.", err) - } - - logging.Msg(logger, "Modules configured", - "consensusModule", consensusConfig.Name, - "applicationManager", managerConfig.Name) - - return core.NewCore(do.ChainId, consensusConfig, managerConfig, logger) -} - -// ServeRunner() returns a command runner that prepares the environment and sets -// up the core for burrow to run. After the setup succeeds, it starts the core -// and waits for the core to terminate. -func ServeRunner(do *definitions.Do) func(*cobra.Command, []string) { - return func(cmd *cobra.Command, args []string) { - // load configuration from a single location to avoid a wrong configuration - // file is loaded. - err := do.ReadConfig(do.WorkDir, DefaultConfigBasename, DefaultConfigType) - if err != nil { - util.Fatalf("Fatal error reading configuration from %s/%s", do.WorkDir, - DefaultConfigFilename) - } - - vm.SetDebug(do.Debug) - - newCore, err := NewCoreFromDo(do) - - if err != nil { - util.Fatalf("Failed to load core: %s", err) - } - - if !do.DisableRpc { - serverConfig, err := core.LoadServerConfigFromDo(do) - if err != nil { - util.Fatalf("Failed to load server configuration: %s.", err) - } - serverProcess, err := newCore.NewGatewayV0(serverConfig) - if err != nil { - util.Fatalf("Failed to load servers: %s.", err) - } - err = serverProcess.Start() - if err != nil { - util.Fatalf("Failed to start servers: %s.", err) - } - _, err = newCore.NewGatewayTendermint(serverConfig) - if err != nil { - util.Fatalf("Failed to start Tendermint gateway") - } - <-serverProcess.StopEventChannel() - // Attempt graceful shutdown - newCore.Stop() - } else { - signals := make(chan os.Signal, 1) - signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) - fmt.Fprintf(os.Stderr, "Received %s signal. Marmots out.", <-signals) - } - } -} - -//------------------------------------------------------------------------------ -// Defaults - -func defaultChainId() string { - // if CHAIN_ID environment variable is not set, keep do.ChainId empty to read - // assert_chain_id from configuration file - return setDefaultString("CHAIN_ID", "") -} - -func defaultWorkDir() string { - // if BURROW_WORKDIR environment variable is not set, keep do.WorkDir empty - // as do.WorkDir is set by the PreRun - return setDefaultString("BURROW_WORKDIR", "") -} - -func defaultDataDir() string { - // As the default data directory depends on the default working directory, - // wait setting a default value, and initialise the data directory from serve() - return setDefaultString("BURROW_DATADIR", "") -} - -func defaultDisableRpc() bool { - // we currently observe environment variable BURROW_API (true = enable) - // and default to enabling the RPC if it is not set. - // TODO: [ben] deprecate BURROW_API across the stack for 0.12.1, and only disable - // the rpc through a command line flag --disable-rpc - return !setDefaultBool("BURROW_API", true) -} diff --git a/config/config.go b/config/config.go index 24753b65..05a69703 100644 --- a/config/config.go +++ b/config/config.go @@ -1,204 +1,67 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package config import ( - "bytes" "fmt" - "text/template" - lconfig "github.com/hyperledger/burrow/logging/config" - "github.com/hyperledger/burrow/version" - "github.com/spf13/viper" + acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/config/source" + "github.com/hyperledger/burrow/consensus/tendermint" + "github.com/hyperledger/burrow/consensus/tendermint/validator" + "github.com/hyperledger/burrow/core" + "github.com/hyperledger/burrow/genesis" + "github.com/hyperledger/burrow/keys" + logging_config "github.com/hyperledger/burrow/logging/config" + "github.com/hyperledger/burrow/logging/lifecycle" + "github.com/hyperledger/burrow/rpc" ) -type ConfigServiceGeneral struct { - ChainImageName string - UseDataContainer bool - ExportedPorts string - ContainerEntrypoint string -} - -// TODO: [ben] increase the configurability upon need -type ConfigChainGeneral struct { - AssertChainId string - BurrowMajorVersion uint8 - BurrowMinorVersion uint8 - GenesisRelativePath string -} - -type ConfigChainModule struct { - Name string - ModuleRelativeRoot string +const DefaultBurrowConfigTOMLFileName = "burrow.toml" +const DefaultBurrowConfigJSONEnvironmentVariable = "BURROW_CONFIG_JSON" +const DefaultGenesisDocJSONFileName = "genesis.json" + +type BurrowConfig struct { + ValidatorAddress *acm.Address `json:",omitempty" toml:",omitempty"` + GenesisDoc *genesis.GenesisDoc `json:",omitempty" toml:",omitempty"` + Tendermint *tendermint.BurrowTendermintConfig `json:",omitempty" toml:",omitempty"` + Keys *keys.KeysConfig `json:",omitempty" toml:",omitempty"` + RPC *rpc.RPCConfig `json:",omitempty" toml:",omitempty"` + Logging *logging_config.LoggingConfig `json:",omitempty" toml:",omitempty"` } -type ConfigTendermint struct { - Moniker string - Seeds string - FastSync bool -} - -var serviceGeneralTemplate *template.Template -var chainGeneralTemplate *template.Template -var chainConsensusTemplate *template.Template -var chainApplicationManagerTemplate *template.Template -var tendermintTemplate *template.Template - -func init() { - var err error - if serviceGeneralTemplate, err = template.New("serviceGeneral").Parse(sectionServiceGeneral); err != nil { - panic(err) - } - if chainGeneralTemplate, err = template.New("chainGeneral").Parse(sectionChainGeneral); err != nil { - panic(err) - } - if chainConsensusTemplate, err = template.New("chainConsensus").Parse(sectionChainConsensus); err != nil { - panic(err) - } - if chainApplicationManagerTemplate, err = template.New("chainApplicationManager").Parse(sectionChainApplicationManager); err != nil { - panic(err) - } - if tendermintTemplate, err = template.New("tendermint").Parse(sectionTendermint); err != nil { - panic(err) +func DefaultBurrowConfig() *BurrowConfig { + return &BurrowConfig{ + Tendermint: tendermint.DefaultBurrowTendermintConfig(), + Keys: keys.DefaultKeysConfig(), + RPC: rpc.DefaultRPCConfig(), + Logging: logging_config.DefaultNodeLoggingConfig(), } } -// NOTE: [ben] for 0.12.0-rc3 we only have a single configuration path -// with Tendermint in-process as the consensus engine and BurrowMint -// in-process as the application manager, so we hard-code the few -// parameters that are already templated. -// Let's learn to walk before we can run. -func GetConfigurationFileBytes(chainId, moniker, seeds string, chainImageName string, - useDataContainer bool, exportedPortsString, containerEntrypoint string) ([]byte, error) { - - burrowService := &ConfigServiceGeneral{ - ChainImageName: chainImageName, - UseDataContainer: useDataContainer, - ExportedPorts: exportedPortsString, - ContainerEntrypoint: containerEntrypoint, - } - - // We want to encode in the config file which Burrow version generated the config - burrowVersion := version.GetBurrowVersion() - burrowChain := &ConfigChainGeneral{ - AssertChainId: chainId, - BurrowMajorVersion: burrowVersion.MajorVersion, - BurrowMinorVersion: burrowVersion.MinorVersion, - GenesisRelativePath: "genesis.json", - } - - chainConsensusModule := &ConfigChainModule{ - Name: "tendermint", - ModuleRelativeRoot: "tendermint", +func (conf *BurrowConfig) Kernel() (*core.Kernel, error) { + if conf.GenesisDoc == nil { + return nil, fmt.Errorf("no GenesisDoc defined in config, cannot make Kernel") } - - chainApplicationManagerModule := &ConfigChainModule{ - Name: "burrowmint", - ModuleRelativeRoot: "burrowmint", + if conf.ValidatorAddress == nil { + return nil, fmt.Errorf("no validator address in config, cannot make Kernel") } - tendermintModule := &ConfigTendermint{ - Moniker: moniker, - Seeds: seeds, - FastSync: false, + logger, err := lifecycle.NewLoggerFromLoggingConfig(conf.Logging) + if err != nil { + return nil, fmt.Errorf("could not generate logger from logging config: %v", err) } - - // NOTE: [ben] according to StackOverflow appending strings with copy is - // more efficient than bytes.WriteString, but for readability and because - // this is not performance critical code we opt for bytes, which is - // still more efficient than + concatentation operator. - var buffer bytes.Buffer - - // write copyright header - buffer.WriteString(headerCopyright) - - // write section [service] - if err := serviceGeneralTemplate.Execute(&buffer, burrowService); err != nil { - return nil, fmt.Errorf("Failed to write template service general for %s: %s", - chainId, err) + keyClient := keys.NewBurrowKeyClient(conf.Keys.URL, logger) + val, err := keys.Addressable(keyClient, *conf.ValidatorAddress) + if err != nil { + return nil, fmt.Errorf("could not get validator addressable from keys client: %v", err) } - // write section for service dependencies; this is currently a static section - // with a fixed dependency on monax-keys - buffer.WriteString(sectionServiceDependencies) + privValidator := validator.NewPrivValidatorMemory(val, keys.Signer(keyClient, val.Address())) - // write section [chain] - if err := chainGeneralTemplate.Execute(&buffer, burrowChain); err != nil { - return nil, fmt.Errorf("Failed to write template chain general for %s: %s", - chainId, err) - } - - // write separator chain consensus - buffer.WriteString(separatorChainConsensus) - // write section [chain.consensus] - if err := chainConsensusTemplate.Execute(&buffer, chainConsensusModule); err != nil { - return nil, fmt.Errorf("Failed to write template chain consensus for %s: %s", - chainId, err) - } - - // write separator chain application manager - buffer.WriteString(separatorChainApplicationManager) - // write section [chain.consensus] - if err := chainApplicationManagerTemplate.Execute(&buffer, - chainApplicationManagerModule); err != nil { - return nil, fmt.Errorf("Failed to write template chain application manager for %s: %s", - chainId, err) - } - - // write separator servers - buffer.WriteString(separatorServerConfiguration) - // TODO: [ben] upon necessity replace this with template too - // write static section servers - buffer.WriteString(sectionServers) - - // write separator modules - buffer.WriteString(separatorModules) - - // write section module Tendermint - if err := tendermintTemplate.Execute(&buffer, tendermintModule); err != nil { - return nil, fmt.Errorf("Failed to write template tendermint for %s, moniker %s: %s", - chainId, moniker, err) - } - - // write static section burrowmint - buffer.WriteString(sectionBurrowMint) - - buffer.WriteString(sectionLoggingHeader) - buffer.WriteString(lconfig.DefaultNodeLoggingConfig().RootTOMLString()) - - return buffer.Bytes(), nil + return core.NewKernel(privValidator, conf.GenesisDoc, conf.Tendermint.TendermintConfig(), conf.RPC, logger) } -func AssertConfigCompatibleWithRuntime(conf *viper.Viper) error { - burrowVersion := version.GetBurrowVersion() - majorVersion := uint8(conf.GetInt(fmt.Sprintf("chain.%s", majorVersionKey))) - minorVersion := uint8(conf.GetInt(fmt.Sprintf("chain.%s", majorVersionKey))) - if burrowVersion.MajorVersion != majorVersion || - burrowVersion.MinorVersion != minorVersion { - fmt.Errorf("Runtime Burrow version %s is not compatible with "+ - "configuration file version: major=%s, minor=%s", - burrowVersion.GetVersionString(), majorVersion, minorVersion) - } - return nil +func (conf *BurrowConfig) JSONString() string { + return source.JSONString(conf) } -func GetExampleConfigFileBytes() ([]byte, error) { - return GetConfigurationFileBytes( - "simplechain", - "delectable_marmot", - "192.168.168.255", - "db:latest", - true, - "46657", - "burrow") +func (conf *BurrowConfig) TOMLString() string { + return source.TOMLString(conf) } diff --git a/config/config_test.go b/config/config_test.go index a49d8084..16a2d9f0 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1,28 +1,17 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package config import ( + "fmt" "testing" - "github.com/stretchr/testify/assert" + "github.com/hyperledger/burrow/genesis" ) -func TestGeneratedConfigIsUsable(t *testing.T) { - bs, err := GetExampleConfigFileBytes() - assert.NoError(t, err, "Should be able to create example config") - _, err = ReadViperConfig(bs) - assert.NoError(t, err, "Should be able to read example config into Viper") +func TestBurrowConfigSerialise(t *testing.T) { + conf := &BurrowConfig{ + GenesisDoc: &genesis.GenesisDoc{ + ChainName: "Foo", + }, + } + fmt.Println(conf.JSONString()) } diff --git a/config/dump_config_test.go b/config/dump_config_test.go deleted file mode 100644 index 5d238c9e..00000000 --- a/config/dump_config_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build dumpconfig - -// Space above matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package config - -import ( - "io/ioutil" - "testing" - - "github.com/stretchr/testify/assert" -) - -// This is a little convenience for getting a config file dump. Just run: -// go test -tags dumpconfig ./config -// This pseudo test won't run unless the dumpconfig tag is -func TestDumpConfig(t *testing.T) { - bs, err := GetExampleConfigFileBytes() - assert.NoError(t, err, "Should be able to create example config") - ioutil.WriteFile("config_dump.toml", bs, 0644) -} diff --git a/config/module.go b/config/module.go deleted file mode 100644 index 8b8eb945..00000000 --- a/config/module.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package config - -// config defines simple types in a separate package to avoid cyclical imports - -import ( - viper "github.com/spf13/viper" -) - -type ModuleConfig struct { - Module string - Name string - WorkDir string - DataDir string - RootDir string - ChainId string - GenesisFile string - Config *viper.Viper -} diff --git a/config/templates.go b/config/templates.go deleted file mode 100644 index 8a4e15fb..00000000 --- a/config/templates.go +++ /dev/null @@ -1,325 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package config - -import "fmt" - -const headerCopyright = `# Copyright 2017 Monax Industries Limited -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is a TOML configuration for burrow chains generated by burrow config. - -` - -const sectionServiceGeneral = `[service] -# NOTE: this section is read by CLI tooling, and ignored by burrow. -# Image specifies the image name monax needs to pull -# for running the chain. -image = "{{.ChainImageName}}" -# Define whether monax needs to attach the data container -# for the chain. -data_container = {{.UseDataContainer}} -# Specify a list of ports that need to be exported on the container. -ports = {{.ExportedPorts}} -{{ if ne .ContainerEntrypoint "" }}# Entrypoint points to the default action to execute -# in the chain container. -entry_point = "{{.ContainerEntrypoint}}"{{ end }} - -` - -const sectionServiceDependencies = `[dependencies] -# NOTE: this section is read by Monax tooling, and ignored by burrow. -# burrow expects these services to be available; eric-cli tooling will -# automatically set these services up for you. -# Services to boot with/required by the chain -services = [ "keys" ] - -` -const majorVersionKey = "major_version" -const minorVersionKey = "minor_version" - -var sectionChainGeneral string = fmt.Sprintf(`[chain] - -# ChainId is a human-readable name to identify the chain. -# This must correspond to the chain_id defined in the genesis file -# and the assertion here provides a safe-guard on misconfiguring chains. -assert_chain_id = "{{.AssertChainId}}" -# semantic major and minor version -%s = {{.BurrowMajorVersion}} -%s = {{.BurrowMinorVersion}} -# genesis file, relative path is to burrow working directory -genesis_file = "{{.GenesisRelativePath}}" - -`, majorVersionKey, minorVersionKey) - -const separatorChainConsensus = ` -################################################################################ -## -## consensus -## -################################################################################ - -` - -const sectionChainConsensus = ` [chain.consensus] - # consensus defines the module to use for consensus and - # this will define the peer-to-peer consensus network; - # accepted values are ("noops", "abci",) "tendermint" - name = "{{.Name}}" - # relative path to consensus' module root folder - relative_root = "{{.ModuleRelativeRoot}}" - - ` - -const separatorChainApplicationManager = ` -################################################################################ -## -## application manager -## -################################################################################ - -` - -const sectionChainApplicationManager = ` [chain.manager] - # application manager name defines the module to use for handling - # the transactions. Supported names are "burrowmint" - name = "{{.Name}}" - # relative path to application manager root folder - relative_root = "{{.ModuleRelativeRoot}}" - - ` - -const separatorServerConfiguration = ` -################################################################################ -################################################################################ -## -## Server configurations -## -################################################################################ -################################################################################ - -` - -// TODO: [ben] map entries to structure defined in burrow -const sectionServers = `[servers] - - [servers.bind] - address = "" - port = 1337 - - [servers.tls] - tls = false - cert_path = "" - key_path = "" - - [servers.cors] - enable = false - allow_origins = [] - allow_credentials = false - allow_methods = [] - allow_headers = [] - expose_headers = [] - max_age = 0 - - [servers.http] - json_rpc_endpoint = "/rpc" - - [servers.websocket] - endpoint = "/socketrpc" - max_sessions = 50 - read_buffer_size = 4096 - write_buffer_size = 4096 - - [servers.tendermint] - # Multiple listeners can be separated with a comma - rpc_local_address = "0.0.0.0:46657" - endpoint = "/websocket" - - ` - -const separatorModules = ` -################################################################################ -################################################################################ -## -## Module configurations - dynamically loaded based on chain configuration -## -################################################################################ -################################################################################ - -` - -// TODO: [ben] minimal fields have been made configurable; expand where needed -const sectionTendermint = ` -################################################################################ -## -## Tendermint -## -## in-process execution of Tendermint consensus engine -## -################################################################################ - -[tendermint] -# private validator file is used by tendermint to keep the status -# of the private validator, but also (currently) holds the private key -# for the private vaildator to sign with. This private key needs to be moved -# out and directly managed by monax-keys -# This file needs to be in the root directory -private_validator_file = "priv_validator.json" - - # Tendermint requires additional configuration parameters. - # burrow's tendermint consensus module will load [tendermint.configuration] - # as the configuration for Tendermint. - # burrow will respect the configurations set in this file where applicable, - # but reserves the option to override or block conflicting settings. - [tendermint.configuration] - # moniker is the name of the node on the tendermint p2p network - moniker = "{{.Moniker}}" - # seeds lists the peers tendermint can connect to join the network - seeds = "{{.Seeds}}" - # fast_sync allows a tendermint node to catch up faster when joining - # the network. - # NOTE: Tendermint has reported potential issues with fast_sync enabled. - # The recommended setting is for keeping it disabled. - fast_sync = {{.FastSync}} - # database backend to use for Tendermint. Supported "leveldb" and "memdb". - db_backend = "leveldb" - # logging level. Supported "error" < "warn" < "notice" < "info" < "debug" - log_level = "info" - # node local address - node_laddr = "0.0.0.0:46656" - # rpc local address - # NOTE: value is ignored when run in-process as RPC is - # handled by [servers.tendermint] - rpc_laddr = "0.0.0.0:46657" - # proxy application address - used for abci connections, - # and this port should not be exposed for in-process Tendermint - proxy_app = "tcp://127.0.0.1:46658" - - # Extended Tendermint configuration settings - # for reference to Tendermint see https://github.com/tendermint/tendermint/blob/master/config/tendermint/config.go - - # genesis_file = "./data/tendermint/genesis.json" - # skip_upnp = false - # addrbook_file = "./data/tendermint/addrbook.json" - # addrbook_strict = true - # pex_reactor = false - # priv_validator_file = "./data/tendermint/priv_validator.json" - # db_dir = "./data/tendermint/data" - # prof_laddr = "" - # revision_file = "./data/tendermint/revision" - # cs_wal_file = "./data/tendermint/data/cs.wal/wal" - # cs_wal_light = false - # filter_peers = false - - # block_size = 10000 - # block_part_size = 65536 - # disable_data_hash = false - # timeout_propose = 3000 - # timeout_propose_delta = 500 - # timeout_prevote = 1000 - # timeout_prevote_delta = 500 - # timeout_precommit = 1000 - # timeout_precommit_delta = 500 - # timeout_commit = 1000 - # skip_timeout_commit = false - # mempool_recheck = true - # mempool_recheck_empty = true - # mempool_broadcast = true - # mempool_wal_dir = "./data/tendermint/data/mempool.wal" - - [tendermint.configuration.p2p] - # Switch config keys - dial_timeout_seconds = 3 - handshake_timeout_seconds = 20 - max_num_peers = 20 - authenticated_encryption = true - - # MConnection config keys - send_rate = 512000 - recv_rate = 512000 - - # Fuzz params - fuzz_enable = false # use the fuzz wrapped conn - fuzz_active = false # toggle fuzzing - fuzz_mode = "drop" # eg. drop, delay - fuzz_max_delay_milliseconds = 3000 - fuzz_prob_drop_rw = 0.2 - fuzz_prob_drop_conn = 0.00 - fuzz_prob_sleep = 0.00 - -` - -const sectionBurrowMint = ` -################################################################################ -## -## Burrow-Mint -## -## The original Ethereum virtual machine with IAVL merkle trees -## and tendermint/go-wire encoding -## -################################################################################ - -[burrowmint] -# Database backend to use for BurrowMint state database. -# Supported "leveldb" and "memdb". -db_backend = "leveldb" -# tendermint host address needs to correspond to tendermints configuration -# of the rpc local address -tendermint_host = "0.0.0.0:46657" - -` - -// TODO: [Silas]: before next logging release (finalising this stuff and adding -// presets) add full documentation of transforms, outputs, and their available -// configuration options. -const sectionLoggingHeader = ` -################################################################################ -## -## System-wide logging configuration -## -## Log messages are sent to one of two 'channels': info or trace -## -## They are delivered on a single non-blocking stream to a 'root sink'. -## -## A sink may optionally define any of a 'transform', an 'output', and a list of -## downstream sinks. Log messages flow through a sink by first having that -## sink's transform applied and then writing to its output and downstream sinks. -## In this way the log messages can output can be finely controlled and sent to -## a multiple different outputs having been filtered, modified, augmented, or -## labelled. This can be used to give more relevant output or to drive external -## systems. -## -## -################################################################################ - -## A minimal logging config for multi-line, colourised terminal output would be: -# -# [logging] -# [logging.root_sink] -# [logging.root_sink.output] -# output_type = "stderr" -# format = "terminal" -` diff --git a/config/viper.go b/config/viper.go deleted file mode 100644 index c59799a8..00000000 --- a/config/viper.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package config - -import ( - "fmt" - - "bytes" - - "github.com/spf13/viper" -) - -// Safely get the subtree from a viper config, returning an error if it could not -// be obtained for any reason. -func ViperSubConfig(conf *viper.Viper, configSubtreePath string) (subConfig *viper.Viper, err error) { - // Viper internally panics if `moduleName` contains an disallowed - // character (eg, a dash). - defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("Viper panicked trying to read config subtree: %s", - configSubtreePath) - } - }() - if !conf.IsSet(configSubtreePath) { - return nil, fmt.Errorf("Failed to read config subtree: %s", - configSubtreePath) - } - subConfig = conf.Sub(configSubtreePath) - if subConfig == nil { - return nil, fmt.Errorf("Failed to read config subtree: %s", - configSubtreePath) - } - return subConfig, err -} - -// Read in TOML Viper config from bytes -func ReadViperConfig(configBytes []byte) (*viper.Viper, error) { - buf := bytes.NewBuffer(configBytes) - conf := viper.New() - conf.SetConfigType("toml") - err := conf.ReadConfig(buf) - if err != nil { - return nil, err - } - return conf, nil -} diff --git a/definitions/do.go b/definitions/do.go deleted file mode 100644 index 8e31e596..00000000 --- a/definitions/do.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package definitions - -import ( - "os" - "path" - - viper "github.com/spf13/viper" - - util "github.com/hyperledger/burrow/util" -) - -type Do struct { - // Persistent flags not reflected in the configuration files - // only set through command line flags or environment variables - Debug bool // BURROW_DEBUG - Verbose bool // BURROW_VERBOSE - - // Work directory is the root directory for burrow to act in - WorkDir string // BURROW_WORKDIR - // Data directory is defaulted to WorkDir + `/data`. - // If cli maps a data container, DataDir is intended to point - // to that mapped data directory. - DataDir string // BURROW_DATADIR - - // Capital configuration options explicitly extracted from the Viper config - ChainId string // has to be set to non-empty string, - // uniquely identifying the chain. - GenesisFile string - // ChainType string - // CSV string - // AccountTypes []string - // Zip bool - // Tarball bool - DisableRpc bool - Config *viper.Viper - // Accounts []*Account - // Result string -} - -func NewDo() *Do { - do := new(Do) - do.Debug = false - do.Verbose = false - do.WorkDir = "" - do.DataDir = "" - do.ChainId = "" - do.GenesisFile = "" - do.DisableRpc = false - do.Config = viper.New() - return do -} - -// ReadConfig uses Viper to set the configuration file name, file format -// where burrow currently only uses `toml`. -// The search directory is explicitly limited to a single location to -// minimise the chance of loading the wrong configuration file. -func (d *Do) ReadConfig(directory string, name string, configType string) error { - // name of the configuration file without extension - d.Config.SetConfigName(name) - // burrow currently only uses "toml" - d.Config.SetConfigType(configType) - // look for configuration file in the working directory - d.Config.AddConfigPath(directory) - return d.Config.ReadInConfig() -} - -// InitialiseDataDirectory will default to WorkDir/data if DataDir is empty -func (d *Do) InitialiseDataDirectory() error { - if d.DataDir == "" { - d.DataDir = path.Join(d.WorkDir, "data") - } - return util.EnsureDir(d.DataDir, os.ModePerm) -} diff --git a/server/server.go b/server/server.go index 2a3d7bc7..fba39b00 100644 --- a/server/server.go +++ b/server/server.go @@ -64,7 +64,6 @@ type ServeProcess struct { // Initializes all the servers and starts listening for connections. func (serveProcess *ServeProcess) Start() error { - router := gin.New() config := serveProcess.config -- GitLab