diff --git a/packer/template.go b/packer/template.go index 01ffd8eaa..36cc846a4 100644 --- a/packer/template.go +++ b/packer/template.go @@ -162,6 +162,10 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err panic("no builder function") } + if len(t.Provisioners) > 0 && components.Provisioner == nil { + panic("no provisioner function") + } + builder, err := components.Builder(builderConfig.builderType) if err != nil { return diff --git a/packer/template_test.go b/packer/template_test.go index 152737a65..c6889878b 100644 --- a/packer/template_test.go +++ b/packer/template_test.go @@ -327,6 +327,69 @@ func TestTemplate_Build_NilBuilderFunc(t *testing.T) { template.Build("test1", &ComponentFinder{}) } +func TestTemplate_Build_NilProvisionerFunc(t *testing.T) { + assert := asserts.NewTestingAsserts(t, true) + + data := ` + { + "name": "my-image", + "builders": [ + { + "name": "test1", + "type": "test-builder" + } + ], + + "provisioners": [ + { + "type": "test-prov" + } + ] + } + ` + + template, err := ParseTemplate([]byte(data)) + assert.Nil(err, "should not error") + + defer func() { + p := recover() + assert.NotNil(p, "should panic") + + if p != nil { + assert.Equal(p.(string), "no provisioner function", "right panic") + } + }() + + template.Build("test1", &ComponentFinder{ + Builder: func(string) (Builder, error) { return nil, nil }, + }) +} + +func TestTemplate_Build_NilProvisionerFunc_WithNoProvisioners(t *testing.T) { + assert := asserts.NewTestingAsserts(t, true) + + data := ` + { + "name": "my-image", + "builders": [ + { + "name": "test1", + "type": "test-builder" + } + ], + + "provisioners": [] + } + ` + + template, err := ParseTemplate([]byte(data)) + assert.Nil(err, "should not error") + + template.Build("test1", &ComponentFinder{ + Builder: func(string) (Builder, error) { return nil, nil }, + }) +} + func TestTemplate_Build(t *testing.T) { assert := asserts.NewTestingAsserts(t, true)