packer: template process build names [GH-744]

This commit is contained in:
Mitchell Hashimoto 2013-12-27 09:43:59 -07:00
parent 107e47fe25
commit 02bb5b0a97
4 changed files with 81 additions and 21 deletions

View File

@ -39,6 +39,8 @@ IMPROVEMENTS:
* core: Plugins communicate over a single TCP connection per plugin now,
instead of sometimes dozens. Performance around plugin communication
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
"Packer Builder" so that they are easily recognizable. [GH-642]
* builder/amazon/all: Copying AMIs to multiple regions now happens

View File

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

View File

@ -446,6 +446,39 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
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
hooks := make(map[string][]Hook)
for tplEvent, tplHooks := range t.Hooks {
@ -542,27 +575,6 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
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{
name: name,
builder: builder,

View File

@ -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) {
data := `
{