diff --git a/hcl2template/types.build.post-processor.go b/hcl2template/types.build.post-processor.go index 1607d59b8..890f2d8d3 100644 --- a/hcl2template/types.build.post-processor.go +++ b/hcl2template/types.build.post-processor.go @@ -49,7 +49,7 @@ func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl return postProcessor, diags } -func (p *Parser) startPostProcessor(pp *PostProcessorBlock, ectx *hcl.EvalContext) (packer.PostProcessor, hcl.Diagnostics) { +func (p *Parser) startPostProcessor(pp *PostProcessorBlock, ectx *hcl.EvalContext, generatedVars map[string]string) (packer.PostProcessor, hcl.Diagnostics) { // ProvisionerBlock represents a detected but unparsed provisioner var diags hcl.Diagnostics @@ -64,7 +64,7 @@ func (p *Parser) startPostProcessor(pp *PostProcessorBlock, ectx *hcl.EvalContex } flatProvisinerCfg, moreDiags := decodeHCL2Spec(pp.Rest, ectx, postProcessor) diags = append(diags, moreDiags...) - err = postProcessor.Configure(flatProvisinerCfg) + err = postProcessor.Configure(flatProvisinerCfg, generatedVars) if err != nil { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, diff --git a/hcl2template/types.build.provisioners.go b/hcl2template/types.build.provisioners.go index d97b8c20c..862b13ca2 100644 --- a/hcl2template/types.build.provisioners.go +++ b/hcl2template/types.build.provisioners.go @@ -5,7 +5,6 @@ import ( "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/gohcl" - "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/packer" ) @@ -47,7 +46,7 @@ func (p *Parser) decodeProvisioner(block *hcl.Block) (*ProvisionerBlock, hcl.Dia return provisioner, diags } -func (p *Parser) startProvisioner(pb *ProvisionerBlock, ectx *hcl.EvalContext, generatedVars []string) (packer.Provisioner, hcl.Diagnostics) { +func (p *Parser) startProvisioner(pb *ProvisionerBlock, ectx *hcl.EvalContext, generatedVars map[string]string) (packer.Provisioner, hcl.Diagnostics) { var diags hcl.Diagnostics provisioner, err := p.ProvisionersSchemas.Start(pb.PType) @@ -67,22 +66,10 @@ func (p *Parser) startProvisioner(pb *ProvisionerBlock, ectx *hcl.EvalContext, g // manipulate generatedVars from builder to add to the interfaces being // passed to the provisioner Prepare() - // If the builder has provided a list of to-be-generated variables that - // should be made accessible to provisioners, pass that list into - // the provisioner prepare() so that the provisioner can appropriately - // validate user input against what will become available. Otherwise, - // only pass the default variables, using the basic placeholder data. - generatedPlaceholderMap := packer.BasicPlaceholderData() - if generatedVars != nil { - for _, k := range generatedVars { - generatedPlaceholderMap[k] = fmt.Sprintf("Generated_%s. "+ - common.PlaceholderMsg, k) - } - } // configs := make([]interface{}, 2) // configs = append(, flatProvisionerCfg) - // configs = append(configs, generatedPlaceholderMap) - err = provisioner.Prepare(flatProvisionerCfg, generatedPlaceholderMap) + // configs = append(configs, generatedVars) + err = provisioner.Prepare(flatProvisionerCfg, generatedVars) if err != nil { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, diff --git a/hcl2template/types.packer_config.go b/hcl2template/types.packer_config.go index 6e003d50a..4f02e2586 100644 --- a/hcl2template/types.packer_config.go +++ b/hcl2template/types.packer_config.go @@ -1,7 +1,9 @@ package hcl2template import ( + "fmt" "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/packer" "github.com/zclconf/go-cty/cty" ) @@ -42,7 +44,7 @@ func (cfg *PackerConfig) EvalContext() *hcl.EvalContext { // getCoreBuildProvisioners takes a list of provisioner block, starts according // provisioners and sends parsed HCL2 over to it. -func (p *Parser) getCoreBuildProvisioners(blocks []*ProvisionerBlock, ectx *hcl.EvalContext, generatedVars []string) ([]packer.CoreBuildProvisioner, hcl.Diagnostics) { +func (p *Parser) getCoreBuildProvisioners(blocks []*ProvisionerBlock, ectx *hcl.EvalContext, generatedVars map[string]string) ([]packer.CoreBuildProvisioner, hcl.Diagnostics) { var diags hcl.Diagnostics res := []packer.CoreBuildProvisioner{} for _, pb := range blocks { @@ -62,11 +64,11 @@ func (p *Parser) getCoreBuildProvisioners(blocks []*ProvisionerBlock, ectx *hcl. // getCoreBuildProvisioners takes a list of post processor block, starts // according provisioners and sends parsed HCL2 over to it. -func (p *Parser) getCoreBuildPostProcessors(blocks []*PostProcessorBlock, ectx *hcl.EvalContext) ([]packer.CoreBuildPostProcessor, hcl.Diagnostics) { +func (p *Parser) getCoreBuildPostProcessors(blocks []*PostProcessorBlock, ectx *hcl.EvalContext, generatedVars map[string]string) ([]packer.CoreBuildPostProcessor, hcl.Diagnostics) { var diags hcl.Diagnostics res := []packer.CoreBuildPostProcessor{} for _, ppb := range blocks { - postProcessor, moreDiags := p.startPostProcessor(ppb, ectx) + postProcessor, moreDiags := p.startPostProcessor(ppb, ectx, generatedVars) diags = append(diags, moreDiags...) if moreDiags.HasErrors() { continue @@ -104,12 +106,26 @@ func (p *Parser) getBuilds(cfg *PackerConfig) ([]packer.Build, hcl.Diagnostics) if moreDiags.HasErrors() { continue } - provisioners, moreDiags := p.getCoreBuildProvisioners(build.ProvisionerBlocks, cfg.EvalContext(), generatedVars) + + // If the builder has provided a list of to-be-generated variables that + // should be made accessible to provisioners, pass that list into + // the provisioner prepare() so that the provisioner can appropriately + // validate user input against what will become available. Otherwise, + // only pass the default variables, using the basic placeholder data. + generatedPlaceholderMap := packer.BasicPlaceholderData() + if generatedVars != nil { + for _, k := range generatedVars { + generatedPlaceholderMap[k] = fmt.Sprintf("Build_%s. "+ + common.PlaceholderMsg, k) + } + } + + provisioners, moreDiags := p.getCoreBuildProvisioners(build.ProvisionerBlocks, cfg.EvalContext(), generatedPlaceholderMap) diags = append(diags, moreDiags...) if moreDiags.HasErrors() { continue } - postProcessors, moreDiags := p.getCoreBuildPostProcessors(build.PostProcessors, cfg.EvalContext()) + postProcessors, moreDiags := p.getCoreBuildPostProcessors(build.PostProcessors, cfg.EvalContext(), generatedPlaceholderMap) pps := [][]packer.CoreBuildPostProcessor{} if len(postProcessors) > 0 { pps = [][]packer.CoreBuildPostProcessor{postProcessors} @@ -124,6 +140,7 @@ func (p *Parser) getBuilds(cfg *PackerConfig) ([]packer.Build, hcl.Diagnostics) Builder: builder, Provisioners: provisioners, PostProcessors: pps, + Prepared: true, } res = append(res, pcb) } diff --git a/hcl2template/types.packer_config_test.go b/hcl2template/types.packer_config_test.go index 38fed400a..b76133e0e 100644 --- a/hcl2template/types.packer_config_test.go +++ b/hcl2template/types.packer_config_test.go @@ -57,8 +57,9 @@ func TestParser_complete(t *testing.T) { false, false, []packer.Build{ &packer.CoreBuild{ - Type: "virtualbox-iso", - Builder: basicMockBuilder, + Type: "virtualbox-iso", + Prepared: true, + Builder: basicMockBuilder, Provisioners: []packer.CoreBuildProvisioner{ { PType: "shell", diff --git a/packer/build.go b/packer/build.go index 56a69b609..007c6ed3b 100644 --- a/packer/build.go +++ b/packer/build.go @@ -97,6 +97,9 @@ type CoreBuild struct { TemplatePath string Variables map[string]string + // Indicates whether the build is already initialized before calling Prepare(..) + Prepared bool + debug bool force bool onError string @@ -132,6 +135,13 @@ func (b *CoreBuild) Name() string { // and any hooks. This _must_ be called prior to Run. The parameter is the // overrides for the variables within the template (if any). func (b *CoreBuild) Prepare() (warn []string, err error) { + // For HCL2 templates, the builder and hooks are initialized when the template is parsed. + // Calling Prepare(...) is not necessary + if b.Prepared { + b.prepareCalled = true + return + } + b.l.Lock() defer b.l.Unlock() diff --git a/packer/build_test.go b/packer/build_test.go index e285554a6..dc1d698b6 100644 --- a/packer/build_test.go +++ b/packer/build_test.go @@ -88,6 +88,17 @@ func TestBuild_Prepare(t *testing.T) { } } +func TestBuild_Prepare_SkipWhenBuilderAlreadyInitialized(t *testing.T) { + build := testBuild() + builder := build.Builder.(*MockBuilder) + + build.Prepared = true + build.Prepare() + if builder.PrepareCalled { + t.Fatal("should not be called") + } +} + func TestBuild_Prepare_Twice(t *testing.T) { build := testBuild() warn, err := build.Prepare()