diff --git a/peer/chaincode/chaincode.go b/peer/chaincode/chaincode.go index 0217a1282b6..89cd38cfb0f 100644 --- a/peer/chaincode/chaincode.go +++ b/peer/chaincode/chaincode.go @@ -87,10 +87,13 @@ var ( ) var chaincodeCmd = &cobra.Command{ - Use: chainFuncName, - Short: fmt.Sprint(chainCmdDes), - Long: fmt.Sprint(chainCmdDes), - PersistentPreRun: common.SetOrdererEnv, + Use: chainFuncName, + Short: fmt.Sprint(chainCmdDes), + Long: fmt.Sprint(chainCmdDes), + PersistentPreRun: func(cmd *cobra.Command, args []string) { + common.InitCmd(cmd, args) + common.SetOrdererEnv(cmd, args) + }, } var flags *pflag.FlagSet diff --git a/peer/chaincode/flags_test.go b/peer/chaincode/flags_test.go index 81356ed196d..c341f5dc7cc 100644 --- a/peer/chaincode/flags_test.go +++ b/peer/chaincode/flags_test.go @@ -9,6 +9,7 @@ package chaincode import ( "testing" + "github.com/hyperledger/fabric/peer/common" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/assert" @@ -34,7 +35,11 @@ func TestOrdererFlags(t *testing.T) { assert.Equal(t, sn, viper.GetString("orderer.tls.serverhostoverride")) assert.Equal(t, true, viper.GetBool("orderer.tls.enabled")) assert.Equal(t, true, viper.GetBool("orderer.tls.clientAuthRequired")) - }} + }, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + common.SetOrdererEnv(cmd, args) + }, + } runCmd := Cmd(nil) diff --git a/peer/channel/channel.go b/peer/channel/channel.go index 23a7f0bce8b..8ba0a83cdda 100644 --- a/peer/channel/channel.go +++ b/peer/channel/channel.go @@ -91,10 +91,13 @@ func attachFlags(cmd *cobra.Command, names []string) { } var channelCmd = &cobra.Command{ - Use: "channel", - Short: "Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.", - Long: "Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.", - PersistentPreRun: common.SetOrdererEnv, + Use: "channel", + Short: "Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.", + Long: "Operate a channel: create|fetch|join|list|update|signconfigtx|getinfo.", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + common.InitCmd(cmd, args) + common.SetOrdererEnv(cmd, args) + }, } type BroadcastClientFactory func() (common.BroadcastClient, error) diff --git a/peer/channel/flags_test.go b/peer/channel/flags_test.go index 87ecb495428..d18e99a455b 100644 --- a/peer/channel/flags_test.go +++ b/peer/channel/flags_test.go @@ -9,6 +9,7 @@ package channel import ( "testing" + "github.com/hyperledger/fabric/peer/common" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/assert" @@ -35,7 +36,11 @@ func TestOrdererFlags(t *testing.T) { assert.Equal(t, sn, viper.GetString("orderer.tls.serverhostoverride")) assert.Equal(t, true, viper.GetBool("orderer.tls.enabled")) assert.Equal(t, true, viper.GetBool("orderer.tls.clientAuthRequired")) - }} + }, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + common.SetOrdererEnv(cmd, args) + }, + } runCmd := Cmd(nil) diff --git a/peer/clilogging/logging.go b/peer/clilogging/logging.go index bbcb44003c8..10988ff9b5a 100644 --- a/peer/clilogging/logging.go +++ b/peer/clilogging/logging.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/hyperledger/fabric/common/flogging" + "github.com/hyperledger/fabric/peer/common" "github.com/spf13/cobra" ) @@ -41,7 +42,8 @@ func Cmd(cf *LoggingCmdFactory) *cobra.Command { } var loggingCmd = &cobra.Command{ - Use: loggingFuncName, - Short: fmt.Sprint(loggingCmdDes), - Long: fmt.Sprint(loggingCmdDes), + Use: loggingFuncName, + Short: fmt.Sprint(loggingCmdDes), + Long: fmt.Sprint(loggingCmdDes), + PersistentPreRun: common.InitCmd, } diff --git a/peer/common/common.go b/peer/common/common.go index 6668ecc0711..b10cb487567 100644 --- a/peer/common/common.go +++ b/peer/common/common.go @@ -9,8 +9,10 @@ package common import ( "crypto/tls" "fmt" + "io" "io/ioutil" "os" + "runtime" "strings" "time" @@ -29,12 +31,14 @@ import ( putils "github.com/hyperledger/fabric/protos/utils" "github.com/op/go-logging" "github.com/pkg/errors" + "github.com/spf13/cobra" "github.com/spf13/viper" "golang.org/x/net/context" ) // UndefinedParamValue defines what undefined parameters in the command line will initialise to const UndefinedParamValue = "" +const CmdRoot = "core" var ( defaultConnTimeout = 3 * time.Second @@ -71,6 +75,9 @@ var ( // GetCertificateFnc is a function that returns the client TLS certificate GetCertificateFnc func() (tls.Certificate, error) + + mainLogger *logging.Logger + logOutput io.Writer ) type commonClient struct { @@ -87,10 +94,13 @@ func init() { GetDeliverClientFnc = GetDeliverClient GetPeerDeliverClientFnc = GetPeerDeliverClient GetCertificateFnc = GetCertificate + mainLogger = flogging.MustGetLogger("main") + logOutput = os.Stderr } // InitConfig initializes viper config func InitConfig(cmdRoot string) error { + err := config.InitViper(nil, cmdRoot) if err != nil { return err @@ -98,7 +108,15 @@ func InitConfig(cmdRoot string) error { err = viper.ReadInConfig() // Find and read the config file if err != nil { // Handle errors reading the config file - return errors.WithMessage(err, fmt.Sprintf("error when reading %s config file", cmdRoot)) + // The version of Viper we use claims the config type isn't supported when in fact the file hasn't been found + // Display a more helpful message to avoid confusing the user. + if strings.Contains(fmt.Sprint(err), "Unsupported Config Type") { + return errors.New(fmt.Sprintf("Could not find config file. "+ + "Please make sure that FABRIC_CFG_PATH or --configPath is set to a path "+ + "which contains %s.yaml", cmdRoot)) + } else { + return errors.WithMessage(err, fmt.Sprintf("error when reading %s config file", cmdRoot)) + } } return nil @@ -111,7 +129,7 @@ func InitCrypto(mspMgrConfigDir, localMSPID, localMSPType string) error { fi, err := os.Stat(mspMgrConfigDir) if os.IsNotExist(err) || !fi.IsDir() { // No need to try to load MSP from folder which is not available - return errors.Errorf("cannot init crypto, missing %s folder", mspMgrConfigDir) + return errors.Errorf("cannot init crypto, folder \"%s\" does not exist", mspMgrConfigDir) } // Check whether localMSPID exists if localMSPID == "" { @@ -277,3 +295,42 @@ func configFromEnv(prefix string) (address, override string, clientConfig comm.C clientConfig.SecOpts = secOpts return } + +func InitCmd(cmd *cobra.Command, args []string) { + + err := InitConfig(CmdRoot) + if err != nil { // Handle errors reading the config file + mainLogger.Errorf("Fatal error when initializing %s config : %s", CmdRoot, err) + os.Exit(1) + } + + // setup system-wide logging backend based on settings from core.yaml + flogging.InitBackend(flogging.SetFormat(viper.GetString("logging.format")), logOutput) + + // check for --logging-level pflag first, which should override all other + // log settings. if --logging-level is not set, use CORE_LOGGING_LEVEL + // (environment variable takes priority; otherwise, the value set in + // core.yaml) + var loggingSpec string + if viper.GetString("logging_level") != "" { + loggingSpec = viper.GetString("logging_level") + } else { + loggingSpec = viper.GetString("logging.level") + } + flogging.InitFromSpec(loggingSpec) + + // Init the MSP + var mspMgrConfigDir = config.GetPath("peer.mspConfigPath") + var mspID = viper.GetString("peer.localMspId") + var mspType = viper.GetString("peer.localMspType") + if mspType == "" { + mspType = msp.ProviderTypeToString(msp.FABRIC) + } + err = InitCrypto(mspMgrConfigDir, mspID, mspType) + if err != nil { // Handle errors reading the config file + mainLogger.Errorf("Cannot run peer because %s", err.Error()) + os.Exit(1) + } + + runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs")) +} diff --git a/peer/common/common_test.go b/peer/common/common_test.go index d0f1a3d5326..4db01686f8d 100644 --- a/peer/common/common_test.go +++ b/peer/common/common_test.go @@ -61,7 +61,7 @@ func TestInitCryptoMissingDir(t *testing.T) { dir := os.TempDir() + "/" + util.GenerateUUID() err := common.InitCrypto(dir, "SampleOrg", msp.ProviderTypeToString(msp.FABRIC)) assert.Error(t, err, "Should be able to initialize crypto with non-existing directory") - assert.Contains(t, err.Error(), fmt.Sprintf("missing %s folder", dir)) + assert.Contains(t, err.Error(), fmt.Sprintf("folder \"%s\" does not exist", dir)) } func TestInitCrypto(t *testing.T) { diff --git a/peer/main.go b/peer/main.go index aa7d3018a61..0299a178903 100644 --- a/peer/main.go +++ b/peer/main.go @@ -9,12 +9,8 @@ package main import ( _ "net/http/pprof" "os" - "runtime" "strings" - "github.com/hyperledger/fabric/common/flogging" - "github.com/hyperledger/fabric/core/config" - "github.com/hyperledger/fabric/msp" "github.com/hyperledger/fabric/peer/chaincode" "github.com/hyperledger/fabric/peer/channel" "github.com/hyperledger/fabric/peer/clilogging" @@ -25,20 +21,15 @@ import ( "github.com/spf13/viper" ) -var logger = flogging.MustGetLogger("main") -var logOutput = os.Stderr - -// Constants go here. -const cmdRoot = "core" - // The main command describes the service and // defaults to printing the help message. var mainCmd = &cobra.Command{ Use: "peer"} func main() { + // For environment variables. - viper.SetEnvPrefix(cmdRoot) + viper.SetEnvPrefix(common.CmdRoot) viper.AutomaticEnv() replacer := strings.NewReplacer(".", "_") viper.SetEnvKeyReplacer(replacer) @@ -56,42 +47,6 @@ func main() { mainCmd.AddCommand(clilogging.Cmd(nil)) mainCmd.AddCommand(channel.Cmd(nil)) - err := common.InitConfig(cmdRoot) - if err != nil { // Handle errors reading the config file - logger.Errorf("Fatal error when initializing %s config : %s", cmdRoot, err) - os.Exit(1) - } - - // setup system-wide logging backend based on settings from core.yaml - flogging.InitBackend(flogging.SetFormat(viper.GetString("logging.format")), logOutput) - - // check for --logging-level pflag first, which should override all other - // log settings. if --logging-level is not set, use CORE_LOGGING_LEVEL - // (environment variable takes priority; otherwise, the value set in - // core.yaml) - var loggingSpec string - if viper.GetString("logging_level") != "" { - loggingSpec = viper.GetString("logging_level") - } else { - loggingSpec = viper.GetString("logging.level") - } - flogging.InitFromSpec(loggingSpec) - - // Init the MSP - var mspMgrConfigDir = config.GetPath("peer.mspConfigPath") - var mspID = viper.GetString("peer.localMspId") - var mspType = viper.GetString("peer.localMspType") - if mspType == "" { - mspType = msp.ProviderTypeToString(msp.FABRIC) - } - err = common.InitCrypto(mspMgrConfigDir, mspID, mspType) - if err != nil { // Handle errors reading the config file - logger.Errorf("Cannot run peer because %s", err.Error()) - os.Exit(1) - } - - runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs")) - // On failure Cobra prints the usage message and error string, so we only // need to exit with a non-0 status if mainCmd.Execute() != nil { diff --git a/peer/node/node.go b/peer/node/node.go index 86f4481dc03..f50a2720040 100644 --- a/peer/node/node.go +++ b/peer/node/node.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/hyperledger/fabric/common/flogging" + "github.com/hyperledger/fabric/peer/common" "github.com/spf13/cobra" ) @@ -39,7 +40,8 @@ func Cmd() *cobra.Command { } var nodeCmd = &cobra.Command{ - Use: nodeFuncName, - Short: fmt.Sprint(nodeCmdDes), - Long: fmt.Sprint(nodeCmdDes), + Use: nodeFuncName, + Short: fmt.Sprint(nodeCmdDes), + Long: fmt.Sprint(nodeCmdDes), + PersistentPreRun: common.InitCmd, }