implement template variable for accessing WinRM password in either environemnt variables or directly in execute_command or inline commands.
This commit is contained in:
parent
62e1323577
commit
846f94c964
|
@ -56,6 +56,11 @@ type Config struct {
|
|||
}
|
||||
|
||||
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{
|
||||
Interpolate: true,
|
||||
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,14 +9,20 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
commonhelper "github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type ExecuteCommandTemplate struct {
|
||||
Vars string
|
||||
Script string
|
||||
Command string
|
||||
Vars string
|
||||
Script string
|
||||
Command string
|
||||
WinRMPassword string
|
||||
}
|
||||
|
||||
type EnvVarsTemplate struct {
|
||||
WinRMPassword string
|
||||
}
|
||||
|
||||
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.
|
||||
flattenedCmd := strings.Join(interpolatedCmds, " ")
|
||||
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 {
|
||||
return false, fmt.Errorf(
|
||||
"Error executing script: %s\n\n"+
|
||||
|
@ -96,7 +106,22 @@ func createInlineScriptFile(config *Config) (string, error) {
|
|||
log.Printf("[INFO] (shell-local): Prepending inline script with %s", shebang)
|
||||
writer.WriteString(shebang)
|
||||
}
|
||||
config.Ctx.Data = &EnvVarsTemplate{
|
||||
WinRMPassword: getWinRMPassword(config.PackerBuildName),
|
||||
}
|
||||
|
||||
// generate context so you can interpolate the command
|
||||
config.Ctx.Data = &EnvVarsTemplate{
|
||||
WinRMPassword: getWinRMPassword(config.PackerBuildName),
|
||||
}
|
||||
|
||||
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 {
|
||||
return "", fmt.Errorf("Error preparing shell script: %s", err)
|
||||
}
|
||||
|
@ -118,9 +143,10 @@ func createInlineScriptFile(config *Config) (string, error) {
|
|||
// the host OS
|
||||
func createInterpolatedCommands(config *Config, script string, flattenedEnvVars string) ([]string, error) {
|
||||
config.Ctx.Data = &ExecuteCommandTemplate{
|
||||
Vars: flattenedEnvVars,
|
||||
Script: script,
|
||||
Command: script,
|
||||
Vars: flattenedEnvVars,
|
||||
Script: script,
|
||||
Command: script,
|
||||
WinRMPassword: getWinRMPassword(config.PackerBuildName),
|
||||
}
|
||||
|
||||
interpolatedCmds := make([]string, len(config.ExecuteCommand))
|
||||
|
@ -142,8 +168,17 @@ func createFlattenedEnvVars(config *Config) (string, error) {
|
|||
envVars["PACKER_BUILD_NAME"] = fmt.Sprintf("%s", config.PackerBuildName)
|
||||
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
|
||||
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)
|
||||
// Store pair, replacing any single quotes in value so they parse
|
||||
// correctly with required environment variable format
|
||||
|
@ -162,3 +197,8 @@ func createFlattenedEnvVars(config *Config) (string, error) {
|
|||
}
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
- `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
|
||||
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.
|
||||
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.
|
||||
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
|
||||
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"), and a later
|
||||
|
@ -94,6 +96,11 @@ Optional parameters:
|
|||
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.
|
||||
|
||||
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
|
||||
[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
|
||||
|
|
Loading…
Reference in New Issue