Going to revert this change for now, becuase of potential issues that arise from calling Prepare() twice

Revert "use statebag instead of SetSharedState for winRM password"

This reverts commit b35acbd879.
This commit is contained in:
Megan Marsh 2018-09-10 16:48:42 -07:00
parent 351cdc8508
commit a0edaf6c46
16 changed files with 67 additions and 128 deletions

View File

@ -12,6 +12,7 @@ import (
"time" "time"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
@ -94,13 +95,15 @@ WaitLoop:
"Password (since debug is enabled): %s", s.Comm.WinRMPassword)) "Password (since debug is enabled): %s", s.Comm.WinRMPassword))
} }
// store so that we can access this later during provisioning // store so that we can access this later during provisioning
state.Put("winrm_password", s.Comm.WinRMPassword)
commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName)
packer.LogSecretFilter.Set(s.Comm.WinRMPassword) packer.LogSecretFilter.Set(s.Comm.WinRMPassword)
return multistep.ActionContinue return multistep.ActionContinue
} }
func (s *StepGetPassword) Cleanup(multistep.StateBag) { func (s *StepGetPassword) Cleanup(multistep.StateBag) {
commonhelper.RemoveSharedStateFile("winrm_password", s.BuildName)
} }
func (s *StepGetPassword) waitForPassword(state multistep.StateBag, cancel <-chan struct{}) (string, error) { func (s *StepGetPassword) waitForPassword(state multistep.StateBag, cancel <-chan struct{}) (string, error) {

View File

@ -22,6 +22,7 @@ import (
"github.com/hashicorp/packer/builder/azure/common/constants" "github.com/hashicorp/packer/builder/azure/common/constants"
"github.com/hashicorp/packer/builder/azure/pkcs12" "github.com/hashicorp/packer/builder/azure/pkcs12"
"github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
@ -359,7 +360,10 @@ func setRuntimeValues(c *Config) {
var tempName = NewTempName() var tempName = NewTempName()
c.tmpAdminPassword = tempName.AdminPassword c.tmpAdminPassword = tempName.AdminPassword
// store so that we can access this later during provisioning
commonhelper.SetSharedState("winrm_password", c.tmpAdminPassword, c.PackerConfig.PackerBuildName)
packer.LogSecretFilter.Set(c.tmpAdminPassword) packer.LogSecretFilter.Set(c.tmpAdminPassword)
c.tmpCertificatePassword = tempName.CertificatePassword c.tmpCertificatePassword = tempName.CertificatePassword
if c.TempComputeName == "" { if c.TempComputeName == "" {
c.tmpComputeName = tempName.ComputeName c.tmpComputeName = tempName.ComputeName

View File

@ -3,6 +3,7 @@ package arm
import ( import (
"context" "context"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
) )
@ -14,10 +15,11 @@ type StepSaveWinRMPassword struct {
func (s *StepSaveWinRMPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { func (s *StepSaveWinRMPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
// store so that we can access this later during provisioning // store so that we can access this later during provisioning
state.Put("winrm_password", s.Password) commonhelper.SetSharedState("winrm_password", s.Password, s.BuildName)
packer.LogSecretFilter.Set(s.Password) packer.LogSecretFilter.Set(s.Password)
return multistep.ActionContinue return multistep.ActionContinue
} }
func (s *StepSaveWinRMPassword) Cleanup(multistep.StateBag) { func (s *StepSaveWinRMPassword) Cleanup(multistep.StateBag) {
commonhelper.RemoveSharedStateFile("winrm_password", s.BuildName)
} }

View File

@ -13,6 +13,7 @@ import (
"os" "os"
"time" "time"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
) )
@ -113,6 +114,7 @@ func (s *StepCreateWindowsPassword) Run(_ context.Context, state multistep.State
} }
state.Put("winrm_password", data.password) state.Put("winrm_password", data.password)
commonhelper.SetSharedState("winrm_password", data.password, c.PackerConfig.PackerBuildName)
packer.LogSecretFilter.Set(data.password) packer.LogSecretFilter.Set(data.password)
return multistep.ActionContinue return multistep.ActionContinue

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"log" "log"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
@ -51,9 +52,8 @@ func (s *stepGetDefaultCredentials) Run(ctx context.Context, state multistep.Sta
} }
// store so that we can access this later during provisioning // store so that we can access this later during provisioning
state.Put("winrm_password", s.Comm.WinRMPassword) commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName)
packer.LogSecretFilter.Set(s.Comm.WinRMPassword) packer.LogSecretFilter.Set(s.Comm.WinRMPassword)
return multistep.ActionContinue return multistep.ActionContinue
} }

View File

@ -53,9 +53,6 @@ type Config struct {
UseLinuxPathing bool `mapstructure:"use_linux_pathing"` UseLinuxPathing bool `mapstructure:"use_linux_pathing"`
Ctx interpolate.Context Ctx interpolate.Context
// internal use only; for the provisioner.
WinRMPassword string
} }
func Decode(config *Config, raws ...interface{}) error { func Decode(config *Config, raws ...interface{}) error {

View File

@ -10,6 +10,7 @@ import (
"strings" "strings"
"github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common"
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"
) )
@ -69,7 +70,6 @@ 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}
packer.LogSecretFilter.Set(config.WinRMPassword)
log.Printf("[INFO] (shell-local): starting local command: %s", flattenedCmd) log.Printf("[INFO] (shell-local): starting local command: %s", flattenedCmd)
if err := cmd.StartWithUi(comm, ui); err != nil { if err := cmd.StartWithUi(comm, ui); err != nil {
return false, fmt.Errorf( return false, fmt.Errorf(
@ -105,7 +105,7 @@ func createInlineScriptFile(config *Config) (string, error) {
// generate context so you can interpolate the command // generate context so you can interpolate the command
config.Ctx.Data = &EnvVarsTemplate{ config.Ctx.Data = &EnvVarsTemplate{
WinRMPassword: config.WinRMPassword, WinRMPassword: getWinRMPassword(config.PackerBuildName),
} }
for _, command := range config.Inline { for _, command := range config.Inline {
@ -139,7 +139,7 @@ func createInterpolatedCommands(config *Config, script string, flattenedEnvVars
Vars: flattenedEnvVars, Vars: flattenedEnvVars,
Script: script, Script: script,
Command: script, Command: script,
WinRMPassword: config.WinRMPassword, WinRMPassword: getWinRMPassword(config.PackerBuildName),
} }
interpolatedCmds := make([]string, len(config.ExecuteCommand)) interpolatedCmds := make([]string, len(config.ExecuteCommand))
@ -169,7 +169,7 @@ func createFlattenedEnvVars(config *Config) (string, error) {
// interpolate environment variables // interpolate environment variables
config.Ctx.Data = &EnvVarsTemplate{ config.Ctx.Data = &EnvVarsTemplate{
WinRMPassword: config.WinRMPassword, 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 {
@ -196,3 +196,9 @@ func createFlattenedEnvVars(config *Config) (string, error) {
} }
return flattened, nil return flattened, nil
} }
func getWinRMPassword(buildName string) string {
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
packer.LogSecretFilter.Set(winRMPass)
return winRMPass
}

View File

@ -22,10 +22,6 @@ type StepProvision struct {
Comm packer.Communicator Comm packer.Communicator
} }
type ProvisionHookData struct {
WinRMPassword string
}
func (s *StepProvision) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { func (s *StepProvision) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
comm := s.Comm comm := s.Comm
if comm == nil { if comm == nil {
@ -37,21 +33,12 @@ func (s *StepProvision) Run(_ context.Context, state multistep.StateBag) multist
hook := state.Get("hook").(packer.Hook) hook := state.Get("hook").(packer.Hook)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
// Save data we need to give to provisioners
WinRMPassword, ok := state.GetOk("winrm_password")
if !ok {
WinRMPassword = ""
} else {
WinRMPassword = WinRMPassword.(string)
}
phd := ProvisionHookData{WinRMPassword.(string)}
// Run the provisioner in a goroutine so we can continually check // Run the provisioner in a goroutine so we can continually check
// for cancellations... // for cancellations...
log.Println("Running the provision hook") log.Println("Running the provision hook")
errCh := make(chan error, 1) errCh := make(chan error, 1)
go func() { go func() {
errCh <- hook.Run(packer.HookProvision, ui, comm, phd) errCh <- hook.Run(packer.HookProvision, ui, comm, nil)
}() }()
for { for {

View File

@ -44,10 +44,6 @@ type ProvisionHook struct {
runningProvisioner Provisioner runningProvisioner Provisioner
} }
type ProvisionHookData struct {
WinRMPassword string
}
// Runs the provisioners in order. // Runs the provisioners in order.
func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interface{}) error { func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interface{}) error {
// Shortcut // Shortcut
@ -75,15 +71,8 @@ func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interfac
h.lock.Unlock() h.lock.Unlock()
ts := CheckpointReporter.AddSpan(p.TypeName, "provisioner", p.Config) ts := CheckpointReporter.AddSpan(p.TypeName, "provisioner", p.Config)
// re-run prepare with builder-generated config variables (e.g. WinRMPassword)
// Hack Alert. #SorryNotSorry.
err := p.Provisioner.Prepare(data)
if err != nil {
log.Printf("Error performing secondary Prepare: %s", err)
}
// Finally, provision. err := p.Provisioner.Provision(ui, comm)
err = p.Provisioner.Provision(ui, comm)
ts.End(err) ts.End(err)
if err != nil { if err != nil {

View File

@ -14,10 +14,8 @@ type MockProvisioner struct {
} }
func (t *MockProvisioner) Prepare(configs ...interface{}) error { func (t *MockProvisioner) Prepare(configs ...interface{}) error {
if !t.PrepCalled {
t.PrepCalled = true t.PrepCalled = true
t.PrepConfigs = configs t.PrepConfigs = configs
}
return nil return nil
} }

View File

@ -26,6 +26,7 @@ import (
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate" "github.com/hashicorp/packer/template/interpolate"
@ -57,8 +58,6 @@ type Config struct {
UseSFTP bool `mapstructure:"use_sftp"` UseSFTP bool `mapstructure:"use_sftp"`
InventoryDirectory string `mapstructure:"inventory_directory"` InventoryDirectory string `mapstructure:"inventory_directory"`
InventoryFile string `mapstructure:"inventory_file"` InventoryFile string `mapstructure:"inventory_file"`
// for internal use only; unsettable by user.
winrmpassword string
} }
type Provisioner struct { type Provisioner struct {
@ -74,35 +73,14 @@ type PassthroughTemplate struct {
} }
func (p *Provisioner) Prepare(raws ...interface{}) error { func (p *Provisioner) Prepare(raws ...interface{}) error {
// This is a bit of a hack. For provisioners that need access to
// auto-generated WinRMPasswords, the mechanism of keeping provisioner data
// and build data totally segregated breaks down. We get around this by
// having the builder stash the WinRMPassword in the state bag, then
// grabbing it out of the statebag inside of StepProvision. Then, when
// the time comes to provision for real, we run the prepare step one more
// time, now with WinRMPassword defined in the raws, and can store the
// password on the provisioner config without overwriting the rest of the
// work we've already done in the first prepare run.
if len(raws) == 1 {
for k, v := range raws[0].(map[interface{}]interface{}) {
if k.(string) == "WinRMPassword" {
p.config.winrmpassword = v.(string)
// Even if WinRMPassword is not gonna be used, we've stored the
// key and pointed it to an empty string. That means we'll
// always reach this on our second-run of Prepare()
return nil
}
}
}
p.done = make(chan struct{}) p.done = make(chan struct{})
// don't interpolate winrmpassword yet; if we've made it to this line, then // Create passthrough for winrm password so we can fill it in once we know
// we have not obtained the winrm password yet. // it
p.config.ctx.Data = &PassthroughTemplate{ p.config.ctx.Data = &PassthroughTemplate{
WinRMPassword: `{{.WinRMPassword}}`, WinRMPassword: `{{.WinRMPassword}}`,
} }
err := config.Decode(&p.config, &config.DecodeOpts{ err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true, Interpolate: true,
InterpolateContext: &p.config.ctx, InterpolateContext: &p.config.ctx,
@ -222,9 +200,8 @@ func (p *Provisioner) getVersion() error {
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
ui.Say("Provisioning with Ansible...") ui.Say("Provisioning with Ansible...")
// Interpolate env vars to check for .WinRMPassword // Interpolate env vars to check for .WinRMPassword
packer.LogSecretFilter.Set(p.config.winrmpassword)
p.config.ctx.Data = &PassthroughTemplate{ p.config.ctx.Data = &PassthroughTemplate{
WinRMPassword: p.config.winrmpassword, WinRMPassword: getWinRMPassword(p.config.PackerBuildName),
} }
for i, envVar := range p.config.AnsibleEnvVars { for i, envVar := range p.config.AnsibleEnvVars {
envVar, err := interpolate.Render(envVar, &p.config.ctx) envVar, err := interpolate.Render(envVar, &p.config.ctx)
@ -443,7 +420,12 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, pri
// remove winrm password from command, if it's been added // remove winrm password from command, if it's been added
flattenedCmd := strings.Join(cmd.Args, " ") flattenedCmd := strings.Join(cmd.Args, " ")
ui.Say(fmt.Sprintf("Executing Ansible: %s", flattenedCmd)) sanitized := flattenedCmd
if len(getWinRMPassword(p.config.PackerBuildName)) > 0 {
sanitized = strings.Replace(sanitized,
getWinRMPassword(p.config.PackerBuildName), "*****", -1)
}
ui.Say(fmt.Sprintf("Executing Ansible: %s", sanitized))
if err := cmd.Start(); err != nil { if err := cmd.Start(); err != nil {
return err return err
@ -571,6 +553,12 @@ func newSigner(privKeyFile string) (*signer, error) {
return signer, nil return signer, nil
} }
func getWinRMPassword(buildName string) string {
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
packer.LogSecretFilter.Set(winRMPass)
return winRMPass
}
// Ui provides concurrency-safe access to packer.Ui. // Ui provides concurrency-safe access to packer.Ui.
type Ui struct { type Ui struct {
sem chan int sem chan int

View File

@ -16,8 +16,8 @@ import (
// Be sure to remove the Ansible stub file in each test with: // Be sure to remove the Ansible stub file in each test with:
// defer os.Remove(config["command"].(string)) // defer os.Remove(config["command"].(string))
func testConfig(t *testing.T) map[interface{}]interface{} { func testConfig(t *testing.T) map[string]interface{} {
m := make((map[interface{}]interface{})) m := make(map[string]interface{})
wd, err := os.Getwd() wd, err := os.Getwd()
if err != nil { if err != nil {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)

View File

@ -17,6 +17,7 @@ import (
"github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/uuid" "github.com/hashicorp/packer/common/uuid"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate" "github.com/hashicorp/packer/template/interpolate"
@ -97,9 +98,6 @@ type Config struct {
// Changes will not be effective until the system is rebooted." // Changes will not be effective until the system is rebooted."
ValidExitCodes []int `mapstructure:"valid_exit_codes"` ValidExitCodes []int `mapstructure:"valid_exit_codes"`
// internal variable, to be written to at provisioner run time.
winrmpassword string
ctx interpolate.Context ctx interpolate.Context
} }
@ -119,28 +117,8 @@ type EnvVarsTemplate struct {
} }
func (p *Provisioner) Prepare(raws ...interface{}) error { func (p *Provisioner) Prepare(raws ...interface{}) error {
// This is a bit of a hack. For provisioners that need access to // Create passthrough for winrm password so we can fill it in once we know
// auto-generated WinRMPasswords, the mechanism of keeping provisioner data // it
// and build data totally segregated breaks down. We get around this by
// having the builder stash the WinRMPassword in the state bag, then
// grabbing it out of the statebag inside of StepProvision. Then, when
// the time comes to provision for real, we run the prepare step one more
// time, now with WinRMPassword defined in the raws, and can store the
// password on the provisioner config without overwriting the rest of the
// work we've already done in the first prepare run.
if len(raws) == 1 {
for k, v := range raws[0].(map[interface{}]interface{}) {
if k.(string) == "WinRMPassword" {
p.config.winrmpassword = v.(string)
// Even if WinRMPassword is not gonna be used, we've stored the
// key and pointed it to an empty string. That means we'll
// always reach this on our second-run of Prepare()
return nil
}
}
}
// Only get here if it's the first time the Provisioner's Prepare is run
p.config.ctx.Data = &EnvVarsTemplate{ p.config.ctx.Data = &EnvVarsTemplate{
WinRMPassword: `{{.WinRMPassword}}`, WinRMPassword: `{{.WinRMPassword}}`,
} }
@ -157,7 +135,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
}, raws...) }, raws...)
if err != nil { if err != nil {
return fmt.Errorf("Error decoding powershell provisioner template: %s", err) return err
} }
if p.config.EnvVarFormat == "" { if p.config.EnvVarFormat == "" {
@ -283,7 +261,7 @@ func extractScript(p *Provisioner) (string, error) {
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
ui.Say(fmt.Sprintf("Provisioning with Powershell...")) ui.Say(fmt.Sprintf("Provisioning with Powershell..."))
p.communicator = comm p.communicator = comm
packer.LogSecretFilter.Set(p.config.winrmpassword)
scripts := make([]string, len(p.config.Scripts)) scripts := make([]string, len(p.config.Scripts))
copy(scripts, p.config.Scripts) copy(scripts, p.config.Scripts)
@ -414,7 +392,7 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) {
// interpolate environment variables // interpolate environment variables
p.config.ctx.Data = &EnvVarsTemplate{ p.config.ctx.Data = &EnvVarsTemplate{
WinRMPassword: p.config.winrmpassword, WinRMPassword: getWinRMPassword(p.config.PackerBuildName),
} }
// Split vars into key/value components // Split vars into key/value components
for _, envVar := range p.config.Vars { for _, envVar := range p.config.Vars {
@ -489,7 +467,7 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro
p.config.ctx.Data = &ExecuteCommandTemplate{ p.config.ctx.Data = &ExecuteCommandTemplate{
Path: p.config.RemotePath, Path: p.config.RemotePath,
Vars: p.config.RemoteEnvVarPath, Vars: p.config.RemoteEnvVarPath,
WinRMPassword: p.config.winrmpassword, WinRMPassword: getWinRMPassword(p.config.PackerBuildName),
} }
command, err = interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) command, err = interpolate.Render(p.config.ExecuteCommand, &p.config.ctx)
@ -501,6 +479,12 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro
return command, nil return command, nil
} }
func getWinRMPassword(buildName string) string {
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
packer.LogSecretFilter.Set(winRMPass)
return winRMPass
}
func (p *Provisioner) createCommandTextPrivileged() (command string, err error) { func (p *Provisioner) createCommandTextPrivileged() (command string, err error) {
// Prepare everything needed to enable the required env vars within the // Prepare everything needed to enable the required env vars within the
// remote environment // remote environment
@ -512,7 +496,7 @@ func (p *Provisioner) createCommandTextPrivileged() (command string, err error)
p.config.ctx.Data = &ExecuteCommandTemplate{ p.config.ctx.Data = &ExecuteCommandTemplate{
Path: p.config.RemotePath, Path: p.config.RemotePath,
Vars: p.config.RemoteEnvVarPath, Vars: p.config.RemoteEnvVarPath,
WinRMPassword: p.config.winrmpassword, WinRMPassword: getWinRMPassword(p.config.PackerBuildName),
} }
command, err = interpolate.Render(p.config.ElevatedExecuteCommand, &p.config.ctx) command, err = interpolate.Render(p.config.ElevatedExecuteCommand, &p.config.ctx)
if err != nil { if err != nil {
@ -571,7 +555,7 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin
} }
// Replace ElevatedPassword for winrm users who used this feature // Replace ElevatedPassword for winrm users who used this feature
p.config.ctx.Data = &EnvVarsTemplate{ p.config.ctx.Data = &EnvVarsTemplate{
WinRMPassword: p.config.winrmpassword, WinRMPassword: getWinRMPassword(p.config.PackerBuildName),
} }
p.config.ElevatedPassword, _ = interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) p.config.ElevatedPassword, _ = interpolate.Render(p.config.ElevatedPassword, &p.config.ctx)

View File

@ -14,8 +14,8 @@ import (
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
) )
func testConfig() map[interface{}]interface{} { func testConfig() map[string]interface{} {
return map[interface{}]interface{}{ return map[string]interface{}{
"inline": []interface{}{"foo", "bar"}, "inline": []interface{}{"foo", "bar"},
} }
} }

View File

@ -10,27 +10,6 @@ type Provisioner struct {
} }
func (p *Provisioner) Prepare(raws ...interface{}) error { func (p *Provisioner) Prepare(raws ...interface{}) error {
// This is a bit of a hack. For provisioners that need access to
// auto-generated WinRMPasswords, the mechanism of keeping provisioner data
// and build data totally segregated breaks down. We get around this by
// having the builder stash the WinRMPassword in the state bag, then
// grabbing it out of the statebag inside of StepProvision. Then, when
// the time comes to provision for real, we run the prepare step one more
// time, now with WinRMPassword defined in the raws, and can store the
// password on the provisioner config without overwriting the rest of the
// work we've already done in the first prepare run.
if len(raws) == 1 {
for k, v := range raws[0].(map[interface{}]interface{}) {
if k.(string) == "WinRMPassword" {
p.config.WinRMPassword = v.(string)
// Even if WinRMPassword is not gonna be used, we've stored the
// key and pointed it to an empty string. That means we'll
// always reach this on our second-run of Prepare()
return nil
}
}
}
err := sl.Decode(&p.config, raws...) err := sl.Decode(&p.config, raws...)
if err != nil { if err != nil {
return err return err

View File

@ -48,8 +48,8 @@ func TestConfigPrepare(t *testing.T) {
} }
} }
func testConfig(t *testing.T) map[interface{}]interface{} { func testConfig(t *testing.T) map[string]interface{} {
return map[interface{}]interface{}{ return map[string]interface{}{
"command": "echo foo", "command": "echo foo",
} }
} }