Avoid calling CoreBuild.Prepare(...) for HCL2 templates (#8742)
This commit is contained in:
parent
7254b04129
commit
2981fd627d
@ -49,7 +49,7 @@ func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl
|
|||||||
return postProcessor, diags
|
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
|
// ProvisionerBlock represents a detected but unparsed provisioner
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ func (p *Parser) startPostProcessor(pp *PostProcessorBlock, ectx *hcl.EvalContex
|
|||||||
}
|
}
|
||||||
flatProvisinerCfg, moreDiags := decodeHCL2Spec(pp.Rest, ectx, postProcessor)
|
flatProvisinerCfg, moreDiags := decodeHCL2Spec(pp.Rest, ectx, postProcessor)
|
||||||
diags = append(diags, moreDiags...)
|
diags = append(diags, moreDiags...)
|
||||||
err = postProcessor.Configure(flatProvisinerCfg)
|
err = postProcessor.Configure(flatProvisinerCfg, generatedVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl/v2/gohcl"
|
"github.com/hashicorp/hcl/v2/gohcl"
|
||||||
"github.com/hashicorp/packer/helper/common"
|
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,7 +46,7 @@ func (p *Parser) decodeProvisioner(block *hcl.Block) (*ProvisionerBlock, hcl.Dia
|
|||||||
return provisioner, diags
|
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
|
var diags hcl.Diagnostics
|
||||||
|
|
||||||
provisioner, err := p.ProvisionersSchemas.Start(pb.PType)
|
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
|
// manipulate generatedVars from builder to add to the interfaces being
|
||||||
// passed to the provisioner Prepare()
|
// 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 := make([]interface{}, 2)
|
||||||
// configs = append(, flatProvisionerCfg)
|
// configs = append(, flatProvisionerCfg)
|
||||||
// configs = append(configs, generatedPlaceholderMap)
|
// configs = append(configs, generatedVars)
|
||||||
err = provisioner.Prepare(flatProvisionerCfg, generatedPlaceholderMap)
|
err = provisioner.Prepare(flatProvisionerCfg, generatedVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package hcl2template
|
package hcl2template
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/hashicorp/packer/helper/common"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"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
|
// getCoreBuildProvisioners takes a list of provisioner block, starts according
|
||||||
// provisioners and sends parsed HCL2 over to it.
|
// 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
|
var diags hcl.Diagnostics
|
||||||
res := []packer.CoreBuildProvisioner{}
|
res := []packer.CoreBuildProvisioner{}
|
||||||
for _, pb := range blocks {
|
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
|
// getCoreBuildProvisioners takes a list of post processor block, starts
|
||||||
// according provisioners and sends parsed HCL2 over to it.
|
// 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
|
var diags hcl.Diagnostics
|
||||||
res := []packer.CoreBuildPostProcessor{}
|
res := []packer.CoreBuildPostProcessor{}
|
||||||
for _, ppb := range blocks {
|
for _, ppb := range blocks {
|
||||||
postProcessor, moreDiags := p.startPostProcessor(ppb, ectx)
|
postProcessor, moreDiags := p.startPostProcessor(ppb, ectx, generatedVars)
|
||||||
diags = append(diags, moreDiags...)
|
diags = append(diags, moreDiags...)
|
||||||
if moreDiags.HasErrors() {
|
if moreDiags.HasErrors() {
|
||||||
continue
|
continue
|
||||||
@ -104,12 +106,26 @@ func (p *Parser) getBuilds(cfg *PackerConfig) ([]packer.Build, hcl.Diagnostics)
|
|||||||
if moreDiags.HasErrors() {
|
if moreDiags.HasErrors() {
|
||||||
continue
|
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...)
|
diags = append(diags, moreDiags...)
|
||||||
if moreDiags.HasErrors() {
|
if moreDiags.HasErrors() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
postProcessors, moreDiags := p.getCoreBuildPostProcessors(build.PostProcessors, cfg.EvalContext())
|
postProcessors, moreDiags := p.getCoreBuildPostProcessors(build.PostProcessors, cfg.EvalContext(), generatedPlaceholderMap)
|
||||||
pps := [][]packer.CoreBuildPostProcessor{}
|
pps := [][]packer.CoreBuildPostProcessor{}
|
||||||
if len(postProcessors) > 0 {
|
if len(postProcessors) > 0 {
|
||||||
pps = [][]packer.CoreBuildPostProcessor{postProcessors}
|
pps = [][]packer.CoreBuildPostProcessor{postProcessors}
|
||||||
@ -124,6 +140,7 @@ func (p *Parser) getBuilds(cfg *PackerConfig) ([]packer.Build, hcl.Diagnostics)
|
|||||||
Builder: builder,
|
Builder: builder,
|
||||||
Provisioners: provisioners,
|
Provisioners: provisioners,
|
||||||
PostProcessors: pps,
|
PostProcessors: pps,
|
||||||
|
Prepared: true,
|
||||||
}
|
}
|
||||||
res = append(res, pcb)
|
res = append(res, pcb)
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ func TestParser_complete(t *testing.T) {
|
|||||||
[]packer.Build{
|
[]packer.Build{
|
||||||
&packer.CoreBuild{
|
&packer.CoreBuild{
|
||||||
Type: "virtualbox-iso",
|
Type: "virtualbox-iso",
|
||||||
|
Prepared: true,
|
||||||
Builder: basicMockBuilder,
|
Builder: basicMockBuilder,
|
||||||
Provisioners: []packer.CoreBuildProvisioner{
|
Provisioners: []packer.CoreBuildProvisioner{
|
||||||
{
|
{
|
||||||
|
@ -97,6 +97,9 @@ type CoreBuild struct {
|
|||||||
TemplatePath string
|
TemplatePath string
|
||||||
Variables map[string]string
|
Variables map[string]string
|
||||||
|
|
||||||
|
// Indicates whether the build is already initialized before calling Prepare(..)
|
||||||
|
Prepared bool
|
||||||
|
|
||||||
debug bool
|
debug bool
|
||||||
force bool
|
force bool
|
||||||
onError string
|
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
|
// and any hooks. This _must_ be called prior to Run. The parameter is the
|
||||||
// overrides for the variables within the template (if any).
|
// overrides for the variables within the template (if any).
|
||||||
func (b *CoreBuild) Prepare() (warn []string, err error) {
|
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()
|
b.l.Lock()
|
||||||
defer b.l.Unlock()
|
defer b.l.Unlock()
|
||||||
|
|
||||||
|
@ -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) {
|
func TestBuild_Prepare_Twice(t *testing.T) {
|
||||||
build := testBuild()
|
build := testBuild()
|
||||||
warn, err := build.Prepare()
|
warn, err := build.Prepare()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user