Json vs HCL2 parity refactor (#9301)

* refactor so that json and hcl2 templates are both prepared in the same place in the build call, to make code easier to reason about. Remove overly verbose error output which isn't useful in vast majority of cases

* fix tests

* check err msg

* hcl2template.PackerConfig.GetBuilds: raise a diagnostic in case the packer core build perpare call errors

Co-authored-by: Adrien Delorme <adrien.delorme@icloud.com>
This commit is contained in:
Megan Marsh 2020-05-28 01:43:58 -07:00 committed by GitHub
parent d3859cf592
commit 3dc4ba2d68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 28 deletions

View File

@ -188,31 +188,6 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int
log.Printf("Force build: %v", cla.Force)
log.Printf("On error: %v", cla.OnError)
// Set the debug and force mode and prepare all the builds
// This is only affects json templates, because HCL2
// templates have already been prepared in GetBuilds() above.
for i := range builds {
b := builds[i]
log.Printf("Preparing build: %s", b.Name())
b.SetDebug(cla.Debug)
b.SetForce(cla.Force)
b.SetOnError(cla.OnError)
warnings, err := b.Prepare()
if err != nil {
c.Ui.Error(err.Error())
return 1
}
if len(warnings) > 0 {
ui := buildUis[b]
ui.Say(fmt.Sprintf("Warnings for build '%s':\n", b.Name()))
for _, warning := range warnings {
ui.Say(fmt.Sprintf("* %s", warning))
}
ui.Say("")
}
}
// Run all the builds in parallel and wait for them to complete
var wg sync.WaitGroup
var artifacts = struct {

View File

@ -359,6 +359,19 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packer.Build
PostProcessors: pps,
Prepared: true,
}
// Prepare just sets the "prepareCalled" flag on CoreBuild, since
// we did all the prep here.
_, err := pcb.Prepare()
if err != nil {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: fmt.Sprintf("Preparing packer core build %s failed", src.Ref().String()),
Detail: err.Error(),
Subject: build.HCL2Ref.DefRange.Ptr(),
})
continue
}
res = append(res, pcb)
}
}

View File

@ -144,7 +144,7 @@ func Decode(target interface{}, config *DecodeOpts, raws ...interface{}) error {
for _, unused := range md.Unused {
if unused != "type" && !strings.HasPrefix(unused, "packer_") {
err = multierror.Append(err, fmt.Errorf(
"unknown configuration key: %q; raws is %#v \n\n and ctx data is %#v", unused, raws, ctxData))
"unknown configuration key: %q", unused))
}
}
if err != nil {

View File

@ -135,8 +135,8 @@ 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
// 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
@ -149,6 +149,8 @@ func (b *CoreBuild) Prepare() (warn []string, err error) {
panic("prepare already called")
}
// Templates loaded from HCL2 will never get here. TODO: move this code into
// a custom json area instead of just aborting early for HCL.
b.prepareCalled = true
packerConfig := map[string]interface{}{

View File

@ -216,6 +216,32 @@ func (c *Core) GetBuilds(opts GetBuildsOptions) ([]Build, hcl.Diagnostics) {
continue
}
builds = append(builds, b)
// Now that build plugin has been launched, call Prepare()
log.Printf("Preparing build: %s", b.Name())
b.SetDebug(opts.Debug)
b.SetForce(opts.Force)
b.SetOnError(opts.OnError)
warnings, err := b.Prepare()
if err != nil {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: fmt.Sprintf("Failed to prepare build: %q", n),
Detail: err.Error(),
})
continue
}
if len(warnings) > 0 {
for _, warning := range warnings {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagWarning,
Summary: fmt.Sprintf("Warning when preparing build: %q", n),
Detail: warning,
})
}
}
}
return builds, diags
}