mirror of
https://github.com/hashicorp/packer.git
synced 2026-10-26 16:08:23 -04:00
HCL2 builds do not send the packer_user_variables config key to the
builder, provisioner and post-processor plugins. Legacy JSON builds
send this key (through CoreBuild.packerConfig()). Without the key, the
plugin SDK keeps interpolate.Context.UserVariables nil. Then the
template function {{ user "name" }} fails with 'error calling user:
test'. This failure occurs in each string that a plugin interpolates at
run time, for example the contents of the vagrant post-processor's
vagrantfile_template.
Add the function PackerConfig.userVariableValues(). This function
converts the input variable values to strings, equivalent to the legacy
user variables. The core sends the map at each plugin handoff point:
builder, provisioner, post-processor, and enforced provisioner.
The map does not contain the sensitive variables. A sensitive value
goes to a plugin only if the template refers to it explicitly. The map
does not contain values that are not primitive (lists, maps, objects).
Legacy user variables were always strings.
Co-authored-by: Claude Fable 5 <[email protected]>
100 lines
2.9 KiB
Go
100 lines
2.9 KiB
Go
// Copyright IBM Corp. 2024, 2025
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
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, ectx *hcl.EvalContext) (*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, ectx, &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
|
|
builderVars["packer_sensitive_variables"] = cfg.sensitiveInputVariableKeys()
|
|
builderVars["packer_user_variables"] = cfg.userVariableValues()
|
|
|
|
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
|
|
}
|