github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/juju/osenv/vars.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package osenv
     5  
     6  import (
     7  	"runtime"
     8  	"strings"
     9  
    10  	"github.com/juju/utils/featureflag"
    11  )
    12  
    13  const (
    14  	// If you are adding variables here that could be defined
    15  	// in a system and therefore changing the behavior on test
    16  	// suites please take a moment to add them to JujuOSEnvSuite
    17  	// setup so they are cleared before running the suites using
    18  	// it.
    19  
    20  	JujuControllerEnvKey    = "JUJU_CONTROLLER"
    21  	JujuModelEnvKey         = "JUJU_MODEL"
    22  	JujuXDGDataHomeEnvKey   = "JUJU_DATA"
    23  	JujuLoggingConfigEnvKey = "JUJU_LOGGING_CONFIG"
    24  	JujuFeatureFlagEnvKey   = "JUJU_DEV_FEATURE_FLAGS"
    25  
    26  	// JujuStartupLoggingConfigEnvKey if set is used to configure the initial
    27  	// logging before the command objects are even created to allow debugging
    28  	// of the command creation and initialisation process.
    29  	JujuStartupLoggingConfigEnvKey = "JUJU_STARTUP_LOGGING_CONFIG"
    30  
    31  	// Registry key containing juju related information
    32  	JujuRegistryKey = `HKLM:\SOFTWARE\juju-core`
    33  
    34  	// Registry value where the jujud password resides
    35  	JujuRegistryPasswordKey = `jujud-password`
    36  
    37  	// TODO(thumper): 2013-09-02 bug 1219630
    38  	// As much as I'd like to remove JujuContainerType now, it is still
    39  	// needed as MAAS still needs it at this stage, and we can't fix
    40  	// everything at once.
    41  	JujuContainerTypeEnvKey = "JUJU_CONTAINER_TYPE"
    42  
    43  	// JujuStatusIsoTimeEnvKey is the env var which if true, will cause status
    44  	// timestamps to be written in RFC3339 format.
    45  	JujuStatusIsoTimeEnvKey = "JUJU_STATUS_ISO_TIME"
    46  
    47  	// XDGDataHome is a path where data for the running user
    48  	// should be stored according to the xdg standard.
    49  	XDGDataHome = "XDG_DATA_HOME"
    50  )
    51  
    52  // FeatureFlags returns a map that can be merged with os.Environ.
    53  func FeatureFlags() map[string]string {
    54  	result := make(map[string]string)
    55  	if envVar := featureflag.AsEnvironmentValue(); envVar != "" {
    56  		result[JujuFeatureFlagEnvKey] = envVar
    57  	}
    58  	return result
    59  }
    60  
    61  // MergeEnvironment will return the current environment updated with
    62  // all the values from newValues.  If current is nil, a new map is
    63  // created.  If current is not nil, it is mutated.
    64  func MergeEnvironment(current, newValues map[string]string) map[string]string {
    65  	if current == nil {
    66  		current = make(map[string]string)
    67  	}
    68  	if runtime.GOOS == "windows" {
    69  		return mergeEnvWin(current, newValues)
    70  	}
    71  	return mergeEnvUnix(current, newValues)
    72  }
    73  
    74  // mergeEnvUnix merges the two evironment variable lists in a case sensitive way.
    75  func mergeEnvUnix(current, newValues map[string]string) map[string]string {
    76  	for key, value := range newValues {
    77  		current[key] = value
    78  	}
    79  	return current
    80  }
    81  
    82  // mergeEnvWin merges the two environment variable lists in a case insensitive,
    83  // but case preserving way.  Thus, if FOO=bar is set, and newValues has foo=baz,
    84  // then the resultant map will contain FOO=baz.
    85  func mergeEnvWin(current, newValues map[string]string) map[string]string {
    86  	uppers := make(map[string]string, len(current))
    87  	news := map[string]string{}
    88  	for k, v := range current {
    89  		uppers[strings.ToUpper(k)] = v
    90  	}
    91  
    92  	for k, v := range newValues {
    93  		up := strings.ToUpper(k)
    94  		if _, ok := uppers[up]; ok {
    95  			uppers[up] = v
    96  		} else {
    97  			news[k] = v
    98  		}
    99  	}
   100  
   101  	for k := range current {
   102  		current[k] = uppers[strings.ToUpper(k)]
   103  	}
   104  	for k, v := range news {
   105  		current[k] = v
   106  	}
   107  	return current
   108  }