packer/hcl2template/types.build.post-processor.go
Wilken Rivera e8b5b4b516
Fix {{packer_version}} interpolation regression (#11200)
* Add Packer version to main context at variable interpolation

Test Results Before Change
```
=== RUN   TestCoreBuild_packerVersion
    testing.go:30: err: template: root:1:2: executing "root" at <packer_version>: error calling packer_version: packer_version not available
--- FAIL: TestCoreBuild_packerVersion (0.00s)
```

Test Results After Change
```
=== RUN   TestCoreBuild_packerVersion
--- PASS: TestCoreBuild_packerVersion (0.00s)
```

* Add packer_core_version to interpolation context for HCL configs

Test Results Before Change
```
=== RUN   TestParse_build/provisioner_with_packer_version_interpolation
    common_test.go:109: Parser.getBuilds() unexpected diagnostics. testdata/build/provisioner_packer_version_interpolation.pkr.hcl:8,5-24: Failed preparing provisioner-block
 "shell" ""; render 'slice_string': template: root:1:2: executing "root" at <packer_version>: error calling packer_version: packer_version not available in:

        {{packer_version}}
--- FAIL: TestParse_build (0.01s)
```

Test Results After Change
```
--- PASS: TestParse_build (0.02s)
--- PASS: TestParse_build/provisioner_with_packer_version_interpolation (0.00s)
```
2021-08-12 10:55:32 +02:00

93 lines
2.7 KiB
Go

package hcl2template
import (
"fmt"
"strconv"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/gohcl"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
// ProvisionerBlock references a detected but unparsed post processor
type PostProcessorBlock struct {
PType string
PName string
OnlyExcept OnlyExcept
KeepInputArtifact *bool
HCL2Ref
}
func (p *PostProcessorBlock) String() string {
return fmt.Sprintf(buildPostProcessorLabel+"-block %q %q", p.PType, p.PName)
}
func (p *Parser) decodePostProcessor(block *hcl.Block, cfg *PackerConfig) (*PostProcessorBlock, hcl.Diagnostics) {
var b struct {
Name string `hcl:"name,optional"`
Only []string `hcl:"only,optional"`
Except []string `hcl:"except,optional"`
KeepInputArtifact *bool `hcl:"keep_input_artifact,optional"`
Rest hcl.Body `hcl:",remain"`
}
diags := gohcl.DecodeBody(block.Body, cfg.EvalContext(BuildContext, nil), &b)
if diags.HasErrors() {
return nil, diags
}
postProcessor := &PostProcessorBlock{
PType: block.Labels[0],
PName: b.Name,
OnlyExcept: OnlyExcept{Only: b.Only, Except: b.Except},
HCL2Ref: newHCL2Ref(block, b.Rest),
KeepInputArtifact: b.KeepInputArtifact,
}
diags = diags.Extend(postProcessor.OnlyExcept.Validate())
if diags.HasErrors() {
return nil, diags
}
return postProcessor, diags
}
func (cfg *PackerConfig) startPostProcessor(source SourceUseBlock, pp *PostProcessorBlock, ectx *hcl.EvalContext) (packersdk.PostProcessor, hcl.Diagnostics) {
// ProvisionerBlock represents a detected but unparsed provisioner
var diags hcl.Diagnostics
postProcessor, err := cfg.parser.PluginConfig.PostProcessors.Start(pp.PType)
if err != nil {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: fmt.Sprintf("Failed loading %s", pp.PType),
Subject: pp.DefRange.Ptr(),
Detail: err.Error(),
})
return nil, diags
}
builderVars := source.builderVariables()
builderVars["packer_core_version"] = cfg.CorePackerVersionString
builderVars["packer_debug"] = strconv.FormatBool(cfg.debug)
builderVars["packer_force"] = strconv.FormatBool(cfg.force)
builderVars["packer_on_error"] = cfg.onError
hclPostProcessor := &HCL2PostProcessor{
PostProcessor: postProcessor,
postProcessorBlock: pp,
evalContext: ectx,
builderVariables: builderVars,
}
err = hclPostProcessor.HCL2Prepare(nil)
if err != nil {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: fmt.Sprintf("Failed preparing %s", pp),
Detail: err.Error(),
Subject: pp.DefRange.Ptr(),
})
return nil, diags
}
return hclPostProcessor, diags
}