Merge pull request #6251 from hashicorp/do_winrm_shell_local
access automatically generated winrm password from shell-local
This commit is contained in:
commit
a012f70e71
|
@ -56,6 +56,11 @@ type Config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Decode(config *Config, raws ...interface{}) error {
|
func Decode(config *Config, raws ...interface{}) error {
|
||||||
|
//Create passthrough for winrm password so we can fill it in once we know it
|
||||||
|
config.Ctx.Data = &EnvVarsTemplate{
|
||||||
|
WinRMPassword: `{{.WinRMPassword}}`,
|
||||||
|
}
|
||||||
|
|
||||||
err := configHelper.Decode(&config, &configHelper.DecodeOpts{
|
err := configHelper.Decode(&config, &configHelper.DecodeOpts{
|
||||||
Interpolate: true,
|
Interpolate: true,
|
||||||
InterpolateContext: &config.Ctx,
|
InterpolateContext: &config.Ctx,
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package shell_local
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConvertToLinuxPath(t *testing.T) {
|
||||||
|
winPath := "C:/path/to/your/file"
|
||||||
|
winBashPath := "/mnt/c/path/to/your/file"
|
||||||
|
converted, _ := ConvertToLinuxPath(winPath)
|
||||||
|
assert.Equal(t, winBashPath, converted,
|
||||||
|
"Should have converted %s to %s -- not %s", winPath, winBashPath, converted)
|
||||||
|
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
commonhelper "github.com/hashicorp/packer/helper/common"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
)
|
)
|
||||||
|
@ -17,6 +18,11 @@ type ExecuteCommandTemplate struct {
|
||||||
Vars string
|
Vars string
|
||||||
Script string
|
Script string
|
||||||
Command string
|
Command string
|
||||||
|
WinRMPassword string
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnvVarsTemplate struct {
|
||||||
|
WinRMPassword string
|
||||||
}
|
}
|
||||||
|
|
||||||
func Run(ui packer.Ui, config *Config) (bool, error) {
|
func Run(ui packer.Ui, config *Config) (bool, error) {
|
||||||
|
@ -63,8 +69,12 @@ func Run(ui packer.Ui, config *Config) (bool, error) {
|
||||||
// buffers and for reading the final exit status.
|
// buffers and for reading the final exit status.
|
||||||
flattenedCmd := strings.Join(interpolatedCmds, " ")
|
flattenedCmd := strings.Join(interpolatedCmds, " ")
|
||||||
cmd := &packer.RemoteCmd{Command: flattenedCmd}
|
cmd := &packer.RemoteCmd{Command: flattenedCmd}
|
||||||
log.Printf("[INFO] (shell-local): starting local command: %s", flattenedCmd)
|
sanitized := flattenedCmd
|
||||||
|
if len(getWinRMPassword(config.PackerBuildName)) > 0 {
|
||||||
|
sanitized = strings.Replace(flattenedCmd,
|
||||||
|
getWinRMPassword(config.PackerBuildName), "*****", -1)
|
||||||
|
}
|
||||||
|
log.Printf("[INFO] (shell-local): starting local command: %s", sanitized)
|
||||||
if err := cmd.StartWithUi(comm, ui); err != nil {
|
if err := cmd.StartWithUi(comm, ui); err != nil {
|
||||||
return false, fmt.Errorf(
|
return false, fmt.Errorf(
|
||||||
"Error executing script: %s\n\n"+
|
"Error executing script: %s\n\n"+
|
||||||
|
@ -96,7 +106,19 @@ func createInlineScriptFile(config *Config) (string, error) {
|
||||||
log.Printf("[INFO] (shell-local): Prepending inline script with %s", shebang)
|
log.Printf("[INFO] (shell-local): Prepending inline script with %s", shebang)
|
||||||
writer.WriteString(shebang)
|
writer.WriteString(shebang)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generate context so you can interpolate the command
|
||||||
|
config.Ctx.Data = &EnvVarsTemplate{
|
||||||
|
WinRMPassword: getWinRMPassword(config.PackerBuildName),
|
||||||
|
}
|
||||||
|
|
||||||
for _, command := range config.Inline {
|
for _, command := range config.Inline {
|
||||||
|
// interpolate command to check for template variables.
|
||||||
|
command, err := interpolate.Render(command, &config.Ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := writer.WriteString(command + "\n"); err != nil {
|
if _, err := writer.WriteString(command + "\n"); err != nil {
|
||||||
return "", fmt.Errorf("Error preparing shell script: %s", err)
|
return "", fmt.Errorf("Error preparing shell script: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -121,6 +143,7 @@ func createInterpolatedCommands(config *Config, script string, flattenedEnvVars
|
||||||
Vars: flattenedEnvVars,
|
Vars: flattenedEnvVars,
|
||||||
Script: script,
|
Script: script,
|
||||||
Command: script,
|
Command: script,
|
||||||
|
WinRMPassword: getWinRMPassword(config.PackerBuildName),
|
||||||
}
|
}
|
||||||
|
|
||||||
interpolatedCmds := make([]string, len(config.ExecuteCommand))
|
interpolatedCmds := make([]string, len(config.ExecuteCommand))
|
||||||
|
@ -142,8 +165,17 @@ func createFlattenedEnvVars(config *Config) (string, error) {
|
||||||
envVars["PACKER_BUILD_NAME"] = fmt.Sprintf("%s", config.PackerBuildName)
|
envVars["PACKER_BUILD_NAME"] = fmt.Sprintf("%s", config.PackerBuildName)
|
||||||
envVars["PACKER_BUILDER_TYPE"] = fmt.Sprintf("%s", config.PackerBuilderType)
|
envVars["PACKER_BUILDER_TYPE"] = fmt.Sprintf("%s", config.PackerBuilderType)
|
||||||
|
|
||||||
|
// interpolate environment variables
|
||||||
|
config.Ctx.Data = &EnvVarsTemplate{
|
||||||
|
WinRMPassword: getWinRMPassword(config.PackerBuildName),
|
||||||
|
}
|
||||||
// Split vars into key/value components
|
// Split vars into key/value components
|
||||||
for _, envVar := range config.Vars {
|
for _, envVar := range config.Vars {
|
||||||
|
envVar, err := interpolate.Render(envVar, &config.Ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// Split vars into key/value components
|
||||||
keyValue := strings.SplitN(envVar, "=", 2)
|
keyValue := strings.SplitN(envVar, "=", 2)
|
||||||
// Store pair, replacing any single quotes in value so they parse
|
// Store pair, replacing any single quotes in value so they parse
|
||||||
// correctly with required environment variable format
|
// correctly with required environment variable format
|
||||||
|
@ -162,3 +194,8 @@ func createFlattenedEnvVars(config *Config) (string, error) {
|
||||||
}
|
}
|
||||||
return flattened, nil
|
return flattened, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getWinRMPassword(buildName string) string {
|
||||||
|
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
|
||||||
|
return winRMPass
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,10 @@ Exactly *one* of the following is required:
|
||||||
|
|
||||||
- `command` (string) - This is a single command to execute. It will be written
|
- `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.
|
to a temporary file and run using the `execute_command` call below.
|
||||||
|
If you are building a windows vm on AWS, Azure or Google Compute and would
|
||||||
|
like to access the generated password that Packer uses to connect to the
|
||||||
|
instance via WinRM, you can use the template variable `{{.WinRMPassword}}`
|
||||||
|
to set this as an environment variable.
|
||||||
|
|
||||||
- `inline` (array of strings) - This is an array of commands to execute. The
|
- `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
|
commands are concatenated by newlines and turned into a single file, so they
|
||||||
|
@ -60,24 +64,22 @@ Exactly *one* of the following is required:
|
||||||
|
|
||||||
Optional parameters:
|
Optional parameters:
|
||||||
|
|
||||||
- `execute_command` (array of strings) - The command to use to execute
|
|
||||||
the script. By default this is `["/bin/sh", "-c", "{{.Command}}"]`. The value
|
|
||||||
is an array of arguments executed directly by the OS. The value of this is
|
|
||||||
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
|
- `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,
|
Packer injects some environmental variables by default into the environment,
|
||||||
as well, which are covered in the section below.
|
as well, which are covered in the section below. If you are building a
|
||||||
|
windows vm on AWS, Azure or Google Compute and would like to access the
|
||||||
|
generated password that Packer uses to connect to the instance via WinRM,
|
||||||
|
you can use the template variable `{{.WinRMPassword}}` to set this as an
|
||||||
|
environment variable. For example:
|
||||||
|
`"environment_vars": "WINRMPASS={{.WinRMPassword}}"`
|
||||||
|
|
||||||
- `execute_command` (array of strings) - The command used to execute the script.
|
- `execute_command` (array of strings) - The command used to execute the script.
|
||||||
By default this is `["/bin/sh", "-c", "{{.Vars}}, "{{.Script}}"]`
|
By default this is `["/bin/sh", "-c", "{{.Vars}}, "{{.Script}}"]`
|
||||||
on unix and `["cmd", "/c", "{{.Vars}}", "{{.Script}}"]` on windows.
|
on unix and `["cmd", "/c", "{{.Vars}}", "{{.Script}}"]` on windows.
|
||||||
This is treated as a [template engine](/docs/templates/engine.html).
|
This is treated as a [template engine](/docs/templates/engine.html).
|
||||||
There are two available variables: `Script`, which is the path to the script
|
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
|
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
|
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"), and a later
|
array is the shell program you want to use (for example, "sh"), and a later
|
||||||
|
@ -94,6 +96,11 @@ Optional parameters:
|
||||||
sake of clarity, as even when you set only a single `command` to run,
|
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.
|
Packer writes it to a temporary file and then runs it as a script.
|
||||||
|
|
||||||
|
If you are building a windows vm on AWS, Azure or Google Compute and would
|
||||||
|
like to access the generated password that Packer uses to connect to the
|
||||||
|
instance via WinRM, you can use the template variable `{{.WinRMPassword}}`
|
||||||
|
to set this as an environment variable.
|
||||||
|
|
||||||
- `inline_shebang` (string) - The
|
- `inline_shebang` (string) - The
|
||||||
[shebang](http://en.wikipedia.org/wiki/Shebang_%28Unix%29) value to use when
|
[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
|
running commands specified by `inline`. By default, this is `/bin/sh -e`. If
|
||||||
|
|
Loading…
Reference in New Issue