Merge pull request #4441 from DanHam/align_flattenenvvar
Align code and tests associated with flattening env vars across provisioners
This commit is contained in:
commit
6e60f6f625
|
@ -5,7 +5,9 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/packer/common"
|
||||
|
@ -111,17 +113,11 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
|||
}
|
||||
|
||||
// Do a check for bad environment variables, such as '=foo', 'foobar'
|
||||
for idx, kv := range p.config.Vars {
|
||||
for _, kv := range p.config.Vars {
|
||||
vs := strings.SplitN(kv, "=", 2)
|
||||
if len(vs) != 2 || vs[0] == "" {
|
||||
errs = packer.MultiErrorAppend(errs,
|
||||
fmt.Errorf("Environment variable not in format 'key=value': %s", kv))
|
||||
} else {
|
||||
// Replace single quotes so they parse
|
||||
vs[1] = strings.Replace(vs[1], "'", `'"'"'`, -1)
|
||||
|
||||
// Single quote env var values
|
||||
p.config.Vars[idx] = fmt.Sprintf("%s='%s'", vs[0], vs[1])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,18 +161,13 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
|||
tf.Close()
|
||||
}
|
||||
|
||||
// Build our variables up by adding in the build name and builder type
|
||||
envVars := make([]string, len(p.config.Vars)+2)
|
||||
envVars[0] = fmt.Sprintf("PACKER_BUILD_NAME='%s'", p.config.PackerBuildName)
|
||||
envVars[1] = fmt.Sprintf("PACKER_BUILDER_TYPE='%s'", p.config.PackerBuilderType)
|
||||
copy(envVars[2:], p.config.Vars)
|
||||
// Create environment variables to set before executing the command
|
||||
flattenedEnvVars := p.createFlattenedEnvVars()
|
||||
|
||||
for _, script := range scripts {
|
||||
// Flatten the environment variables
|
||||
flattendVars := strings.Join(envVars, " ")
|
||||
|
||||
p.config.ctx.Data = &ExecuteCommandTemplate{
|
||||
Vars: flattendVars,
|
||||
Vars: flattenedEnvVars,
|
||||
Script: script,
|
||||
}
|
||||
|
||||
|
@ -185,15 +176,13 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
|||
return nil, false, fmt.Errorf("Error processing command: %s", err)
|
||||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Post processing with local shell script: %s", command))
|
||||
ui.Say(fmt.Sprintf("Post processing with local shell script: %s", script))
|
||||
|
||||
comm := &Communicator{}
|
||||
|
||||
cmd := &packer.RemoteCmd{Command: command}
|
||||
|
||||
ui.Say(fmt.Sprintf(
|
||||
"Executing local script: %s",
|
||||
script))
|
||||
log.Printf("starting local command: %s", command)
|
||||
if err := cmd.StartWithUi(comm, ui); err != nil {
|
||||
return nil, false, fmt.Errorf(
|
||||
"Error executing script: %s\n\n"+
|
||||
|
@ -211,3 +200,33 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
|||
|
||||
return artifact, true, nil
|
||||
}
|
||||
|
||||
func (p *PostProcessor) createFlattenedEnvVars() (flattened string) {
|
||||
flattened = ""
|
||||
envVars := make(map[string]string)
|
||||
|
||||
// Always available Packer provided env vars
|
||||
envVars["PACKER_BUILD_NAME"] = fmt.Sprintf("%s", p.config.PackerBuildName)
|
||||
envVars["PACKER_BUILDER_TYPE"] = fmt.Sprintf("%s", p.config.PackerBuilderType)
|
||||
|
||||
// Split vars into key/value components
|
||||
for _, envVar := range p.config.Vars {
|
||||
keyValue := strings.SplitN(envVar, "=", 2)
|
||||
// Store pair, replacing any single quotes in value so they parse
|
||||
// correctly with required environment variable format
|
||||
envVars[keyValue[0]] = strings.Replace(keyValue[1], "'", `'"'"'`, -1)
|
||||
}
|
||||
|
||||
// Create a list of env var keys in sorted order
|
||||
var keys []string
|
||||
for k := range envVars {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
// Re-assemble vars surrounding value with single quotes and flatten
|
||||
for _, key := range keys {
|
||||
flattened += fmt.Sprintf("%s='%s' ", key, envVars[key])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -198,22 +198,57 @@ func TestPostProcessorPrepare_EnvironmentVars(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Test when the env variable value contains an equals sign
|
||||
config["environment_vars"] = []string{"good=withequals=true"}
|
||||
p = new(PostProcessor)
|
||||
err = p.Configure(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Test when the env variable value starts with an equals sign
|
||||
config["environment_vars"] = []string{"good==true"}
|
||||
p = new(PostProcessor)
|
||||
err = p.Configure(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostProcessorQuote_EnvironmentVars(t *testing.T) {
|
||||
func TestPostProcessor_createFlattenedEnvVars(t *testing.T) {
|
||||
var flattenedEnvVars string
|
||||
config := testConfig()
|
||||
|
||||
config["environment_vars"] = []string{"keyone=valueone", "keytwo=value\ntwo"}
|
||||
userEnvVarTests := [][]string{
|
||||
{}, // No user env var
|
||||
{"FOO=bar"}, // Single user env var
|
||||
{"FOO=bar's"}, // User env var with single quote in value
|
||||
{"FOO=bar", "BAZ=qux"}, // Multiple user env vars
|
||||
{"FOO=bar=baz"}, // User env var with value containing equals
|
||||
{"FOO==bar"}, // User env var with value starting with equals
|
||||
}
|
||||
expected := []string{
|
||||
`PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`FOO='bar' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`FOO='bar'"'"'s' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`BAZ='qux' FOO='bar' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`FOO='bar=baz' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`FOO='=bar' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
}
|
||||
|
||||
p := new(PostProcessor)
|
||||
p.Configure(config)
|
||||
|
||||
expectedValue := "keyone='valueone'"
|
||||
if p.config.Vars[0] != expectedValue {
|
||||
t.Fatalf("%s should be equal to %s", p.config.Vars[0], expectedValue)
|
||||
}
|
||||
// Defaults provided by Packer
|
||||
p.config.PackerBuildName = "vmware"
|
||||
p.config.PackerBuilderType = "iso"
|
||||
|
||||
expectedValue = "keytwo='value\ntwo'"
|
||||
if p.config.Vars[1] != expectedValue {
|
||||
t.Fatalf("%s should be equal to %s", p.config.Vars[1], expectedValue)
|
||||
for i, expectedValue := range expected {
|
||||
p.config.Vars = userEnvVarTests[i]
|
||||
flattenedEnvVars = p.createFlattenedEnvVars()
|
||||
if flattenedEnvVars != expectedValue {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -331,7 +331,7 @@ func (p *Provisioner) retryable(f func() error) error {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string, err error) {
|
||||
func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) {
|
||||
flattened = ""
|
||||
envVars := make(map[string]string)
|
||||
|
||||
|
@ -346,11 +346,6 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string, e
|
|||
// Split vars into key/value components
|
||||
for _, envVar := range p.config.Vars {
|
||||
keyValue := strings.SplitN(envVar, "=", 2)
|
||||
|
||||
if len(keyValue) != 2 || keyValue[0] == "" {
|
||||
err = errors.New(fmt.Sprintf("Shell provisioner environment variables must be in key=value format. Currently it is '%s'", envVar))
|
||||
return
|
||||
}
|
||||
envVars[keyValue[0]] = keyValue[1]
|
||||
}
|
||||
|
||||
|
@ -383,10 +378,8 @@ func (p *Provisioner) createCommandText() (command string, err error) {
|
|||
|
||||
func (p *Provisioner) createCommandTextNonPrivileged() (command string, err error) {
|
||||
// Create environment variables to set before executing the command
|
||||
flattenedEnvVars, err := p.createFlattenedEnvVars(false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
flattenedEnvVars := p.createFlattenedEnvVars(false)
|
||||
|
||||
p.config.ctx.Data = &ExecuteCommandTemplate{
|
||||
Vars: flattenedEnvVars,
|
||||
Path: p.config.RemotePath,
|
||||
|
@ -420,10 +413,8 @@ func (p *Provisioner) generateCommandLineRunner(command string) (commandText str
|
|||
|
||||
func (p *Provisioner) createCommandTextPrivileged() (command string, err error) {
|
||||
// Can't double escape the env vars, lets create shiny new ones
|
||||
flattenedEnvVars, err := p.createFlattenedEnvVars(true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
flattenedEnvVars := p.createFlattenedEnvVars(true)
|
||||
|
||||
p.config.ctx.Data = &ExecuteCommandTemplate{
|
||||
Vars: flattenedEnvVars,
|
||||
Path: p.config.RemotePath,
|
||||
|
|
|
@ -550,113 +550,73 @@ func TestProvisionerProvision_UISlurp(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) {
|
||||
var flattenedEnvVars string
|
||||
config := testConfig()
|
||||
|
||||
p := new(Provisioner)
|
||||
err := p.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error preparing config: %s", err)
|
||||
userEnvVarTests := [][]string{
|
||||
{}, // No user env var
|
||||
{"FOO=bar"}, // Single user env var
|
||||
{"FOO=bar", "BAZ=qux"}, // Multiple user env vars
|
||||
{"FOO=bar=baz"}, // User env var with value containing equals
|
||||
{"FOO==bar"}, // User env var with value starting with equals
|
||||
}
|
||||
expected := []string{
|
||||
`$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
`$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
`$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
`$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
`$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
}
|
||||
|
||||
p := new(Provisioner)
|
||||
p.Prepare(config)
|
||||
|
||||
// Defaults provided by Packer
|
||||
p.config.PackerBuildName = "vmware"
|
||||
p.config.PackerBuilderType = "iso"
|
||||
|
||||
// no user env var
|
||||
flattenedEnvVars, err := p.createFlattenedEnvVars(true)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
if flattenedEnvVars != `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; ` {
|
||||
t.Fatalf("unexpected flattened env vars: %s", flattenedEnvVars)
|
||||
}
|
||||
|
||||
// single user env var
|
||||
p.config.Vars = []string{"FOO=bar"}
|
||||
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars(true)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
if flattenedEnvVars != `$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; ` {
|
||||
t.Fatalf("unexpected flattened env vars: %s", flattenedEnvVars)
|
||||
}
|
||||
|
||||
// multiple user env vars
|
||||
p.config.Vars = []string{"FOO=bar", "BAZ=qux"}
|
||||
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars(true)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
if flattenedEnvVars != `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; ` {
|
||||
t.Fatalf("unexpected flattened env vars: %s", flattenedEnvVars)
|
||||
}
|
||||
|
||||
// Environment variable with value containing equals
|
||||
p.config.Vars = []string{"FOO=bar=baz"}
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars(true)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
if flattenedEnvVars != `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; ` {
|
||||
t.Fatalf("unexpected flattened env vars: %s", flattenedEnvVars)
|
||||
}
|
||||
|
||||
// Environment variable with value starting with equals
|
||||
p.config.Vars = []string{"FOO==baz"}
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars(true)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
if flattenedEnvVars != `$env:FOO="=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; ` {
|
||||
t.Fatalf("unexpected flattened env vars: %s", flattenedEnvVars)
|
||||
for i, expectedValue := range expected {
|
||||
p.config.Vars = userEnvVarTests[i]
|
||||
flattenedEnvVars = p.createFlattenedEnvVars(true)
|
||||
if flattenedEnvVars != expectedValue {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) {
|
||||
var flattenedEnvVars string
|
||||
config := testConfig()
|
||||
|
||||
p := new(Provisioner)
|
||||
err := p.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error preparing config: %s", err)
|
||||
userEnvVarTests := [][]string{
|
||||
{}, // No user env var
|
||||
{"FOO=bar"}, // Single user env var
|
||||
{"FOO=bar", "BAZ=qux"}, // Multiple user env vars
|
||||
{"FOO=bar=baz"}, // User env var with value containing equals
|
||||
{"FOO==bar"}, // User env var with value starting with equals
|
||||
}
|
||||
expected := []string{
|
||||
`$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
`$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
`$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
`$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
`$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
||||
}
|
||||
|
||||
p := new(Provisioner)
|
||||
p.Prepare(config)
|
||||
|
||||
// Defaults provided by Packer
|
||||
p.config.PackerBuildName = "vmware"
|
||||
p.config.PackerBuilderType = "iso"
|
||||
|
||||
// no user env var
|
||||
flattenedEnvVars, err := p.createFlattenedEnvVars(false)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
if flattenedEnvVars != `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; ` {
|
||||
t.Fatalf("unexpected flattened env vars: %s", flattenedEnvVars)
|
||||
}
|
||||
|
||||
// single user env var
|
||||
p.config.Vars = []string{"FOO=bar"}
|
||||
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars(false)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
if flattenedEnvVars != `$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; ` {
|
||||
t.Fatalf("unexpected flattened env vars: %s", flattenedEnvVars)
|
||||
}
|
||||
|
||||
// multiple user env vars
|
||||
p.config.Vars = []string{"FOO=bar", "BAZ=qux"}
|
||||
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars(false)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
if flattenedEnvVars != `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; ` {
|
||||
t.Fatalf("unexpected flattened env vars: %s", flattenedEnvVars)
|
||||
for i, expectedValue := range expected {
|
||||
p.config.Vars = userEnvVarTests[i]
|
||||
flattenedEnvVars = p.createFlattenedEnvVars(false)
|
||||
if flattenedEnvVars != expectedValue {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -167,17 +168,11 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
}
|
||||
|
||||
// Do a check for bad environment variables, such as '=foo', 'foobar'
|
||||
for idx, kv := range p.config.Vars {
|
||||
for _, kv := range p.config.Vars {
|
||||
vs := strings.SplitN(kv, "=", 2)
|
||||
if len(vs) != 2 || vs[0] == "" {
|
||||
errs = packer.MultiErrorAppend(errs,
|
||||
fmt.Errorf("Environment variable not in format 'key=value': %s", kv))
|
||||
} else {
|
||||
// Replace single quotes so they parse
|
||||
vs[1] = strings.Replace(vs[1], "'", `'"'"'`, -1)
|
||||
|
||||
// Single quote env var values
|
||||
p.config.Vars[idx] = fmt.Sprintf("%s='%s'", vs[0], vs[1])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,16 +223,8 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
|||
tf.Close()
|
||||
}
|
||||
|
||||
// Build our variables up by adding in the build name and builder type
|
||||
envVars := make([]string, len(p.config.Vars)+2)
|
||||
envVars[0] = fmt.Sprintf("PACKER_BUILD_NAME='%s'", p.config.PackerBuildName)
|
||||
envVars[1] = fmt.Sprintf("PACKER_BUILDER_TYPE='%s'", p.config.PackerBuilderType)
|
||||
|
||||
copy(envVars[2:], p.config.Vars)
|
||||
httpAddr := common.GetHTTPAddr()
|
||||
if httpAddr != "" {
|
||||
envVars = append(envVars, fmt.Sprintf("PACKER_HTTP_ADDR=%s", common.GetHTTPAddr()))
|
||||
}
|
||||
// Create environment variables to set before executing the command
|
||||
flattenedEnvVars := p.createFlattenedEnvVars()
|
||||
|
||||
for _, path := range scripts {
|
||||
ui.Say(fmt.Sprintf("Provisioning with shell script: %s", path))
|
||||
|
@ -249,12 +236,9 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
// Flatten the environment variables
|
||||
flattendVars := strings.Join(envVars, " ")
|
||||
|
||||
// Compile the command
|
||||
p.config.ctx.Data = &ExecuteCommandTemplate{
|
||||
Vars: flattendVars,
|
||||
Vars: flattenedEnvVars,
|
||||
Path: p.config.RemotePath,
|
||||
}
|
||||
command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx)
|
||||
|
@ -377,3 +361,37 @@ func (p *Provisioner) retryable(f func() error) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provisioner) createFlattenedEnvVars() (flattened string) {
|
||||
flattened = ""
|
||||
envVars := make(map[string]string)
|
||||
|
||||
// Always available Packer provided env vars
|
||||
envVars["PACKER_BUILD_NAME"] = fmt.Sprintf("%s", p.config.PackerBuildName)
|
||||
envVars["PACKER_BUILDER_TYPE"] = fmt.Sprintf("%s", p.config.PackerBuilderType)
|
||||
httpAddr := common.GetHTTPAddr()
|
||||
if httpAddr != "" {
|
||||
envVars["PACKER_HTTP_ADDR"] = fmt.Sprintf("%s", httpAddr)
|
||||
}
|
||||
|
||||
// Split vars into key/value components
|
||||
for _, envVar := range p.config.Vars {
|
||||
keyValue := strings.SplitN(envVar, "=", 2)
|
||||
// Store pair, replacing any single quotes in value so they parse
|
||||
// correctly with required environment variable format
|
||||
envVars[keyValue[0]] = strings.Replace(keyValue[1], "'", `'"'"'`, -1)
|
||||
}
|
||||
|
||||
// Create a list of env var keys in sorted order
|
||||
var keys []string
|
||||
for k := range envVars {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
// Re-assemble vars surrounding value with single quotes and flatten
|
||||
for _, key := range keys {
|
||||
flattened += fmt.Sprintf("%s='%s' ", key, envVars[key])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -231,23 +231,58 @@ func TestProvisionerPrepare_EnvironmentVars(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Test when the env variable value contains an equals sign
|
||||
config["environment_vars"] = []string{"good=withequals=true"}
|
||||
p = new(Provisioner)
|
||||
err = p.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Test when the env variable value starts with an equals sign
|
||||
config["environment_vars"] = []string{"good==true"}
|
||||
p = new(Provisioner)
|
||||
err = p.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvisionerQuote_EnvironmentVars(t *testing.T) {
|
||||
func TestProvisioner_createFlattenedEnvVars(t *testing.T) {
|
||||
var flattenedEnvVars string
|
||||
config := testConfig()
|
||||
|
||||
config["environment_vars"] = []string{"keyone=valueone", "keytwo=value\ntwo"}
|
||||
userEnvVarTests := [][]string{
|
||||
{}, // No user env var
|
||||
{"FOO=bar"}, // Single user env var
|
||||
{"FOO=bar's"}, // User env var with single quote in value
|
||||
{"FOO=bar", "BAZ=qux"}, // Multiple user env vars
|
||||
{"FOO=bar=baz"}, // User env var with value containing equals
|
||||
{"FOO==bar"}, // User env var with value starting with equals
|
||||
}
|
||||
expected := []string{
|
||||
`PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`FOO='bar' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`FOO='bar'"'"'s' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`BAZ='qux' FOO='bar' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`FOO='bar=baz' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
`FOO='=bar' PACKER_BUILDER_TYPE='iso' PACKER_BUILD_NAME='vmware' `,
|
||||
}
|
||||
|
||||
p := new(Provisioner)
|
||||
p.Prepare(config)
|
||||
|
||||
expectedValue := "keyone='valueone'"
|
||||
if p.config.Vars[0] != expectedValue {
|
||||
t.Fatalf("%s should be equal to %s", p.config.Vars[0], expectedValue)
|
||||
}
|
||||
// Defaults provided by Packer
|
||||
p.config.PackerBuildName = "vmware"
|
||||
p.config.PackerBuilderType = "iso"
|
||||
|
||||
expectedValue = "keytwo='value\ntwo'"
|
||||
if p.config.Vars[1] != expectedValue {
|
||||
t.Fatalf("%s should be equal to %s", p.config.Vars[1], expectedValue)
|
||||
for i, expectedValue := range expected {
|
||||
p.config.Vars = userEnvVarTests[i]
|
||||
flattenedEnvVars = p.createFlattenedEnvVars()
|
||||
if flattenedEnvVars != expectedValue {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -207,10 +207,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
|||
defer f.Close()
|
||||
|
||||
// Create environment variables to set before executing the command
|
||||
flattendVars, err := p.createFlattenedEnvVars()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
flattendVars := p.createFlattenedEnvVars()
|
||||
|
||||
// Compile the command
|
||||
p.config.ctx.Data = &ExecuteCommandTemplate{
|
||||
|
@ -287,7 +284,7 @@ func (p *Provisioner) retryable(f func() error) error {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Provisioner) createFlattenedEnvVars() (flattened string, err error) {
|
||||
func (p *Provisioner) createFlattenedEnvVars() (flattened string) {
|
||||
flattened = ""
|
||||
envVars := make(map[string]string)
|
||||
|
||||
|
@ -302,10 +299,6 @@ func (p *Provisioner) createFlattenedEnvVars() (flattened string, err error) {
|
|||
// Split vars into key/value components
|
||||
for _, envVar := range p.config.Vars {
|
||||
keyValue := strings.SplitN(envVar, "=", 2)
|
||||
if len(keyValue) != 2 || keyValue[0] == "" {
|
||||
err = errors.New(fmt.Sprintf("Shell provisioner environment variables must be in key=value format. Currently it is '%s'", envVar))
|
||||
return
|
||||
}
|
||||
envVars[keyValue[0]] = keyValue[1]
|
||||
}
|
||||
// Create a list of env var keys in sorted order
|
||||
|
|
|
@ -378,72 +378,37 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) {
|
||||
var flattenedEnvVars string
|
||||
config := testConfig()
|
||||
|
||||
p := new(Provisioner)
|
||||
err := p.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error preparing config: %s", err)
|
||||
userEnvVarTests := [][]string{
|
||||
{}, // No user env var
|
||||
{"FOO=bar"}, // Single user env var
|
||||
{"FOO=bar", "BAZ=qux"}, // Multiple user env vars
|
||||
{"FOO=bar=baz"}, // User env var with value containing equals
|
||||
{"FOO==bar"}, // User env var with value starting with equals
|
||||
}
|
||||
expected := []string{
|
||||
`set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `,
|
||||
`set "FOO=bar" && set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `,
|
||||
`set "BAZ=qux" && set "FOO=bar" && set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `,
|
||||
`set "FOO=bar=baz" && set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `,
|
||||
`set "FOO==bar" && set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `,
|
||||
}
|
||||
|
||||
p := new(Provisioner)
|
||||
p.Prepare(config)
|
||||
|
||||
// Defaults provided by Packer
|
||||
p.config.PackerBuildName = "vmware"
|
||||
p.config.PackerBuilderType = "iso"
|
||||
|
||||
// no user env var
|
||||
flattenedEnvVars, err := p.createFlattenedEnvVars()
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
expectedEnvVars := `set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `
|
||||
if flattenedEnvVars != expectedEnvVars {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got: %s", expectedEnvVars, flattenedEnvVars)
|
||||
}
|
||||
|
||||
// single user env var
|
||||
p.config.Vars = []string{"FOO=bar"}
|
||||
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars()
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
expectedEnvVars = `set "FOO=bar" && set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `
|
||||
if flattenedEnvVars != expectedEnvVars {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got: %s", expectedEnvVars, flattenedEnvVars)
|
||||
}
|
||||
|
||||
// multiple user env vars
|
||||
p.config.Vars = []string{"FOO=bar", "BAZ=qux"}
|
||||
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars()
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
expectedEnvVars = `set "BAZ=qux" && set "FOO=bar" && set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `
|
||||
if flattenedEnvVars != expectedEnvVars {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got: %s", expectedEnvVars, flattenedEnvVars)
|
||||
}
|
||||
|
||||
// Environment variable with value containing equals
|
||||
p.config.Vars = []string{"FOO=bar=baz"}
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars()
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
expectedEnvVars = `set "FOO=bar=baz" && set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `
|
||||
if flattenedEnvVars != expectedEnvVars {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got: %s", expectedEnvVars, flattenedEnvVars)
|
||||
}
|
||||
|
||||
// Environment variable with value starting with equals
|
||||
p.config.Vars = []string{"FOO==baz"}
|
||||
flattenedEnvVars, err = p.createFlattenedEnvVars()
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error creating flattened env vars: %s", err)
|
||||
}
|
||||
expectedEnvVars = `set "FOO==baz" && set "PACKER_BUILDER_TYPE=iso" && set "PACKER_BUILD_NAME=vmware" && `
|
||||
if flattenedEnvVars != expectedEnvVars {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got: %s", expectedEnvVars, flattenedEnvVars)
|
||||
for i, expectedValue := range expected {
|
||||
p.config.Vars = userEnvVarTests[i]
|
||||
flattenedEnvVars = p.createFlattenedEnvVars()
|
||||
if flattenedEnvVars != expectedValue {
|
||||
t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue