From d689e6b4d3cd651a90de77adafea1017c9969808 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 8 Mar 2018 15:14:57 -0800 Subject: [PATCH] allow users of AWS to use the dynamically-generated admin password which we use as the winRM password as an elevated password in the Powershell provisioner, as well as an environment variable in same provisoner. --- builder/amazon/common/step_get_password.go | 7 ++++++- common/step_http_server.go | 22 ++++++++-------------- provisioner/powershell/provisioner.go | 19 ++++++++++++++++++- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/builder/amazon/common/step_get_password.go b/builder/amazon/common/step_get_password.go index 5e2a236c2..c9011d930 100644 --- a/builder/amazon/common/step_get_password.go +++ b/builder/amazon/common/step_get_password.go @@ -12,6 +12,7 @@ import ( "time" "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/multistep" "github.com/hashicorp/packer/packer" @@ -92,11 +93,15 @@ WaitLoop: ui.Message(fmt.Sprintf( "Password (since debug is enabled): %s", s.Comm.WinRMPassword)) } + // store so that we can access this later during provisioning + commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword) return multistep.ActionContinue } -func (s *StepGetPassword) Cleanup(multistep.StateBag) {} +func (s *StepGetPassword) Cleanup(multistep.StateBag) { + commonhelper.RemoveSharedStateFile("winrm_password") +} func (s *StepGetPassword) waitForPassword(state multistep.StateBag, cancel <-chan struct{}) (string, error) { ec2conn := state.Get("ec2").(*ec2.EC2) diff --git a/common/step_http_server.go b/common/step_http_server.go index e90c6ef60..953ef38c1 100644 --- a/common/step_http_server.go +++ b/common/step_http_server.go @@ -3,14 +3,12 @@ package common import ( "context" "fmt" - "io/ioutil" "log" "math/rand" "net" "net/http" - "os" - "path/filepath" + "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -77,25 +75,21 @@ func (s *StepHTTPServer) Run(_ context.Context, state multistep.StateBag) multis return multistep.ActionContinue } -func httpAddrFilename(suffix string) string { - uuid := os.Getenv("PACKER_RUN_UUID") - return filepath.Join(os.TempDir(), fmt.Sprintf("packer-%s-%s", uuid, suffix)) -} - func SetHTTPPort(port string) error { - return ioutil.WriteFile(httpAddrFilename("port"), []byte(port), 0644) + return common.SetSharedState("port", port) } func SetHTTPIP(ip string) error { - return ioutil.WriteFile(httpAddrFilename("ip"), []byte(ip), 0644) + return common.SetSharedState("ip", ip) } func GetHTTPAddr() string { - ip, err := ioutil.ReadFile(httpAddrFilename("ip")) + ip, err := common.RetrieveSharedState("ip") if err != nil { return "" } - port, err := ioutil.ReadFile(httpAddrFilename("port")) + + port, err := common.RetrieveSharedState("port") if err != nil { return "" } @@ -107,6 +101,6 @@ func (s *StepHTTPServer) Cleanup(multistep.StateBag) { // Close the listener so that the HTTP server stops s.l.Close() } - os.Remove(httpAddrFilename("port")) - os.Remove(httpAddrFilename("ip")) + common.RemoveSharedStateFile("port") + common.RemoveSharedStateFile("ip") } diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 9655f6fed..a071a6b21 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common/uuid" + commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -114,7 +115,6 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { }, }, }, raws...) - if err != nil { return err } @@ -358,10 +358,17 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // Always available Packer provided env vars envVars["PACKER_BUILD_NAME"] = p.config.PackerBuildName envVars["PACKER_BUILDER_TYPE"] = p.config.PackerBuilderType + httpAddr := common.GetHTTPAddr() if httpAddr != "" { envVars["PACKER_HTTP_ADDR"] = httpAddr } + winRMPass, err := commonhelper.RetrieveSharedState("winrm_password") + // This shared state is only created by the amazon builder. + if err == nil { + envVars["AUTO_WINRM_PASSWORD"] = psEscape.Replace(winRMPass) + + } // Split vars into key/value components for _, envVar := range p.config.Vars { @@ -501,6 +508,16 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", p.config.ElevatedUser, escapedElevatedUser) } + // Replace ElevatedPassword for winrm users who used this feature + if strings.Compare(p.config.ElevatedPassword, ".AUTO_WINRM_PASSWORD") == 0 { + winRMPass, err := commonhelper.RetrieveSharedState("winrm_password") + // This shared state is only created by the amazon builder. + if err != nil { + fmt.Printf("Error reading AUTO_WINRM_PASSWORD from state: %s", err) + return "", err + } + p.config.ElevatedPassword = winRMPass + } // Escape chars special to PowerShell in the ElevatedPassword string escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword)