diff --git a/common/shell-local/communicator.go b/common/shell-local/communicator.go index 7664bc896..b51d309d9 100644 --- a/common/shell-local/communicator.go +++ b/common/shell-local/communicator.go @@ -3,6 +3,7 @@ package shell_local import ( "fmt" "io" + "log" "os" "os/exec" "syscall" @@ -20,6 +21,7 @@ func (c *Communicator) Start(cmd *packer.RemoteCmd) error { } // Build the local command to execute + log.Printf("Executing local shell command %s", c.ExecuteCommand) localCmd := exec.Command(c.ExecuteCommand[0], c.ExecuteCommand[1:]...) localCmd.Stdin = cmd.Stdin localCmd.Stdout = cmd.Stdout diff --git a/post-processor/shell-local/post-processor.go b/post-processor/shell-local/post-processor.go index 557fe7eba..cc1f2845e 100644 --- a/post-processor/shell-local/post-processor.go +++ b/post-processor/shell-local/post-processor.go @@ -30,7 +30,11 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { } 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 + // 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. p.config.ExecuteCommand = append([]string{"sh", "-c"}, p.config.ExecuteCommand...) } diff --git a/website/source/docs/post-processors/shell-local.html.md b/website/source/docs/post-processors/shell-local.html.md index d23780731..26ef7871f 100644 --- a/website/source/docs/post-processors/shell-local.html.md +++ b/website/source/docs/post-processors/shell-local.html.md @@ -13,7 +13,7 @@ Type: `shell-local` The local shell post processor executes scripts locally during the post processing stage. Shell local provides a convenient way to automate executing -some task with the packer outputs. +some task with packer outputs and variables. ## Basic example @@ -33,6 +33,9 @@ required element is either "inline" or "script". Every other option is optional. Exactly *one* of the following is required: +- `command` (string) - This is a single command to execute. It will be written + to a temporary file and run using the `execute_command` call below. + - `inline` (array of strings) - This is an array of commands to execute. The commands are concatenated by newlines and turned into a single file, so they are all executed within the same context. This allows you to change @@ -52,15 +55,32 @@ Exactly *one* of the following is required: Optional parameters: - `environment_vars` (array of strings) - An array of key/value pairs to - inject prior to the execute\_command. The format should be `key=value`. + inject prior to the `execute_command`. The format should be `key=value`. Packer injects some environmental variables by default into the environment, as well, which are covered in the section below. -- `execute_command` (string) - The command to use to execute the script. By - default this is `chmod +x "{{.Script}}"; {{.Vars}} "{{.Script}}"`. - The value of this is treated as [template engine](/docs/templates/engine.html). +- `execute_command` (array of strings) - The command used to execute the script. By + default this is `["sh", "-c", "chmod +x \"{{.Script}}\"; {{.Vars}} \"{{.Script}}\""]` + on unix and `["cmd", "/c", "{{.Vars}}", "{{.Script}}"]` on windows. + This is treated as a [template engine](/docs/templates/engine.html). There are two available variables: `Script`, which is the path to the script - to run, `Vars`, which is the list of `environment_vars`, if configured. + to run, and `Vars`, which is the list of `environment_vars`, if configured. + If you choose to set this option, make sure that the first element in the + array is the shell program you want to use (for example, "sh" or + "/usr/local/bin/zsh" or even "powershell.exe" although anything other than + a flavor of the shell command language is not explicitly supported and may + be broken by assumptions made within Packer). + + For backwards compatibility, `execute_command` will accept a string insetad + of an array of strings. If a single string or an array of strings with only + one element is provided, Packer will replicate past behavior by appending + your `execute_command` to the array of strings `["sh", "-c"]`. For example, + if you set `"execute_command": "foo bar"`, the final `execute_command` that + Packer runs will be ["sh", "-c", "foo bar"]. If you set `"execute_command": ["foo", "bar"]`, + the final execute_command will remain `["foo", "bar"]`. + + Again, the above is only provided as a backwards compatibility fix; we + strongly recommend that you set execute_command as an array of strings. - `inline_shebang` (string) - The [shebang](http://en.wikipedia.org/wiki/Shebang_%28Unix%29) value to use when diff --git a/website/source/docs/provisioners/shell-local.html.md b/website/source/docs/provisioners/shell-local.html.md index c52bcd893..bd66e74c7 100644 --- a/website/source/docs/provisioners/shell-local.html.md +++ b/website/source/docs/provisioners/shell-local.html.md @@ -37,10 +37,26 @@ The example below is fully functional. The reference of available configuration options is listed below. The only required element is "command". -Required: +Exactly *one* of the following is required: -- `command` (string) - The command to execute. This will be executed within - the context of a shell as specified by `execute_command`. +- `command` (string) - This is a single command to execute. It will be written + to a temporary file and run using the `execute_command` call below. + +- `inline` (array of strings) - This is an array of commands to execute. The + commands are concatenated by newlines and turned into a single file, so they + are all executed within the same context. This allows you to change + directories in one command and use something in the directory in the next + and so on. Inline scripts are the easiest way to pull off simple tasks + within the machine. + +- `script` (string) - The path to a script to execute. This path can be + absolute or relative. If it is relative, it is relative to the working + directory when Packer is executed. + +- `scripts` (array of strings) - An array of scripts to execute. The scripts + will be executed in the order specified. Each script is executed in + isolation, so state such as variables from one script won't carry on to the + next. Optional parameters: @@ -50,3 +66,34 @@ Optional parameters: treated as [configuration template](/docs/templates/engine.html). The only available variable is `Command` which is the command to execute. + +- `environment_vars` (array of strings) - An array of key/value pairs to + inject prior to the `execute_command`. The format should be `key=value`. + Packer injects some environmental variables by default into the environment, + as well, which are covered in the section below. + +- `execute_command` (array of strings) - The command used to execute the script. + By default this is `["/bin/sh", "-c", "{{.Vars}}, "{{.Script}}"]` + on unix and `["cmd", "/c", "{{.Vars}}", "{{.Script}}"]` on windows. + This is treated as a [template engine](/docs/templates/engine.html). + There are two available variables: `Script`, which is the path to the script + to run, and `Vars`, which is the list of `environment_vars`, if configured + If you choose to set this option, make sure that the first element in the + array is the shell program you want to use (for example, "sh" or + "/usr/local/bin/zsh" or even "powershell.exe" although anything other than + a flavor of the shell command language is not explicitly supported and may + be broken by assumptions made within Packer), and a later element in the + array must be `{{.Script}}`. + + For backwards compatability, {{.Command}} is also available to use in + `execute_command` but it is decoded the same way as {{.Script}}. We + recommend using {{.Script}} for the sake of clarity, as even when you set + only a single `command` to run, Packer writes it to a temporary file and + then runs it as a script. + +- `inline_shebang` (string) - The + [shebang](http://en.wikipedia.org/wiki/Shebang_%28Unix%29) value to use when + running commands specified by `inline`. By default, this is `/bin/sh -e`. If + you're not using `inline`, then this configuration has no effect. + **Important:** If you customize this, be sure to include something like the + `-e` flag, otherwise individual steps failing won't fail the provisioner.