github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/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  }