diff --git a/packer/build.go b/packer/build.go index 9e300fec3..8b610296e 100644 --- a/packer/build.go +++ b/packer/build.go @@ -29,7 +29,7 @@ type coreBuild struct { // within the build. type coreBuildProvisioner struct { provisioner Provisioner - config interface{} + config []interface{} } // Returns the name of the build. @@ -51,7 +51,7 @@ func (b *coreBuild) Prepare(ui Ui) (err error) { // Prepare the provisioners for _, coreProv := range b.provisioners { - if err = coreProv.provisioner.Prepare(coreProv.config); err != nil { + if err = coreProv.provisioner.Prepare(coreProv.config...); err != nil { return } } diff --git a/packer/build_test.go b/packer/build_test.go index fb748561c..ef48757c0 100644 --- a/packer/build_test.go +++ b/packer/build_test.go @@ -14,7 +14,7 @@ func testBuild() Build { "foo": []Hook{&TestHook{}}, }, provisioners: []coreBuildProvisioner{ - coreBuildProvisioner{&TestProvisioner{}, 42}, + coreBuildProvisioner{&TestProvisioner{}, []interface{}{42}}, }, } } diff --git a/packer/template.go b/packer/template.go index 1a48b40e5..585764ac4 100644 --- a/packer/template.go +++ b/packer/template.go @@ -220,7 +220,16 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err return } - coreProv := coreBuildProvisioner{provisioner, rawProvisioner.rawConfig} + configs := make([]interface{}, 1, 2) + configs[0] = rawProvisioner.rawConfig + + if rawProvisioner.Override != nil { + if override, ok := rawProvisioner.Override[name]; ok { + configs = append(configs, override) + } + } + + coreProv := coreBuildProvisioner{provisioner, configs} provisioners = append(provisioners, coreProv) } diff --git a/packer/template_test.go b/packer/template_test.go index 91265e68f..7b90fb5e2 100644 --- a/packer/template_test.go +++ b/packer/template_test.go @@ -448,3 +448,59 @@ func TestTemplate_Build(t *testing.T) { assert.Equal(coreBuild.builderConfig, expectedConfig, "should have proper config") assert.Equal(len(coreBuild.provisioners), 1, "should have one provisioner") } + +func TestTemplate_Build_ProvisionerOverride(t *testing.T) { + assert := asserts.NewTestingAsserts(t, true) + + data := ` + { + "name": "my-image", + "builders": [ + { + "name": "test1", + "type": "test-builder" + } + ], + + "provisioners": [ + { + "type": "test-prov", + + "override": { + "test1": {} + } + } + ] + } + ` + + template, err := ParseTemplate([]byte(data)) + assert.Nil(err, "should not error") + + builder := testBuilder() + builderMap := map[string]Builder{ + "test-builder": builder, + } + + provisioner := &TestProvisioner{} + provisionerMap := map[string]Provisioner{ + "test-prov": provisioner, + } + + builderFactory := func(n string) (Builder, error) { return builderMap[n], nil } + provFactory := func(n string) (Provisioner, error) { return provisionerMap[n], nil } + components := &ComponentFinder{ + Builder: builderFactory, + Provisioner: provFactory, + } + + // Get the build, verifying we can get it without issue, but also + // that the proper builder was looked up and used for the build. + build, err := template.Build("test1", components) + assert.Nil(err, "should not error") + + coreBuild, ok := build.(*coreBuild) + assert.True(ok, "should be a core build") + assert.Equal(len(coreBuild.provisioners), 1, "should have one provisioner") + assert.Equal(len(coreBuild.provisioners[0].config), 2, "should have two configs on the provisioner") +}