command/validate: add option to eval datasources

When packer validate is invoked, it does not try to evaluate the
datasources before attempting to decide if the template is valid.

In many cases, this works, but sometimes it will fail as the value is
unknown by the validation code.

Since the validation code for all the elements of a Packer template is
left to be implemented by plugins, we cannot rely on checking for
unknown values everywhere, especially since the unknown references are
replaced automatically by a value of the right type for the
configuration expected.

So, in order for such configurations to be validable, we add an extra
option to packer validate, that will let users evaluate the datasources
from a template.
pull/12123/head
Lucas Bajolet 3 years ago committed by Lucas Bajolet
parent 4af0619721
commit bb2384c56a

@ -136,6 +136,7 @@ type FixArgs struct {
func (va *ValidateArgs) AddFlagSets(flags *flag.FlagSet) {
flags.BoolVar(&va.SyntaxOnly, "syntax-only", false, "check syntax only")
flags.BoolVar(&va.NoWarnUndeclaredVar, "no-warn-undeclared-var", false, "Ignore warnings for variable files containing undeclared variables.")
flags.BoolVar(&va.EvaluateDatasources, "evaluate-datasources", false, "evaluate datasources for validation (HCL2 only, may incur costs)")
va.MetaArgs.AddFlagSets(flags)
}
@ -144,6 +145,7 @@ func (va *ValidateArgs) AddFlagSets(flags *flag.FlagSet) {
type ValidateArgs struct {
MetaArgs
SyntaxOnly, NoWarnUndeclaredVar bool
EvaluateDatasources bool
}
func (va *InspectArgs) AddFlagSets(flags *flag.FlagSet) {

@ -0,0 +1,17 @@
data "null" "dep" {
input = "upload"
}
source "null" "test" {
communicator = "none"
}
build {
sources = ["sources.null.test"]
provisioner "file" {
source = "test-fixtures/hcl/force.pkr.hcl"
destination = "dest"
direction = "${data.null.dep.output}"
}
}

@ -63,7 +63,7 @@ func (c *ValidateCommand) RunContext(ctx context.Context, cla *ValidateArgs) int
}
diags := packerStarter.Initialize(packer.InitializeOptions{
SkipDatasourcesExecution: true,
SkipDatasourcesExecution: !cla.EvaluateDatasources,
})
ret = writeDiags(c.Ui, nil, diags)
if ret != 0 {

@ -11,8 +11,9 @@ import (
func TestValidateCommand(t *testing.T) {
tt := []struct {
path string
exitCode int
path string
exitCode int
extraArgs []string
}{
{path: filepath.Join(testFixture("validate"), "build.json")},
{path: filepath.Join(testFixture("validate"), "build.pkr.hcl")},
@ -39,6 +40,11 @@ func TestValidateCommand(t *testing.T) {
// datasource could be unknown at that moment
{path: filepath.Join(testFixture("hcl", "data-source-validation.pkr.hcl")), exitCode: 0},
// datasource unknown at validation-time without datasource evaluation -> fail on provisioner
{path: filepath.Join(testFixture("hcl", "local-ds-validate.pkr.hcl")), exitCode: 1},
// datasource unknown at validation-time with datasource evaluation -> success
{path: filepath.Join(testFixture("hcl", "local-ds-validate.pkr.hcl")), exitCode: 0, extraArgs: []string{"--evaluate-datasources"}},
}
for _, tc := range tt {
@ -47,7 +53,8 @@ func TestValidateCommand(t *testing.T) {
Meta: TestMetaFile(t),
}
tc := tc
args := []string{tc.path}
args := tc.extraArgs
args = append(args, tc.path)
if code := c.Run(args); code != tc.exitCode {
fatalCommand(t, c.Meta)
}

@ -31,6 +31,14 @@ Errors validating build 'vmware'. 1 error(s) occurred:
- `-syntax-only` - Only the syntax of the template is checked. The
configuration is not validated.
- `-evaluate-datasources` - Evaluate all data sources when validating a template.
This is only valid on HCL2 templates, since JSON templates do not feature
datasources, this option will be ignored.
~> **Warning:** Data sources may rely on external services for fetching data,
which can incur some costs at validation if the services being contacted are
billing per operation.
- `-except=foo,bar,baz` - Validates all the builds except those with the
comma-separated names. In legacy JSON templates, build names default to the
types of their builders (e.g. `docker` or

Loading…
Cancel
Save