github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/core/config/config.go (about)

     1  /*
     2  Copyright Greg Haskins <gregory.haskins@gmail.com> 2017, All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package config
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"path/filepath"
    23  
    24  	"github.com/spf13/viper"
    25  )
    26  
    27  func dirExists(path string) bool {
    28  	_, err := os.Stat(path)
    29  	return err == nil
    30  }
    31  
    32  func addConfigPath(v *viper.Viper, p string) {
    33  	if v != nil {
    34  		v.AddConfigPath(p)
    35  	} else {
    36  		viper.AddConfigPath(p)
    37  	}
    38  }
    39  
    40  //----------------------------------------------------------------------------------
    41  // GetDevConfigDir()
    42  //----------------------------------------------------------------------------------
    43  // Returns the path to the default configuration that is maintained with the source
    44  // tree.  Only valid to call from a test/development context.
    45  //----------------------------------------------------------------------------------
    46  func GetDevConfigDir() (string, error) {
    47  	gopath := os.Getenv("GOPATH")
    48  	if gopath == "" {
    49  		return "", fmt.Errorf("GOPATH not set")
    50  	}
    51  
    52  	for _, p := range filepath.SplitList(gopath) {
    53  		devPath := filepath.Join(p, "src/github.com/hyperledger/fabric/sampleconfig")
    54  		if !dirExists(devPath) {
    55  			continue
    56  		}
    57  
    58  		return devPath, nil
    59  	}
    60  
    61  	return "", fmt.Errorf("DevConfigDir not found in %s", gopath)
    62  }
    63  
    64  //----------------------------------------------------------------------------------
    65  // GetDevMspDir()
    66  //----------------------------------------------------------------------------------
    67  // Builds upon GetDevConfigDir to return the path to our sampleconfig/msp that is
    68  // maintained with the source tree.  Only valid to call from a test/development
    69  // context.  Runtime environment should use configuration elements such as
    70  //
    71  //   GetPath("peer.mspConfigDir")
    72  //----------------------------------------------------------------------------------
    73  func GetDevMspDir() (string, error) {
    74  	devDir, err := GetDevConfigDir()
    75  	if err != nil {
    76  		return "", fmt.Errorf("Error obtaining DevConfigDir: %s", devDir)
    77  	}
    78  
    79  	return filepath.Join(devDir, "msp"), nil
    80  }
    81  
    82  //----------------------------------------------------------------------------------
    83  // TranslatePath()
    84  //----------------------------------------------------------------------------------
    85  // Translates a relative path into a fully qualified path relative to the config
    86  // file that specified it.  Absolute paths are passed unscathed.
    87  //----------------------------------------------------------------------------------
    88  func TranslatePath(base, p string) string {
    89  	if filepath.IsAbs(p) {
    90  		return p
    91  	}
    92  
    93  	return filepath.Join(base, p)
    94  }
    95  
    96  //----------------------------------------------------------------------------------
    97  // TranslatePathInPlace()
    98  //----------------------------------------------------------------------------------
    99  // Translates a relative path into a fully qualified path in-place (updating the
   100  // pointer) relative to the config file that specified it.  Absolute paths are
   101  // passed unscathed.
   102  //----------------------------------------------------------------------------------
   103  func TranslatePathInPlace(base string, p *string) {
   104  	*p = TranslatePath(base, *p)
   105  }
   106  
   107  //----------------------------------------------------------------------------------
   108  // GetPath()
   109  //----------------------------------------------------------------------------------
   110  // GetPath allows configuration strings that specify a (config-file) relative path
   111  //
   112  // For example: Assume our config is located in /etc/hyperledger/fabric/core.yaml with
   113  // a key "msp.configPath" = "msp/config.yaml".
   114  //
   115  // This function will return:
   116  //      GetPath("msp.configPath") -> /etc/hyperledger/fabric/msp/config.yaml
   117  //
   118  //----------------------------------------------------------------------------------
   119  func GetPath(key string) string {
   120  	p := viper.GetString(key)
   121  	if p == "" {
   122  		return ""
   123  	}
   124  
   125  	return TranslatePath(filepath.Dir(viper.ConfigFileUsed()), p)
   126  }
   127  
   128  const OfficialPath = "/etc/hyperledger/fabric"
   129  
   130  //----------------------------------------------------------------------------------
   131  // InitViper()
   132  //----------------------------------------------------------------------------------
   133  // Performs basic initialization of our viper-based configuration layer.
   134  // Primary thrust is to establish the paths that should be consulted to find
   135  // the configuration we need.  If v == nil, we will initialize the global
   136  // Viper instance
   137  //----------------------------------------------------------------------------------
   138  func InitViper(v *viper.Viper, configName string) error {
   139  	var altPath = os.Getenv("FABRIC_CFG_PATH")
   140  	if altPath != "" {
   141  		// If the user has overridden the path with an envvar, its the only path
   142  		// we will consider
   143  		addConfigPath(v, altPath)
   144  	} else {
   145  		// If we get here, we should use the default paths in priority order:
   146  		//
   147  		// *) CWD
   148  		// *) The $GOPATH based development tree
   149  		// *) /etc/hyperledger/fabric
   150  		//
   151  
   152  		// CWD
   153  		addConfigPath(v, "./")
   154  
   155  		// DevConfigPath
   156  		err := AddDevConfigPath(v)
   157  		if err != nil {
   158  			return err
   159  		}
   160  
   161  		// And finally, the official path
   162  		if dirExists(OfficialPath) {
   163  			addConfigPath(v, OfficialPath)
   164  		}
   165  	}
   166  
   167  	// Now set the configuration file.
   168  	if v != nil {
   169  		v.SetConfigName(configName)
   170  	} else {
   171  		viper.SetConfigName(configName)
   172  	}
   173  
   174  	return nil
   175  }
   176  
   177  //----------------------------------------------------------------------------------
   178  // AddDevConfigPath()
   179  //----------------------------------------------------------------------------------
   180  // Helper utility that automatically adds our DevConfigDir to the viper path
   181  //----------------------------------------------------------------------------------
   182  func AddDevConfigPath(v *viper.Viper) error {
   183  	devPath, err := GetDevConfigDir()
   184  	if err != nil {
   185  		return err
   186  	}
   187  
   188  	addConfigPath(v, devPath)
   189  
   190  	return nil
   191  }