Skip to content

Commit 9065a7c

Browse files
committed
[FAB-2880] Fix configtxgen output
No more: 1. ```Checking for configtx.yaml at: Checking for configtx.yaml at: Checking for configtx.yaml at: /opt/gopath/src/github.com/hyperledger/fabric/common/configtx/tool``` 2. Dumping the `TopLevel` config struct on screen. (This is what the `-inspectXYZ` flags are for.) Also: 1. Fixed the comments for the exported variables. 2. Removed the hardcoded references to `configtx.yaml`. 3. Updated the default batch timeout to 2s inline with the `configtx.yaml` default value. 4. Updated all panic statements to their logger-enabled equivalent. Change-Id: Ifc19bd8342005a434cdb4fb7e788abf1b281e087 Signed-off-by: Kostas Christidis <[email protected]>
1 parent 8d3275f commit 9065a7c

File tree

2 files changed

+68
-45
lines changed

2 files changed

+68
-45
lines changed

common/configtx/tool/localconfig/config.go

+66-43
Original file line numberDiff line numberDiff line change
@@ -31,60 +31,74 @@ import (
3131
bccsp "github.com/hyperledger/fabric/bccsp/factory"
3232
)
3333

34+
var logger = logging.MustGetLogger("configtx/tool/localconfig")
35+
3436
const (
35-
// SampleInsecureProfile references the sample profile which does not include any MSPs and uses solo for consensus
37+
// SampleInsecureProfile references the sample profile which does not include any MSPs and uses solo for ordering.
3638
SampleInsecureProfile = "SampleInsecureSolo"
37-
38-
// SampleSingleMSPSoloProfile references the sample profile which includes only the sample MSP and uses solo for consensus
39+
// SampleSingleMSPSoloProfile references the sample profile which includes only the sample MSP and uses solo for ordering.
3940
SampleSingleMSPSoloProfile = "SampleSingleMSPSolo"
41+
42+
// Prefix identifies the prefix for the configtxgen-related ENV vars.
43+
Prefix string = "CONFIGTX"
4044
)
4145

42-
var logger = logging.MustGetLogger("configtx/tool/localconfig")
46+
var (
47+
configName string
48+
configFileName string
49+
)
4350

44-
// Prefix is the default config prefix for the orderer
45-
const Prefix string = "CONFIGTX"
51+
func init() {
52+
configName = strings.ToLower(Prefix)
53+
configFileName = configName + ".yaml"
54+
}
4655

47-
// TopLevel contains the genesis structures for use by the provisional bootstrapper
56+
// TopLevel consists of the structs used by the configtxgen tool.
4857
type TopLevel struct {
4958
Profiles map[string]*Profile `yaml:"Profiles"`
5059
Organizations []*Organization `yaml:"Organizations"`
5160
Application *Application `yaml:"Application"`
5261
Orderer *Orderer `yaml:"Orderer"`
5362
}
5463

55-
// TopLevel contains the genesis structures for use by the provisional bootstrapper
64+
// Profile encodes orderer/application configuration combinations for the configtxgen tool.
5665
type Profile struct {
5766
Application *Application `yaml:"Application"`
5867
Orderer *Orderer `yaml:"Orderer"`
5968
}
6069

61-
// Application encodes the configuration needed for the config transaction
70+
// Application encodes the application-level configuration needed in config transactions.
6271
type Application struct {
6372
Organizations []*Organization `yaml:"Organizations"`
6473
}
6574

75+
// Organization encodes the organization-level configuration needed in config transactions.
6676
type Organization struct {
6777
Name string `yaml:"Name"`
6878
ID string `yaml:"ID"`
6979
MSPDir string `yaml:"MSPDir"`
7080
BCCSP *bccsp.FactoryOpts `yaml:"BCCSP"`
7181

72-
// Note, the viper deserialization does not seem to care for
73-
// embedding of types, so we use one organization structure for
74-
// both orderers and applications
82+
// Note: Viper deserialization does not seem to care for
83+
// embedding of types, so we use one organization struct
84+
// for both orderers and applications.
7585
AnchorPeers []*AnchorPeer `yaml:"AnchorPeers"`
7686
}
7787

88+
// AnchorPeer encodes the necessary fields to identify an anchor peer.
7889
type AnchorPeer struct {
7990
Host string `yaml:"Host"`
8091
Port int `yaml:"Port"`
8192
}
8293

94+
// ApplicationOrganization ...
95+
// TODO This should probably be removed
8396
type ApplicationOrganization struct {
8497
Organization `yaml:"Organization"`
8598
}
8699

87-
// Orderer contains config which is used for orderer genesis by the provisional bootstrapper
100+
// Orderer contains configuration which is used for the
101+
// bootstrapping of an orderer by the provisional bootstrapper.
88102
type Orderer struct {
89103
OrdererType string `yaml:"OrdererType"`
90104
Addresses []string `yaml:"Addresses"`
@@ -95,14 +109,14 @@ type Orderer struct {
95109
MaxChannels uint64 `yaml:"MaxChannels"`
96110
}
97111

98-
// BatchSize contains configuration affecting the size of batches
112+
// BatchSize contains configuration affecting the size of batches.
99113
type BatchSize struct {
100114
MaxMessageCount uint32 `yaml:"MaxMessageSize"`
101115
AbsoluteMaxBytes uint32 `yaml:"AbsoluteMaxBytes"`
102116
PreferredMaxBytes uint32 `yaml:"PreferredMaxBytes"`
103117
}
104118

105-
// Kafka contains config for the Kafka orderer
119+
// Kafka contains configuration for the Kafka-based orderer.
106120
type Kafka struct {
107121
Brokers []string `yaml:"Brokers"`
108122
}
@@ -111,7 +125,7 @@ var genesisDefaults = TopLevel{
111125
Orderer: &Orderer{
112126
OrdererType: "solo",
113127
Addresses: []string{"127.0.0.1:7050"},
114-
BatchTimeout: 10 * time.Second,
128+
BatchTimeout: 2 * time.Second,
115129
BatchSize: BatchSize{
116130
MaxMessageCount: 10,
117131
AbsoluteMaxBytes: 100000000,
@@ -123,43 +137,44 @@ var genesisDefaults = TopLevel{
123137
},
124138
}
125139

126-
func (g *Profile) completeInitialization() {
140+
func (p *Profile) completeInitialization() {
127141
for {
128142
switch {
129-
case g.Orderer.OrdererType == "":
143+
case p.Orderer.OrdererType == "":
130144
logger.Infof("Orderer.OrdererType unset, setting to %s", genesisDefaults.Orderer.OrdererType)
131-
g.Orderer.OrdererType = genesisDefaults.Orderer.OrdererType
132-
case g.Orderer.Addresses == nil:
145+
p.Orderer.OrdererType = genesisDefaults.Orderer.OrdererType
146+
case p.Orderer.Addresses == nil:
133147
logger.Infof("Orderer.Addresses unset, setting to %s", genesisDefaults.Orderer.Addresses)
134-
g.Orderer.Addresses = genesisDefaults.Orderer.Addresses
135-
case g.Orderer.BatchTimeout == 0:
148+
p.Orderer.Addresses = genesisDefaults.Orderer.Addresses
149+
case p.Orderer.BatchTimeout == 0:
136150
logger.Infof("Orderer.BatchTimeout unset, setting to %s", genesisDefaults.Orderer.BatchTimeout)
137-
g.Orderer.BatchTimeout = genesisDefaults.Orderer.BatchTimeout
138-
case g.Orderer.BatchSize.MaxMessageCount == 0:
151+
p.Orderer.BatchTimeout = genesisDefaults.Orderer.BatchTimeout
152+
case p.Orderer.BatchSize.MaxMessageCount == 0:
139153
logger.Infof("Orderer.BatchSize.MaxMessageCount unset, setting to %s", genesisDefaults.Orderer.BatchSize.MaxMessageCount)
140-
g.Orderer.BatchSize.MaxMessageCount = genesisDefaults.Orderer.BatchSize.MaxMessageCount
141-
case g.Orderer.BatchSize.AbsoluteMaxBytes == 0:
154+
p.Orderer.BatchSize.MaxMessageCount = genesisDefaults.Orderer.BatchSize.MaxMessageCount
155+
case p.Orderer.BatchSize.AbsoluteMaxBytes == 0:
142156
logger.Infof("Orderer.BatchSize.AbsoluteMaxBytes unset, setting to %s", genesisDefaults.Orderer.BatchSize.AbsoluteMaxBytes)
143-
g.Orderer.BatchSize.AbsoluteMaxBytes = genesisDefaults.Orderer.BatchSize.AbsoluteMaxBytes
144-
case g.Orderer.BatchSize.PreferredMaxBytes == 0:
157+
p.Orderer.BatchSize.AbsoluteMaxBytes = genesisDefaults.Orderer.BatchSize.AbsoluteMaxBytes
158+
case p.Orderer.BatchSize.PreferredMaxBytes == 0:
145159
logger.Infof("Orderer.BatchSize.PreferredMaxBytes unset, setting to %s", genesisDefaults.Orderer.BatchSize.PreferredMaxBytes)
146-
g.Orderer.BatchSize.PreferredMaxBytes = genesisDefaults.Orderer.BatchSize.PreferredMaxBytes
147-
case g.Orderer.Kafka.Brokers == nil:
160+
p.Orderer.BatchSize.PreferredMaxBytes = genesisDefaults.Orderer.BatchSize.PreferredMaxBytes
161+
case p.Orderer.Kafka.Brokers == nil:
148162
logger.Infof("Orderer.Kafka.Brokers unset, setting to %v", genesisDefaults.Orderer.Kafka.Brokers)
149-
g.Orderer.Kafka.Brokers = genesisDefaults.Orderer.Kafka.Brokers
163+
p.Orderer.Kafka.Brokers = genesisDefaults.Orderer.Kafka.Brokers
150164
default:
151165
return
152166
}
153167
}
154168
}
155169

170+
// Load returns the orderer/application config combination that corresponds to a given profile.
156171
func Load(profile string) *Profile {
157172
config := viper.New()
158173

159174
config.SetConfigName("configtx")
160175
var cfgPath string
161176

162-
// Path to look for the config file in based on GOPATH
177+
// Candidate paths to look for the config file in, based on GOPATH
163178
searchPath := []string{
164179
os.Getenv("ORDERER_CFG_PATH"),
165180
os.Getenv("PEER_CFG_PATH"),
@@ -169,21 +184,30 @@ func Load(profile string) *Profile {
169184
searchPath = append(searchPath, filepath.Join(p, "src/github.com/hyperledger/fabric/common/configtx/tool/"))
170185
}
171186

172-
for _, genesisPath := range searchPath {
173-
logger.Infof("Checking for configtx.yaml at: %s", genesisPath)
174-
if _, err := os.Stat(filepath.Join(genesisPath, "configtx.yaml")); err != nil {
175-
// The yaml file does not exist in this component of the path
187+
for _, path := range searchPath {
188+
if len(path) == 0 {
189+
// No point printing a "checking for" message below for an empty path
190+
continue
191+
}
192+
logger.Infof("Looking for %s in: %s", configFileName, path)
193+
if _, err := os.Stat(filepath.Join(path, configFileName)); err != nil {
194+
// The YAML file does not exist in this component of the path
176195
continue
177196
}
178-
cfgPath = genesisPath
197+
cfgPath = path
198+
logger.Infof("Found %s there", configFileName)
179199
}
180200

181201
if cfgPath == "" {
182-
logger.Fatalf("Could not find configtx.yaml in paths of %s. Try setting ORDERER_CFG_PATH, PEER_CFG_PATH, or GOPATH correctly", searchPath)
202+
logger.Fatalf("Could not find %s in paths of %s."+
203+
"Try setting ORDERER_CFG_PATH, PEER_CFG_PATH, or GOPATH correctly.",
204+
configFileName, searchPath)
183205
}
184-
config.AddConfigPath(cfgPath) // Path to look for the config file in
185206

186-
// for environment variables
207+
// Path to look for the config file in
208+
config.AddConfigPath(cfgPath)
209+
210+
// For environment variables
187211
config.SetEnvPrefix(Prefix)
188212
config.AutomaticEnv()
189213
// This replacer allows substitution within the particular profile without having to fully qualify the name
@@ -192,14 +216,13 @@ func Load(profile string) *Profile {
192216

193217
err := config.ReadInConfig()
194218
if err != nil {
195-
panic(fmt.Errorf("Error reading %s plugin config from %s: %s", Prefix, cfgPath, err))
219+
logger.Panicf("Error reading configuration from %s in %s: %s", configFileName, cfgPath, err)
196220
}
197221

198222
var uconf TopLevel
199-
200223
err = viperutil.EnhancedExactUnmarshal(config, &uconf)
201224
if err != nil {
202-
panic(fmt.Errorf("Error unmarshaling into structure: %s", err))
225+
logger.Panicf("Error unmarshaling config into struct: %s", err)
203226
}
204227

205228
result, ok := uconf.Profiles[profile]

common/viperutil/config_util.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ func pemBlocksFromFileDecodeHook() mapstructure.DecodeHookFunc {
219219
var fileI interface{}
220220
fileI, ok = d["File"]
221221
if !ok {
222-
fileI, ok = d["file"]
222+
fileI, _ = d["file"]
223223
}
224224
fileName, ok = fileI.(string)
225225
}
@@ -259,7 +259,7 @@ func EnhancedExactUnmarshal(v *viper.Viper, output interface{}) error {
259259
baseKeys := v.AllSettings() // AllKeys doesn't actually return all keys, it only returns the base ones
260260
leafKeys := getKeysRecursively("", v, baseKeys)
261261

262-
logger.Infof("%+v", leafKeys)
262+
logger.Debugf("%+v", leafKeys)
263263
config := &mapstructure.DecoderConfig{
264264
ErrorUnused: true,
265265
Metadata: nil,

0 commit comments

Comments
 (0)