From 000ace61a3880b95fe897cd079d7d7a56618f212 Mon Sep 17 00:00:00 2001 From: teddylear Date: Tue, 17 May 2022 22:06:03 -0400 Subject: [PATCH 1/2] feat: Add pause_after config to powershell provisioner like shell provisioner --- provisioner/powershell/provisioner.go | 10 ++++++ .../powershell/provisioner.hcl2spec.go | 2 ++ provisioner/powershell/provisioner_test.go | 33 +++++++++++++++++++ .../content/docs/provisioners/powershell.mdx | 3 ++ 4 files changed, 48 insertions(+) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 9e762ea18..1b0dbe226 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -88,6 +88,9 @@ type Config struct { // ``` DebugMode int `mapstructure:"debug_mode"` + // A duration of how long to pause after the provisioner + PauseAfter time.Duration `mapstructure:"pause_after"` + ctx interpolate.Context } @@ -351,6 +354,13 @@ func (p *Provisioner) Provision(ctx context.Context, ui packersdk.Ui, comm packe log.Printf("remote cleanup script failed to upload; skipping the removal of temporary files: %s; ", strings.Join(uploadedScripts, ",")) } + if p.config.PauseAfter != 0 { ui.Say(fmt.Sprintf("Pausing %s after this provisioner...", p.config.PauseAfter)) + select { + case <-time.After(p.config.PauseAfter): + return nil + } + } + return nil } diff --git a/provisioner/powershell/provisioner.hcl2spec.go b/provisioner/powershell/provisioner.hcl2spec.go index cbeb427ce..04109019e 100644 --- a/provisioner/powershell/provisioner.hcl2spec.go +++ b/provisioner/powershell/provisioner.hcl2spec.go @@ -37,6 +37,7 @@ type FlatConfig struct { ElevatedPassword *string `mapstructure:"elevated_password" cty:"elevated_password" hcl:"elevated_password"` ExecutionPolicy *string `mapstructure:"execution_policy" cty:"execution_policy" hcl:"execution_policy"` DebugMode *int `mapstructure:"debug_mode" cty:"debug_mode" hcl:"debug_mode"` + PauseAfter *string `mapstructure:"pause_after" cty:"pause_after" hcl:"pause_after"` } // FlatMapstructure returns a new FlatConfig. @@ -78,6 +79,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "elevated_password": &hcldec.AttrSpec{Name: "elevated_password", Type: cty.String, Required: false}, "execution_policy": &hcldec.AttrSpec{Name: "execution_policy", Type: cty.String, Required: false}, "debug_mode": &hcldec.AttrSpec{Name: "debug_mode", Type: cty.Number, Required: false}, + "pause_after": &hcldec.AttrSpec{Name: "pause_after", Type: cty.String, Required: false}, } return s } diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index 65cbbe897..3e95e22a1 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -381,6 +381,39 @@ func TestProvisionerProvision_ValidExitCodes(t *testing.T) { } } +func TestProvisionerProvision_PauseAfter(t *testing.T) { + config := testConfig() + delete(config, "inline") + + // Defaults provided by Packer + config["remote_path"] = "c:/Windows/Temp/inlineScript.ps1" + config["inline"] = []string{"whoami"} + ui := testUi() + p := new(Provisioner) + + // Defaults provided by Packer + p.config.PackerBuildName = "vmware" + p.config.PackerBuilderType = "iso" + p.config.ValidExitCodes = []int{0, 200} + pause_amount := time.Duration(1 * time.Second) + p.config.PauseAfter = pause_amount + comm := new(packersdk.MockCommunicator) + comm.StartExitStatus = 200 + p.Prepare(config) + + start_time := time.Now() + err := p.Provision(context.Background(), ui, comm, generatedData()) + end_time := time.Now() + + if err != nil { + t.Fatal("should not have error") + } + + if end_time.Sub(start_time) < pause_amount { + t.Fatal("Didn't wait pause_amount") + } +} + func TestProvisionerProvision_InvalidExitCodes(t *testing.T) { config := testConfig() delete(config, "inline") diff --git a/website/content/docs/provisioners/powershell.mdx b/website/content/docs/provisioners/powershell.mdx index f0402121b..5120a7d0b 100644 --- a/website/content/docs/provisioners/powershell.mdx +++ b/website/content/docs/provisioners/powershell.mdx @@ -244,6 +244,9 @@ provisioner "powershell" { exists in order to deal with times when SSH may restart, such as a system reboot. Set this to a higher value if reboots take a longer amount of time. +- `pause_after` (string) - Wait the amount of time after provisioning a powershell + script, this pause be taken if all previous steps were successful. + @include 'provisioners/common-config.mdx' ## Default Environmental Variables From d00a41c6aeb49df2871dbf75f4b0604c1e9197ea Mon Sep 17 00:00:00 2001 From: teddylear Date: Fri, 27 May 2022 19:16:43 -0400 Subject: [PATCH 2/2] fix: updates to have make fmt-check and ci-lint pass --- provisioner/powershell/provisioner.go | 8 +++----- provisioner/powershell/provisioner_test.go | 9 ++++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 1b0dbe226..b3d44ffa3 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -354,11 +354,9 @@ func (p *Provisioner) Provision(ctx context.Context, ui packersdk.Ui, comm packe log.Printf("remote cleanup script failed to upload; skipping the removal of temporary files: %s; ", strings.Join(uploadedScripts, ",")) } - if p.config.PauseAfter != 0 { ui.Say(fmt.Sprintf("Pausing %s after this provisioner...", p.config.PauseAfter)) - select { - case <-time.After(p.config.PauseAfter): - return nil - } + if p.config.PauseAfter != 0 { + ui.Say(fmt.Sprintf("Pausing %s after this provisioner...", p.config.PauseAfter)) + time.Sleep(p.config.PauseAfter) } return nil diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index 3e95e22a1..515c85ff8 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -395,14 +395,17 @@ func TestProvisionerProvision_PauseAfter(t *testing.T) { p.config.PackerBuildName = "vmware" p.config.PackerBuilderType = "iso" p.config.ValidExitCodes = []int{0, 200} - pause_amount := time.Duration(1 * time.Second) + pause_amount := time.Second p.config.PauseAfter = pause_amount comm := new(packersdk.MockCommunicator) comm.StartExitStatus = 200 - p.Prepare(config) + err := p.Prepare(config) + if err != nil { + t.Fatalf("Prepar failed: %s", err) + } start_time := time.Now() - err := p.Provision(context.Background(), ui, comm, generatedData()) + err = p.Provision(context.Background(), ui, comm, generatedData()) end_time := time.Now() if err != nil {