|
|
|
|
@ -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
|
|
|
|
|
}
|
|
|
|
|
|