backport 1.13.1 changes to release/1.13.x (#13405)

* Merge pull request #13404 from hashicorp/karthik/prepare_version_1.13.1

prepare version 1.13.1

* Merge pull request #13396 from hashicorp/karthik/powershell_fix

Powershell Script Config Environment Variables Fix
release/1.13.x v1.13.1
kp2099 11 months ago committed by GitHub
parent b9fbe81e35
commit 89be76ccb7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -11,6 +11,7 @@ import (
"context"
"errors"
"fmt"
"io"
"log"
"os"
"path/filepath"
@ -265,9 +266,43 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
return nil
}
// extractScript prepares a temporary PowerShell script by prepending environment setup and debug config.
// It copies the contents of the provided script file into the temp script and returns its path.
func extractScript(p *Provisioner, script string) (string, error) {
temp, err := tmp.File("powershell-provisioner-script")
if err != nil {
return "", err
}
defer temp.Close()
baseString := `if (Test-Path variable:global:ProgressPreference)` +
`{set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'};`
if p.config.DebugMode != 0 {
baseString += fmt.Sprintf(`Set-PsDebug -Trace %d;`, p.config.DebugMode)
}
baseString += p.createFlattenedEnvVars(p.config.ElevatedUser != "")
if _, err := temp.WriteString(baseString); err != nil {
return "", fmt.Errorf("Error writing PowerShell script: %w", err)
}
f, err := os.Open(script)
if err != nil {
return "", fmt.Errorf("Error opening powershell script: %s", err)
}
defer f.Close()
if _, err := io.Copy(temp, f); err != nil {
return "", fmt.Errorf("Error copying script contents: %w", err)
}
return temp.Name(), nil
}
// Takes the inline scripts, adds a wrapper around the inline scripts, concatenates them into a temporary file and
// returns a string containing the location of said file.
func extractScript(p *Provisioner) (string, error) {
func extractInlineScript(p *Provisioner) (string, error) {
temp, err := tmp.File("powershell-provisioner")
if err != nil {
return "", err
@ -280,7 +315,7 @@ func extractScript(p *Provisioner) (string, error) {
// we concatenate all the inline commands
for _, command := range p.config.Inline {
log.Printf("Found command: %s", command)
if _, err := commandBuilder.WriteString(command); err != nil {
if _, err := commandBuilder.WriteString(command + "\n\t"); err != nil {
return "", fmt.Errorf("failed to wrap script contents: %w", err)
}
}
@ -310,11 +345,12 @@ func (p *Provisioner) Provision(ctx context.Context, ui packersdk.Ui, comm packe
p.communicator = comm
p.generatedData = generatedData
scripts := make([]string, len(p.config.Scripts))
copy(scripts, p.config.Scripts)
var scripts []string
// maps temp script paths to original script paths
tempToOriginalScriptMap := make(map[string]string)
if p.config.Inline != nil {
temp, err := extractScript(p)
temp, err := extractInlineScript(p)
tempToOriginalScriptMap[temp] = temp
if err != nil {
ui.Error(fmt.Sprintf("Unable to extract inline scripts into a file: %s", err))
}
@ -323,12 +359,27 @@ func (p *Provisioner) Provision(ctx context.Context, ui packersdk.Ui, comm packe
defer os.Remove(temp)
}
if len(p.config.Scripts) > 0 {
for _, script := range p.config.Scripts {
temp, err := extractScript(p, script)
tempToOriginalScriptMap[temp] = script
if err != nil {
ui.Error(fmt.Sprintf("Unable to extract script into a file: %s", err))
}
scripts = append(scripts, temp)
// Defer removal until the function exits
defer os.Remove(temp)
}
}
// every provisioner run will only have one env var script file so lets add it first
uploadedScripts := []string{p.config.RemoteEnvVarPath}
for _, path := range scripts {
ui.Say(fmt.Sprintf("Provisioning with powershell script: %s", path))
ui.Say(fmt.Sprintf("Provisioning with powershell script: %s", tempToOriginalScriptMap[path]))
log.Printf("Opening %s for reading", path)
log.Printf("Opening %s for reading", tempToOriginalScriptMap[path])
fi, err := os.Stat(path)
if err != nil {
return fmt.Errorf("Error stating powershell script: %s", err)

@ -9,6 +9,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"testing"
@ -82,6 +83,16 @@ func TestAccPowershellProvisioner_Inline(t *testing.T) {
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
}
}
out, err := os.ReadFile(logfile)
if err != nil {
return err
}
output := string(out)
regexMatchString := "test_env_var: TestValue"
if !regexp.MustCompile(regexp.QuoteMeta(regexMatchString)).MatchString(output) {
t.Errorf("expected env string %q in logs:\n%s", regexMatchString, output)
}
return nil
},
}
@ -105,6 +116,16 @@ func TestAccPowershellProvisioner_Script(t *testing.T) {
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
}
}
out, err := os.ReadFile(logfile)
if err != nil {
return err
}
output := string(out)
regexMatchString := "likewise, var2 is A`Backtick"
if !regexp.MustCompile(regexp.QuoteMeta(regexMatchString)).MatchString(output) {
t.Errorf("expected env string %q in logs:\n%s", regexMatchString, output)
}
return nil
},
}

@ -24,7 +24,7 @@ func TestProvisionerPrepare_extractScript(t *testing.T) {
p := new(Provisioner)
_ = p.Prepare(config)
p.generatedData = generatedData()
file, err := extractScript(p)
file, err := extractInlineScript(p)
defer os.Remove(file)
if err != nil {
t.Fatalf("Should not be error: %s", err)
@ -36,7 +36,7 @@ func TestProvisionerPrepare_extractScript(t *testing.T) {
// File contents should contain 2 lines concatenated by newlines: foo\nbar
readFile, err := os.ReadFile(file)
expectedContents := "if (Test-Path variable:global:ProgressPreference) {\n set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'\n }\n \n $exitCode = 0\n try {\n $env:PACKER_BUILDER_TYPE=\"\"; $env:PACKER_BUILD_NAME=\"\"; \n foobar\n $exitCode = 0\n } catch {\n Write-Error \"An error occurred: $_\"\n $exitCode = 1\n }\n \n if ($LASTEXITCODE -ne $null -and $LASTEXITCODE -ne 0) {\n $exitCode = $LASTEXITCODE\n }\n \n Write-Host $result\n exit $exitCode"
expectedContents := " \n\tif (Test-Path variable:global:ProgressPreference) {\n\t set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'\n\t}\n\t\n\t$exitCode = 0\n\ttry {\n\t$env:PACKER_BUILDER_TYPE=\"\"; $env:PACKER_BUILD_NAME=\"\"; \n\tfoo\n\tbar\n\t\n\t$exitCode = 0\n\t} catch {\n\tWrite-Error \"An error occurred: $_\"\n\t$exitCode = 1\n\t}\n\t\n\tif ($LASTEXITCODE -ne $null -and $LASTEXITCODE -ne 0) {\n\t\t$exitCode = $LASTEXITCODE\n\t}\n\t\n\tWrite-Host $result\n\texit $exitCode\n\n"
normalizedExpectedContent := normalizeWhiteSpace(expectedContents)
if err != nil {
t.Fatalf("Should not be error: %s", err)

@ -1,8 +1,10 @@
{
"type": "powershell",
"environment_vars": "PackerRunUUID={{build `PackerRunUUID`}},ID={{build `ID`}}",
"environment_vars": "PackerRunUUID={{build `PackerRunUUID`}},ID={{build `ID`}},TEST_ENV_VAR=TestValue",
"inline": [
"Write-Host \"$env:ID for provisioner.$env:PackerRunUUID\""
"Write-Host \"$env:ID for provisioner.$env:PackerRunUUID build_name: $env:packer_build_name, test_env_var: $env:test_env_var\"",
"setx BUILD_AMI_VERSION \"1.0.0\"",
"setx BUILD_AMI_NAME custom_ami_name",
"setx BUILD_AMI_DESCRIPTION \"This is a custom AMI created for testing purposes\""
]
}
}

@ -1 +1 @@
1.13.0
1.13.1

Loading…
Cancel
Save