|
|
|
|
@ -10,6 +10,7 @@ import (
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/hashicorp/packer/common"
|
|
|
|
|
commonhelper "github.com/hashicorp/packer/helper/common"
|
|
|
|
|
"github.com/hashicorp/packer/helper/config"
|
|
|
|
|
"github.com/hashicorp/packer/packer"
|
|
|
|
|
"github.com/hashicorp/packer/provisioner"
|
|
|
|
|
@ -65,6 +66,12 @@ type Config struct {
|
|
|
|
|
// The directory from which the command will be executed.
|
|
|
|
|
// Packer requires the directory to exist when running puppet.
|
|
|
|
|
WorkingDir string `mapstructure:"working_directory"`
|
|
|
|
|
|
|
|
|
|
// Instructs the communicator to run the remote script as a Windows
|
|
|
|
|
// scheduled task, effectively elevating the remote user by impersonating
|
|
|
|
|
// a logged-in user
|
|
|
|
|
ElevatedUser string `mapstructure:"elevated_user"`
|
|
|
|
|
ElevatedPassword string `mapstructure:"elevated_password"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type guestOSTypeConfig struct {
|
|
|
|
|
@ -117,6 +124,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{
|
|
|
|
|
|
|
|
|
|
type Provisioner struct {
|
|
|
|
|
config Config
|
|
|
|
|
communicator packer.Communicator
|
|
|
|
|
guestOSTypeConfig guestOSTypeConfig
|
|
|
|
|
guestCommands *provisioner.GuestCommands
|
|
|
|
|
}
|
|
|
|
|
@ -135,7 +143,17 @@ type ExecuteTemplate struct {
|
|
|
|
|
WorkingDir string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type EnvVarsTemplate struct {
|
|
|
|
|
WinRMPassword string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|
|
|
|
// Create passthrough for winrm password so we can fill it in once we know
|
|
|
|
|
// it
|
|
|
|
|
p.config.ctx.Data = &EnvVarsTemplate{
|
|
|
|
|
WinRMPassword: `{{.WinRMPassword}}`,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := config.Decode(&p.config, &config.DecodeOpts{
|
|
|
|
|
Interpolate: true,
|
|
|
|
|
InterpolateContext: &p.config.ctx,
|
|
|
|
|
@ -240,6 +258,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|
|
|
|
|
|
|
|
|
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
|
|
|
|
ui.Say("Provisioning with Puppet...")
|
|
|
|
|
p.communicator = comm
|
|
|
|
|
ui.Message("Creating Puppet staging directory...")
|
|
|
|
|
if err := p.createDir(ui, comm, p.config.StagingDir); err != nil {
|
|
|
|
|
return fmt.Errorf("Error creating staging directory: %s", err)
|
|
|
|
|
@ -316,6 +335,13 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if p.config.ElevatedUser != "" {
|
|
|
|
|
command, err = provisioner.GenerateElevatedRunner(command, p)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd := &packer.RemoteCmd{
|
|
|
|
|
Command: command,
|
|
|
|
|
}
|
|
|
|
|
@ -432,10 +458,7 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Provisioner) removeDir(ui packer.Ui, comm packer.Communicator, dir string) error {
|
|
|
|
|
cmd := &packer.RemoteCmd{
|
|
|
|
|
Command: fmt.Sprintf("rm -fr '%s'", dir),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd := &packer.RemoteCmd{Command: p.guestCommands.RemoveDir(dir)}
|
|
|
|
|
if err := cmd.StartWithUi(comm, ui); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
@ -460,3 +483,28 @@ func (p *Provisioner) uploadDirectory(ui packer.Ui, comm packer.Communicator, ds
|
|
|
|
|
|
|
|
|
|
return comm.UploadDir(dst, src, nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getWinRMPassword(buildName string) string {
|
|
|
|
|
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
|
|
|
|
|
packer.LogSecretFilter.Set(winRMPass)
|
|
|
|
|
return winRMPass
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Provisioner) Communicator() packer.Communicator {
|
|
|
|
|
return p.communicator
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Provisioner) ElevatedUser() string {
|
|
|
|
|
return p.config.ElevatedUser
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Provisioner) ElevatedPassword() string {
|
|
|
|
|
// Replace ElevatedPassword for winrm users who used this feature
|
|
|
|
|
p.config.ctx.Data = &EnvVarsTemplate{
|
|
|
|
|
WinRMPassword: getWinRMPassword(p.config.PackerBuildName),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
elevatedPassword, _ := interpolate.Render(p.config.ElevatedPassword, &p.config.ctx)
|
|
|
|
|
|
|
|
|
|
return elevatedPassword
|
|
|
|
|
}
|
|
|
|
|
|