mirror of
https://github.com/hashicorp/packer.git
synced 2026-06-09 00:32:09 -04:00
hcl2template: use refString for local/data deps
When registering dependencies for datasources and locals, we now use refString. This allows for the functions that detect dependencies to not only be able to register the same types as dependencies, but instead generalises it to any type that refString supports, so data, local and var. This can then be leveraged for orchestrating evaluation of those components in a non-phased way (i.e. with a DAG for dependency management).
This commit is contained in:
parent
8ba998a5d0
commit
9c3ec44379
3 changed files with 22 additions and 9 deletions
|
|
@ -17,6 +17,7 @@ import (
|
|||
type DatasourceBlock struct {
|
||||
Type string
|
||||
DSName string
|
||||
Dependencies []refString
|
||||
|
||||
value cty.Value
|
||||
block *hcl.Block
|
||||
|
|
|
|||
|
|
@ -245,25 +245,27 @@ func (c *PackerConfig) evaluateLocalVariables(locals []*LocalBlock) hcl.Diagnost
|
|||
// attributes, as HCL2 expressions are not allowed in a block's labels.
|
||||
vars := FilterTraversalsByType(local.Expr.Variables(), "local")
|
||||
|
||||
var localDeps []*LocalBlock
|
||||
var localDeps []refString
|
||||
for _, v := range vars {
|
||||
// Some local variables may be locally aliased as
|
||||
// `local`, which
|
||||
if len(v) < 2 {
|
||||
continue
|
||||
}
|
||||
varName := v[1].(hcl.TraverseAttr).Name
|
||||
block, err := c.localByName(varName)
|
||||
|
||||
depRef, err := NewRefStringFromDep(v)
|
||||
if err != nil {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Missing variable dependency",
|
||||
Detail: fmt.Sprintf("The expression for variable %q depends on local.%s, which is not defined.",
|
||||
local.Name, varName),
|
||||
Summary: "failed to extract dependency name from traversal ref",
|
||||
Detail: fmt.Sprintf("while preparing for evaluation of local variable %q, "+
|
||||
"a dependency was unable to be converted to a refString. "+
|
||||
"This is likely a Packer bug, please consider reporting it.", local.Name),
|
||||
})
|
||||
continue
|
||||
}
|
||||
localDeps = append(localDeps, block)
|
||||
|
||||
localDeps = append(localDeps, depRef)
|
||||
}
|
||||
local.dependencies = localDeps
|
||||
}
|
||||
|
|
@ -325,7 +327,17 @@ func (c *PackerConfig) recursivelyEvaluateLocalVariable(local *LocalBlock, depth
|
|||
var diags hcl.Diagnostics
|
||||
|
||||
for _, dep := range local.dependencies {
|
||||
localDiags := c.recursivelyEvaluateLocalVariable(dep, depth+1)
|
||||
locBlock, err := c.getComponentByRef(dep)
|
||||
if err != nil {
|
||||
return diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "failed to get local variable",
|
||||
Detail: fmt.Sprintf("While evaluating %q, its dependency %q was not found, is it defined?",
|
||||
local.Name, dep.String()),
|
||||
})
|
||||
}
|
||||
|
||||
localDiags := c.recursivelyEvaluateLocalVariable(locBlock.(*LocalBlock), depth+1)
|
||||
diags = diags.Extend(localDiags)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ type LocalBlock struct {
|
|||
//
|
||||
// Only `local`/`locals` will be referenced here as we execute all the
|
||||
// same component types at once.
|
||||
dependencies []*LocalBlock
|
||||
dependencies []refString
|
||||
// evaluated toggles to true if it has been evaluated.
|
||||
//
|
||||
// We use this to determine if we're ready to get the value of the
|
||||
|
|
|
|||
Loading…
Reference in a new issue