Commit 02bb5b0a authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

packer: template process build names [GH-744]

parent 107e47fe
...@@ -39,6 +39,8 @@ IMPROVEMENTS: ...@@ -39,6 +39,8 @@ IMPROVEMENTS:
* core: Plugins communicate over a single TCP connection per plugin now, * core: Plugins communicate over a single TCP connection per plugin now,
instead of sometimes dozens. Performance around plugin communication instead of sometimes dozens. Performance around plugin communication
dramatically increased. dramatically increased.
* core: Build names are now template processed so you can use things
like user variables in them. [GH-744]
* builder/amazon/all: Launched EC2 instances now have a name of * builder/amazon/all: Launched EC2 instances now have a name of
"Packer Builder" so that they are easily recognizable. [GH-642] "Packer Builder" so that they are easily recognizable. [GH-642]
* builder/amazon/all: Copying AMIs to multiple regions now happens * builder/amazon/all: Copying AMIs to multiple regions now happens
......
...@@ -142,5 +142,9 @@ func (c Command) Run(env packer.Environment, args []string) int { ...@@ -142,5 +142,9 @@ func (c Command) Run(env packer.Environment, args []string) int {
} }
} }
ui.Say("\nNote: If your build names contain user variables or template\n" +
"functions such as 'timestamp', these are processed at build time,\n" +
"and therefore only show in their raw form here.")
return 0 return 0
} }
...@@ -446,6 +446,39 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err ...@@ -446,6 +446,39 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
return return
} }
// Prepare the variables
var varErrors []error
variables := make(map[string]string)
for k, v := range t.Variables {
if v.Required && !v.HasValue {
varErrors = append(varErrors,
fmt.Errorf("Required user variable '%s' not set", k))
}
var val string = v.Default
if v.HasValue {
val = v.Value
}
variables[k] = val
}
if len(varErrors) > 0 {
return nil, &MultiError{varErrors}
}
// Process the name
tpl, err := NewConfigTemplate()
if err != nil {
return nil, err
}
tpl.UserVars = variables
name, err = tpl.Process(name, nil)
if err != nil {
return nil, err
}
// Gather the Hooks // Gather the Hooks
hooks := make(map[string][]Hook) hooks := make(map[string][]Hook)
for tplEvent, tplHooks := range t.Hooks { for tplEvent, tplHooks := range t.Hooks {
...@@ -542,27 +575,6 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err ...@@ -542,27 +575,6 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
provisioners = append(provisioners, coreProv) provisioners = append(provisioners, coreProv)
} }
// Prepare the variables
var varErrors []error
variables := make(map[string]string)
for k, v := range t.Variables {
if v.Required && !v.HasValue {
varErrors = append(varErrors,
fmt.Errorf("Required user variable '%s' not set", k))
}
var val string = v.Default
if v.HasValue {
val = v.Value
}
variables[k] = val
}
if len(varErrors) > 0 {
return nil, &MultiError{varErrors}
}
b = &coreBuild{ b = &coreBuild{
name: name, name: name,
builder: builder, builder: builder,
......
...@@ -688,6 +688,48 @@ func TestTemplate_BuildUnknownBuilder(t *testing.T) { ...@@ -688,6 +688,48 @@ func TestTemplate_BuildUnknownBuilder(t *testing.T) {
} }
} }
func TestTemplateBuild_names(t *testing.T) {
data := `
{
"variables": {
"foo": null
},
"builders": [
{
"name": "test1",
"type": "test-builder"
},
{
"name": "test2-{{user \"foo\"}}",
"type": "test-builder"
}
]
}
`
template, err := ParseTemplate([]byte(data), map[string]string{"foo": "bar"})
if err != nil {
t.Fatalf("err: %s", err)
}
b, err := template.Build("test1", testComponentFinder())
if err != nil {
t.Fatalf("err: %s", err)
}
if b.Name() != "test1" {
t.Fatalf("bad: %#v", b.Name())
}
b, err = template.Build("test2-{{user \"foo\"}}", testComponentFinder())
if err != nil {
t.Fatalf("err: %s", err)
}
if b.Name() != "test2-bar" {
t.Fatalf("bad: %#v", b.Name())
}
}
func TestTemplate_Build_NilBuilderFunc(t *testing.T) { func TestTemplate_Build_NilBuilderFunc(t *testing.T) {
data := ` data := `
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment