github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/uniter/runner/args.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 "fmt" 8 "os" 9 "os/exec" 10 "path/filepath" 11 "strings" 12 13 "github.com/juju/juju/worker/uniter/runner/context" 14 jujuos "github.com/juju/utils/os" 15 ) 16 17 var windowsSuffixOrder = []string{ 18 ".ps1", 19 ".cmd", 20 ".bat", 21 ".exe", 22 } 23 24 func lookPath(hook string) (string, error) { 25 hookFile, err := exec.LookPath(hook) 26 if err != nil { 27 if ee, ok := err.(*exec.Error); ok && os.IsNotExist(ee.Err) { 28 return "", context.NewMissingHookError(hook) 29 } 30 return "", err 31 } 32 return hookFile, nil 33 } 34 35 // searchHook will search, in order, hooks suffixed with extensions 36 // in windowsSuffixOrder. As windows cares about extensions to determine 37 // how to execute a file, we will allow several suffixes, with powershell 38 // being default. 39 func searchHook(charmDir, hook string) (string, error) { 40 hookFile := filepath.Join(charmDir, hook) 41 if jujuos.HostOS() != jujuos.Windows { 42 // we are not running on windows, 43 // there is no need to look for suffixed hooks 44 return lookPath(hookFile) 45 } 46 for _, suffix := range windowsSuffixOrder { 47 file := fmt.Sprintf("%s%s", hookFile, suffix) 48 foundHook, err := lookPath(file) 49 if err != nil { 50 if context.IsMissingHookError(err) { 51 // look for next suffix 52 continue 53 } 54 return "", err 55 } 56 return foundHook, nil 57 } 58 return "", context.NewMissingHookError(hook) 59 } 60 61 // hookCommand constructs an appropriate command to be passed to 62 // exec.Command(). The exec package uses cmd.exe as default on windows. 63 // cmd.exe does not know how to execute ps1 files by default, and 64 // powershell needs a few flags to allow execution (-ExecutionPolicy) 65 // and propagate error levels (-File). .cmd and .bat files can be run 66 // directly. 67 func hookCommand(hook string) []string { 68 if jujuos.HostOS() != jujuos.Windows { 69 // we are not running on windows, 70 // just return the hook name 71 return []string{hook} 72 } 73 if strings.HasSuffix(hook, ".ps1") { 74 return []string{ 75 "powershell.exe", 76 "-NonInteractive", 77 "-ExecutionPolicy", 78 "RemoteSigned", 79 "-File", 80 hook, 81 } 82 } 83 return []string{hook} 84 }