hcl2template: err on malformed local/data dep

When introducing the DAG for locals and datasources, we forgot to handle
one limit case: if a dependency for a local or data is malformed, we
didn't check that a vertex was associated to it, leading to the final
DAG being malformed, and the DAG library would crash in this case.

This commit fixes this problem by checking that the dependency does
exist before attempting to add it to the graph as an edge for a vertex,
so that it is reported accurately, and do that Packer doesn't crash.
fix_hcl2_dag_missing_dependency
Lucas Bajolet 1 year ago
parent d4ebc48b89
commit d722d3c634

@ -9,6 +9,7 @@ import (
"path/filepath"
"reflect"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-version"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/ext/dynblock"
@ -398,6 +399,8 @@ func (cfg *PackerConfig) buildPrereqsDAG() (*dag.AcyclicGraph, error) {
verticesMap := map[string]dag.Vertex{}
var err error
// Do a first pass to create all the vertices
for ref := range cfg.Datasources {
// We keep a reference to the datasource separately from where it
@ -429,27 +432,48 @@ func (cfg *PackerConfig) buildPrereqsDAG() (*dag.AcyclicGraph, error) {
for _, ds := range cfg.Datasources {
dsName := fmt.Sprintf("data.%s", ds.Name())
source := verticesMap[dsName]
if source == nil {
err = multierror.Append(err, fmt.Errorf("unable to find source vertex %q for dependency analysis, this is likely a Packer bug", dsName))
continue
}
for _, dep := range ds.Dependencies {
retGraph.Connect(
dag.BasicEdge(verticesMap[dsName],
verticesMap[dep.String()]))
target := verticesMap[dep.String()]
if target == nil {
err = multierror.Append(err, fmt.Errorf("unknown dependency %q for %q", dep.String(), dsName))
continue
}
retGraph.Connect(dag.BasicEdge(source, target))
}
}
for _, loc := range cfg.LocalBlocks {
locName := fmt.Sprintf("local.%s", loc.LocalName)
source := verticesMap[locName]
if source == nil {
err = multierror.Append(err, fmt.Errorf("unable to find source vertex %q for dependency analysis, this is likely a Packer bug", locName))
continue
}
for _, dep := range loc.dependencies {
retGraph.Connect(
dag.BasicEdge(verticesMap[locName],
verticesMap[dep.String()]))
target := verticesMap[dep.String()]
if target == nil {
err = multierror.Append(err, fmt.Errorf("unknown dependency %q for %q", dep.String(), locName))
continue
}
retGraph.Connect(dag.BasicEdge(source, target))
}
}
if err := retGraph.Validate(); err != nil {
return nil, err
if validateErr := retGraph.Validate(); validateErr != nil {
err = multierror.Append(err, validateErr)
}
return &retGraph, nil
return &retGraph, err
}
func (cfg *PackerConfig) evaluateBuildPrereqs(skipDatasources bool) hcl.Diagnostics {

@ -0,0 +1,49 @@
package main
import (
"fmt"
"github.com/hashicorp/packer/packer_test/common/check"
)
type malformedDepTestCase struct {
name string
command string
templatePath string
useSequential bool
}
func genMalformedDepTestCases() []malformedDepTestCase {
retVals := []malformedDepTestCase{}
for _, cmd := range []string{"build", "validate"} {
for _, template := range []string{"./templates/malformed_data_dep.pkr.hcl", "./templates/malformed_local_dep.pkr.hcl"} {
for _, seq := range []bool{true, false} {
retVals = append(retVals, malformedDepTestCase{
name: fmt.Sprintf("Malformed dep packer %s --use-sequential-evaluation=%t %s",
cmd, seq, template),
command: cmd,
templatePath: template,
useSequential: seq,
})
}
}
}
return retVals
}
func (ts *PackerDAGTestSuite) TestMalformedDependency() {
pluginDir := ts.MakePluginDir()
defer pluginDir.Cleanup()
for _, tc := range genMalformedDepTestCases() {
ts.Run(tc.name, func() {
ts.PackerCommand().UsePluginDir(pluginDir).
SetArgs(tc.command,
fmt.Sprintf("--use-sequential-evaluation=%t", tc.useSequential),
tc.templatePath).
Assert(check.MustFail())
})
}
}

@ -0,0 +1,8 @@
data "http" "trusted_ca_certificates" {
method = "GET"
url = "http://example.com/ca-bundle.crt"
}
locals {
test = data.trusted_ca_certificates.url
}

@ -0,0 +1,4 @@
data "http" "trusted_ca_certificates" {
method = "GET"
url = local.no_dep
}
Loading…
Cancel
Save