fix default windows bash call for shell-local provisioner and move chmod command from the execute_command array into the portion of code where we actually generate inline scripts, sparing users the need to think about this modification which Packer should really handle on its own

make bash call work on windows
pull/5956/head
Megan Marsh 8 years ago
parent 5da4377f21
commit e983a94a88

@ -67,6 +67,11 @@ func Decode(config *Config, raws ...interface{}) error {
func Validate(config *Config) error {
var errs *packer.MultiError
// Do not treat these defaults as a source of truth; the shell-local
// provisioner sets these defaults before Validate is called. Eventually
// we will have to bring the provisioner and post-processor defaults in
// line with one another, but for now the following may or may not be
// applied depending on where Validate is being called from.
if runtime.GOOS == "windows" {
if len(config.ExecuteCommand) == 0 {
config.ExecuteCommand = []string{
@ -84,8 +89,7 @@ func Validate(config *Config) error {
config.ExecuteCommand = []string{
"/bin/sh",
"-c",
"{{.Vars}}",
"{{.Script}}",
"{{.Vars}} {{.Script}}",
}
}
}

@ -41,7 +41,7 @@ func Run(ui packer.Ui, config *Config) (bool, error) {
if err != nil {
return false, err
}
ui.Say(fmt.Sprintf("Post processing with local shell script: %s", script))
ui.Say(fmt.Sprintf("Running local shell script: %s", script))
comm := &Communicator{
ExecuteCommand: interpolatedCmds,
@ -93,6 +93,10 @@ func createInlineScriptFile(config *Config) (string, error) {
}
tf.Close()
err = os.Chmod(tf.Name(), 0555)
if err != nil {
log.Printf("error modifying permissions of temp script file: %s", err.Error())
}
return tf.Name(), nil
}

@ -1,8 +1,6 @@
package shell_local
import (
"runtime"
sl "github.com/hashicorp/packer/common/shell-local"
"github.com/hashicorp/packer/packer"
)
@ -21,20 +19,16 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
if err != nil {
return err
}
if len(p.config.ExecuteCommand) == 0 && runtime.GOOS != "windows" {
// Backwards compatibility from before post-processor merge with
// provisioner. Don't need to default separately for windows becuase the
// post-processor never worked for windows before the merge with the
// provisioner code, so the provisioner defaults are fine.
p.config.ExecuteCommand = []string{"sh", "-c", `chmod +x "{{.Script}}"; {{.Vars}} "{{.Script}}"`}
} else if len(p.config.ExecuteCommand) == 1 {
// Backwards compatibility -- before merge, post-processor didn't have
// configurable call to shell program, meaning users may not have
// defined this in their call. If users are still using the old way of
// defining ExecuteCommand (e.g. just supplying a single string that is
// now being interpolated as a slice with one item), then assume we need
// to prepend this call still, and use the one that the post-processor
// defaulted to before.
if len(p.config.ExecuteCommand) == 1 {
// Backwards compatibility -- before we merged the shell-local
// post-processor and provisioners, the post-processor accepted
// execute_command as a string rather than a slice of strings. It didn't
// have a configurable call to shell program, automatically prepending
// the user-supplied execute_command string with "sh -c". If users are
// still using the old way of defining ExecuteCommand (by supplying a
// single string rather than a slice of strings) then we need to
// prepend this command with the call that the post-processor defaulted
// to before.
p.config.ExecuteCommand = append([]string{"sh", "-c"}, p.config.ExecuteCommand...)
}

@ -1,6 +1,11 @@
package shell
import (
"fmt"
"path/filepath"
"runtime"
"strings"
sl "github.com/hashicorp/packer/common/shell-local"
"github.com/hashicorp/packer/packer"
)
@ -10,12 +15,46 @@ type Provisioner struct {
}
func (p *Provisioner) Prepare(raws ...interface{}) error {
err := sl.Decode(&p.config, raws)
err := sl.Decode(&p.config, raws...)
if err != nil {
return err
}
convertPath := false
if len(p.config.ExecuteCommand) == 0 && runtime.GOOS == "windows" {
convertPath = true
p.config.ExecuteCommand = []string{
"bash",
"-c",
"{{.Vars}} {{.Script}}",
}
}
return sl.Validate(&p.config)
err = sl.Validate(&p.config)
if err != nil {
return err
}
if convertPath {
for index, script := range p.config.Scripts {
p.config.Scripts[index], err = convertToWindowsBashPath(script)
if err != nil {
return err
}
}
}
return nil
}
func convertToWindowsBashPath(winPath string) (string, error) {
// get absolute path of script, and morph it into the bash path
winAbsPath, err := filepath.Abs(winPath)
if err != nil {
return "", fmt.Errorf("Error converting %s to absolute path: %s", winPath, err.Error())
}
winAbsPath = strings.Replace(winAbsPath, "\\", "/", -1)
winBashPath := strings.Replace(winAbsPath, "C:/", "/mnt/c/", 1)
return winBashPath, nil
}
func (p *Provisioner) Provision(ui packer.Ui, _ packer.Communicator) error {

Loading…
Cancel
Save