fix command and inline calls on windows

This commit is contained in:
Megan Marsh 2018-04-04 11:07:10 -07:00
parent fabd1a6517
commit 1bea658e16
4 changed files with 231 additions and 8 deletions

View File

@ -29,6 +29,9 @@ type Config struct {
// The shebang value used when running inline scripts.
InlineShebang string `mapstructure:"inline_shebang"`
// The file extension to use for the file generated from the inline commands
TempfileExtension string `mapstructure:"tempfile_extension"`
// The local path of the shell script to upload and execute.
Script string
@ -39,7 +42,7 @@ type Config struct {
// your command(s) are executed.
Vars []string `mapstructure:"environment_vars"`
EnvVarFormat string
EnvVarFormat string `mapstructure:"env_var_format"`
// End dedupe with postprocessor
// The command used to execute the script. The '{{ .Path }}' variable
@ -76,8 +79,10 @@ func Validate(config *Config) error {
if len(config.ExecuteCommand) == 0 {
config.ExecuteCommand = []string{
"cmd",
"/V",
"/C",
"{{.Vars}}",
"call",
"{{.Script}}",
}
}
@ -89,8 +94,7 @@ func Validate(config *Config) error {
config.ExecuteCommand = []string{
"/bin/sh",
"-c",
"{{.Vars}}",
"{{.Script}}",
"{{.Vars}} {{.Script}}",
}
}
}
@ -168,12 +172,19 @@ func Validate(config *Config) error {
// interact with.
if config.EnvVarFormat == "" {
if (runtime.GOOS == "windows") && !config.UseLinuxPathing {
config.EnvVarFormat = `set "%s=%s" && `
config.EnvVarFormat = "set %s=%s && "
} else {
config.EnvVarFormat = "%s='%s' "
}
}
// drop unnecessary "." in extension; we add this later.
if config.TempfileExtension != "" {
if strings.HasPrefix(config.TempfileExtension, ".") {
config.TempfileExtension = config.TempfileExtension[1:]
}
}
// Do a check for bad environment variables, such as '=foo', 'foobar'
for _, kv := range config.Vars {
vs := strings.SplitN(kv, "=", 2)

View File

@ -30,8 +30,13 @@ func Run(ui packer.Ui, config *Config) (bool, error) {
if err != nil {
return false, err
}
defer os.Remove(tempScriptFileName)
scripts = append(scripts, tempScriptFileName)
defer os.Remove(tempScriptFileName)
// figure out what extension the file should have, and rename it.
if config.TempfileExtension != "" {
os.Rename(tempScriptFileName, fmt.Sprintf("%s.%s", tempScriptFileName, config.TempfileExtension))
}
}
// Create environment variables to set before executing the command
@ -78,14 +83,18 @@ func Run(ui packer.Ui, config *Config) (bool, error) {
}
func createInlineScriptFile(config *Config) (string, error) {
tf, err := ioutil.TempFile("", "packer-shell")
tf, err := ioutil.TempFile(os.TempDir(), "packer-shell")
if err != nil {
return "", fmt.Errorf("Error preparing shell script: %s", err)
}
defer tf.Close()
// Write our contents to it
writer := bufio.NewWriter(tf)
writer.WriteString(fmt.Sprintf("#!%s\n", config.InlineShebang))
if config.InlineShebang != "" {
shebang := fmt.Sprintf("#!%s\n", config.InlineShebang)
log.Printf("Prepending inline script with %s", shebang)
writer.WriteString(shebang)
}
for _, command := range config.Inline {
if _, err := writer.WriteString(command + "\n"); err != nil {
return "", fmt.Errorf("Error preparing shell script: %s", err)

View File

@ -227,3 +227,105 @@ are cleaned up.
For a shell script, that means the script **must** exit with a zero code. You
*must* be extra careful to `exit 0` when necessary.
## Usage Examples:
Example of running a .cmd file on windows:
```
{
"type": "shell-local",
"environment_vars": ["SHELLLOCALTEST=ShellTest1"],
"scripts": ["./scripts/test_cmd.cmd"]
},
```
Contents of "test_cmd.cmd":
```
echo %SHELLLOCALTEST%
```
Example of running an inline command on windows:
Required customization: tempfile_extension
```
{
"type": "shell-local",
"environment_vars": ["SHELLLOCALTEST=ShellTest2"],
"tempfile_extension": ".cmd",
"inline": ["echo %SHELLLOCALTEST%"]
},
```
Example of running a bash command on windows using WSL:
Required customizations: use_linux_pathing and execute_command
```
{
"type": "shell-local",
"environment_vars": ["SHELLLOCALTEST=ShellTest3"],
"execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"],
"use_linux_pathing": true,
"script": "./scripts/example_bash.sh"
}
```
Contents of "example_bash.sh":
```
#!/bin/bash
echo $SHELLLOCALTEST
```
Example of running a powershell script on windows:
Required customizations: env_var_format and execute_command
```
{
"type": "shell-local",
"environment_vars": ["SHELLLOCALTEST=ShellTest4"],
"execute_command": ["powershell.exe", "{{.Vars}} {{.Script}}"],
"env_var_format": "$env:%s=\"%s\"; ",
}
```
Example of running a powershell script on windows as "inline":
Required customizations: env_var_format, tempfile_extension, and execute_command
```
{
"type": "shell-local",
"tempfile_extension": ".ps1",
"environment_vars": ["SHELLLOCALTEST=ShellTest5"],
"execute_command": ["powershell.exe", "{{.Vars}} {{.Script}}"],
"env_var_format": "$env:%s=\"%s\"; ",
"inline": ["write-output $env:SHELLLOCALTEST"]
}
```
Example of running a bash script on linux:
```
{
"type": "shell-local",
"environment_vars": ["PROVISIONERTEST=ProvisionerTest1"],
"scripts": ["./scripts/dummy_bash.sh"]
}
```
Example of running a bash "inline" on linux:
```
{
"type": "shell-local",
"environment_vars": ["PROVISIONERTEST=ProvisionerTest2"],
"inline": ["echo hello",
"echo $PROVISIONERTEST"]
}
```

View File

@ -197,3 +197,104 @@ are cleaned up.
For a shell script, that means the script **must** exit with a zero code. You
*must* be extra careful to `exit 0` when necessary.
## Usage Examples:
Example of running a .cmd file on windows:
```
{
"type": "shell-local",
"environment_vars": ["SHELLLOCALTEST=ShellTest1"],
"scripts": ["./scripts/test_cmd.cmd"]
},
```
Contents of "test_cmd.cmd":
```
echo %SHELLLOCALTEST%
```
Example of running an inline command on windows:
Required customization: tempfile_extension
```
{
"type": "shell-local",
"environment_vars": ["SHELLLOCALTEST=ShellTest2"],
"tempfile_extension": ".cmd",
"inline": ["echo %SHELLLOCALTEST%"]
},
```
Example of running a bash command on windows using WSL:
Required customizations: use_linux_pathing and execute_command
```
{
"type": "shell-local",
"environment_vars": ["SHELLLOCALTEST=ShellTest3"],
"execute_command": ["bash", "-c", "{{.Vars}} {{.Script}}"],
"use_linux_pathing": true,
"script": "./scripts/example_bash.sh"
}
```
Contents of "example_bash.sh":
```
#!/bin/bash
echo $SHELLLOCALTEST
```
Example of running a powershell script on windows:
Required customizations: env_var_format and execute_command
```
{
"type": "shell-local",
"environment_vars": ["SHELLLOCALTEST=ShellTest4"],
"execute_command": ["powershell.exe", "{{.Vars}} {{.Script}}"],
"env_var_format": "$env:%s=\"%s\"; ",
}
```
Example of running a powershell script on windows as "inline":
Required customizations: env_var_format, tempfile_extension, and execute_command
```
{
"type": "shell-local",
"tempfile_extension": ".ps1",
"environment_vars": ["SHELLLOCALTEST=ShellTest5"],
"execute_command": ["powershell.exe", "{{.Vars}} {{.Script}}"],
"env_var_format": "$env:%s=\"%s\"; ",
"inline": ["write-output $env:SHELLLOCALTEST"]
}
```
Example of running a bash script on linux:
```
{
"type": "shell-local",
"environment_vars": ["PROVISIONERTEST=ProvisionerTest1"],
"scripts": ["./scripts/dummy_bash.sh"]
}
```
Example of running a bash "inline" on linux:
```
{
"type": "shell-local",
"environment_vars": ["PROVISIONERTEST=ProvisionerTest2"],
"inline": ["echo hello",
"echo $PROVISIONERTEST"]
}
```