Elevated support for puppet-masterless provisioner
This should fix #5478.
This commit is contained in:
parent
11be4ffc4b
commit
a42f8fac4d
|
@ -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/helper/config"
|
"github.com/hashicorp/packer/helper/config"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/hashicorp/packer/provisioner"
|
"github.com/hashicorp/packer/provisioner"
|
||||||
|
@ -65,6 +66,12 @@ type Config struct {
|
||||||
// The directory from which the command will be executed.
|
// The directory from which the command will be executed.
|
||||||
// Packer requires the directory to exist when running puppet.
|
// Packer requires the directory to exist when running puppet.
|
||||||
WorkingDir string `mapstructure:"working_directory"`
|
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 {
|
type guestOSTypeConfig struct {
|
||||||
|
@ -117,6 +124,7 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{
|
||||||
|
|
||||||
type Provisioner struct {
|
type Provisioner struct {
|
||||||
config Config
|
config Config
|
||||||
|
communicator packer.Communicator
|
||||||
guestOSTypeConfig guestOSTypeConfig
|
guestOSTypeConfig guestOSTypeConfig
|
||||||
guestCommands *provisioner.GuestCommands
|
guestCommands *provisioner.GuestCommands
|
||||||
}
|
}
|
||||||
|
@ -135,7 +143,17 @@ type ExecuteTemplate struct {
|
||||||
WorkingDir string
|
WorkingDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EnvVarsTemplate struct {
|
||||||
|
WinRMPassword string
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provisioner) Prepare(raws ...interface{}) error {
|
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{
|
err := config.Decode(&p.config, &config.DecodeOpts{
|
||||||
Interpolate: true,
|
Interpolate: true,
|
||||||
InterpolateContext: &p.config.ctx,
|
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 {
|
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
||||||
ui.Say("Provisioning with Puppet...")
|
ui.Say("Provisioning with Puppet...")
|
||||||
|
p.communicator = comm
|
||||||
ui.Message("Creating Puppet staging directory...")
|
ui.Message("Creating Puppet staging directory...")
|
||||||
if err := p.createDir(ui, comm, p.config.StagingDir); err != nil {
|
if err := p.createDir(ui, comm, p.config.StagingDir); err != nil {
|
||||||
return fmt.Errorf("Error creating staging directory: %s", err)
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.config.ElevatedUser != "" {
|
||||||
|
command, err = provisioner.GenerateElevatedRunner(command, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd := &packer.RemoteCmd{
|
cmd := &packer.RemoteCmd{
|
||||||
Command: command,
|
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 {
|
func (p *Provisioner) removeDir(ui packer.Ui, comm packer.Communicator, dir string) error {
|
||||||
cmd := &packer.RemoteCmd{
|
cmd := &packer.RemoteCmd{Command: p.guestCommands.RemoveDir(dir)}
|
||||||
Command: fmt.Sprintf("rm -fr '%s'", dir),
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := cmd.StartWithUi(comm, ui); err != nil {
|
if err := cmd.StartWithUi(comm, ui); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -460,3 +483,28 @@ func (p *Provisioner) uploadDirectory(ui packer.Ui, comm packer.Communicator, ds
|
||||||
|
|
||||||
return comm.UploadDir(dst, src, nil)
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue