github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/worker/uniter/runner/env.go (about) 1 // Copyright 2012-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package runner 5 6 import ( 7 "os" 8 "path/filepath" 9 "strings" 10 11 "github.com/juju/juju/version" 12 ) 13 14 func osDependentEnvVars(paths Paths) []string { 15 switch version.Current.OS { 16 case version.Windows: 17 return windowsEnv(paths) 18 case version.Ubuntu: 19 return ubuntuEnv(paths) 20 case version.CentOS: 21 return centosEnv(paths) 22 } 23 return nil 24 } 25 26 func appendPath(paths Paths) []string { 27 return []string{ 28 "PATH=" + paths.GetToolsDir() + ":" + os.Getenv("PATH"), 29 } 30 } 31 32 func ubuntuEnv(paths Paths) []string { 33 path := appendPath(paths) 34 env := []string{ 35 "APT_LISTCHANGES_FRONTEND=none", 36 "DEBIAN_FRONTEND=noninteractive", 37 } 38 env = append(env, path...) 39 return env 40 } 41 42 func centosEnv(paths Paths) []string { 43 return appendPath(paths) 44 } 45 46 // windowsEnv adds windows specific environment variables. PSModulePath 47 // helps hooks use normal imports instead of dot sourcing modules 48 // its a convenience variable. The PATH variable delimiter is 49 // a semicolon instead of a colon 50 func windowsEnv(paths Paths) []string { 51 charmDir := paths.GetCharmDir() 52 charmModules := filepath.Join(charmDir, "lib", "Modules") 53 return []string{ 54 "Path=" + paths.GetToolsDir() + ";" + os.Getenv("Path"), 55 "PSModulePath=" + os.Getenv("PSModulePath") + ";" + charmModules, 56 } 57 } 58 59 // mergeEnvironment takes in a string array representing the desired environment 60 // and merges it with the current environment. On Windows, clearing the environment, 61 // or having missing environment variables, may lead to standard go packages not working 62 // (os.TempDir relies on $env:TEMP), and powershell erroring out 63 // TODO(fwereade, gsamfira): this is copy/pasted from utils/exec. 64 // This is only used on windows, so it is safe to do in a case insensitive way. 65 func mergeWindowsEnvironment(newEnv, env []string) []string { 66 if len(newEnv) == 0 { 67 return env 68 } 69 70 // this whole rigamarole is so that we retain the case of existing 71 // environment variables, while being case insensitive about overwriting 72 // their values. 73 74 orig := make(map[string]string, len(env)) 75 uppers := make(map[string]string, len(env)) 76 news := map[string]string{} 77 78 tmpEnv := make([]string, 0, len(env)) 79 for _, val := range env { 80 varSplit := strings.SplitN(val, "=", 2) 81 k := varSplit[0] 82 uppers[strings.ToUpper(k)] = varSplit[1] 83 orig[k] = varSplit[1] 84 } 85 86 for _, val := range newEnv { 87 varSplit := strings.SplitN(val, "=", 2) 88 k := varSplit[0] 89 if _, ok := uppers[strings.ToUpper(k)]; ok { 90 uppers[strings.ToUpper(k)] = varSplit[1] 91 } else { 92 news[k] = varSplit[1] 93 } 94 } 95 96 for k, _ := range orig { 97 tmpEnv = append(tmpEnv, k+"="+uppers[strings.ToUpper(k)]) 98 } 99 100 for k, v := range news { 101 tmpEnv = append(tmpEnv, k+"="+v) 102 } 103 return tmpEnv 104 }