mirror of
https://github.com/hashicorp/packer.git
synced 2026-09-20 15:01:40 -04:00
Before this commit, some HCP-related logic was embedded in the parser, making all of it common to all commands. This complexifies the logic as some parts rely on the template being in a HCP-valid environment, and the datasources need to be evaluated in order for some operations to be executed. To simplify this and avoid those pitfalls, we move this logic to its own set of functions that will be performed after the parsing is done, on any valid HCL2 or JSON template.
499 lines
15 KiB
Go
499 lines
15 KiB
Go
package command
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
"github.com/hashicorp/hcl/v2"
|
|
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
|
"github.com/hashicorp/packer/builder/file"
|
|
"github.com/hashicorp/packer/hcl2template"
|
|
"github.com/hashicorp/packer/internal/registry"
|
|
"github.com/hashicorp/packer/packer"
|
|
)
|
|
|
|
type registryTestArgs struct {
|
|
name string
|
|
inputFilePath string
|
|
expectedBuilds []packersdk.Build
|
|
expectError bool
|
|
envvars map[string]string
|
|
}
|
|
|
|
var registryCmpOpts = cmp.Options{
|
|
cmpopts.IgnoreFields(
|
|
registry.Iteration{},
|
|
"Fingerprint",
|
|
),
|
|
cmpopts.IgnoreFields(
|
|
packer.CoreBuild{},
|
|
"TemplatePath",
|
|
"Variables",
|
|
),
|
|
cmpopts.IgnoreUnexported(
|
|
hcl2template.PackerConfig{},
|
|
hcl2template.Variable{},
|
|
hcl2template.SourceBlock{},
|
|
hcl2template.DatasourceBlock{},
|
|
hcl2template.ProvisionerBlock{},
|
|
hcl2template.PostProcessorBlock{},
|
|
packer.CoreBuild{},
|
|
hcl2template.HCL2Provisioner{},
|
|
hcl2template.HCL2PostProcessor{},
|
|
packer.CoreBuildPostProcessor{},
|
|
packer.CoreBuildProvisioner{},
|
|
packer.CoreBuildPostProcessor{},
|
|
file.Builder{},
|
|
registry.Bucket{},
|
|
registry.Iteration{},
|
|
packer.RegistryBuilder{},
|
|
),
|
|
}
|
|
|
|
func TestRegistrySetup(t *testing.T) {
|
|
tests := []registryTestArgs{
|
|
{
|
|
"HCL2 - hcp_registry_block and multiple sources",
|
|
"test-fixtures/hcp/multiple_sources.pkr.hcl",
|
|
[]packersdk.Build{
|
|
&packer.CoreBuild{
|
|
BuildName: "bucket-slug",
|
|
Type: "file.test",
|
|
Prepared: true,
|
|
Builder: &packer.RegistryBuilder{
|
|
Name: "file.test",
|
|
Builder: &file.Builder{},
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some description\n",
|
|
BucketLabels: map[string]string{"foo": "bar"},
|
|
BuildLabels: map[string]string{"python_version": "3.0"},
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
Provisioners: []packer.CoreBuildProvisioner{},
|
|
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
|
{
|
|
{
|
|
PostProcessor: &packer.RegistryPostProcessor{
|
|
BuilderType: "file.test",
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some description\n",
|
|
BucketLabels: map[string]string{"foo": "bar"},
|
|
BuildLabels: map[string]string{"python_version": "3.0"},
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
&packer.CoreBuild{
|
|
BuildName: "bucket-slug",
|
|
Type: "file.other",
|
|
Prepared: true,
|
|
Builder: &packer.RegistryBuilder{
|
|
Name: "file.other",
|
|
Builder: &file.Builder{},
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some description\n",
|
|
BucketLabels: map[string]string{"foo": "bar"},
|
|
BuildLabels: map[string]string{"python_version": "3.0"},
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
Provisioners: []packer.CoreBuildProvisioner{},
|
|
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
|
{
|
|
{
|
|
PostProcessor: &packer.RegistryPostProcessor{
|
|
BuilderType: "file.other",
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some description\n",
|
|
BucketLabels: map[string]string{"foo": "bar"},
|
|
BuildLabels: map[string]string{"python_version": "3.0"},
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
map[string]string{},
|
|
},
|
|
{
|
|
"HCL2 - set slug in hcp packer registry block",
|
|
"test-fixtures/hcp/slug.pkr.hcl",
|
|
[]packersdk.Build{
|
|
&packer.CoreBuild{
|
|
BuildName: "bucket-slug",
|
|
Type: "file.test",
|
|
Prepared: true,
|
|
Builder: &packer.RegistryBuilder{
|
|
Name: "file.test",
|
|
Builder: &file.Builder{},
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "real-bucket-slug",
|
|
Description: "Some description\n",
|
|
BucketLabels: map[string]string{"foo": "bar"},
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
Provisioners: []packer.CoreBuildProvisioner{},
|
|
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
|
{
|
|
{
|
|
PostProcessor: &packer.RegistryPostProcessor{
|
|
BuilderType: "file.test",
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "real-bucket-slug",
|
|
Description: "Some description\n",
|
|
BucketLabels: map[string]string{"foo": "bar"},
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
map[string]string{},
|
|
},
|
|
{
|
|
"HCL2 - hcp - use build description",
|
|
"test-fixtures/hcp/build-description.pkr.hcl",
|
|
[]packersdk.Build{
|
|
&packer.CoreBuild{
|
|
Type: "file.test",
|
|
Prepared: true,
|
|
BuildName: "bucket-slug",
|
|
Builder: &packer.RegistryBuilder{
|
|
Name: "file.test",
|
|
Builder: &file.Builder{},
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some build description",
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
Provisioners: []packer.CoreBuildProvisioner{},
|
|
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
|
{
|
|
{
|
|
PostProcessor: &packer.RegistryPostProcessor{
|
|
BuilderType: "file.test",
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some build description",
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
map[string]string{},
|
|
},
|
|
{
|
|
"HCL2 - override build description with hcp packer registry description",
|
|
"test-fixtures/hcp/override-build-description.pkr.hcl",
|
|
[]packersdk.Build{
|
|
&packer.CoreBuild{
|
|
Type: "file.test",
|
|
Prepared: true,
|
|
Builder: &packer.RegistryBuilder{
|
|
Name: "file.test",
|
|
Builder: &file.Builder{},
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some override description",
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
Provisioners: []packer.CoreBuildProvisioner{},
|
|
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
|
{
|
|
{
|
|
PostProcessor: &packer.RegistryPostProcessor{
|
|
BuilderType: "file.test",
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some override description",
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
map[string]string{},
|
|
},
|
|
{
|
|
"HCL2 - deprecated labels in hcp packer registry block",
|
|
"test-fixtures/hcp/deprecated_labels.pkr.hcl",
|
|
[]packersdk.Build{
|
|
&packer.CoreBuild{
|
|
Type: "file.test",
|
|
Prepared: true,
|
|
Builder: &packer.RegistryBuilder{
|
|
Name: "file.test",
|
|
Builder: &file.Builder{},
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
BucketLabels: map[string]string{"foo": "bar"},
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
Provisioners: []packer.CoreBuildProvisioner{},
|
|
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
|
{
|
|
{
|
|
PostProcessor: &packer.RegistryPostProcessor{
|
|
BuilderType: "file.test",
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
BucketLabels: map[string]string{"foo": "bar"},
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
true,
|
|
map[string]string{},
|
|
},
|
|
{
|
|
"HCL2 - duplicate hcp_registry blocks",
|
|
"test-fixtures/hcp/duplicate.pkr.hcl",
|
|
nil,
|
|
true,
|
|
map[string]string{},
|
|
},
|
|
{
|
|
"HCL2 - two build blocks with hcp_registry",
|
|
"test-fixtures/hcp/dup_build_blocks.pkr.hcl",
|
|
nil,
|
|
true,
|
|
map[string]string{},
|
|
},
|
|
{
|
|
"HCL2/JSON - hcp enabled build",
|
|
"test-fixtures/hcp/hcp_normal.pkr.json",
|
|
[]packersdk.Build{
|
|
&packer.CoreBuild{
|
|
Type: "file.test",
|
|
Prepared: true,
|
|
BuildName: "test-file",
|
|
Builder: &packer.RegistryBuilder{
|
|
Name: "file.test",
|
|
Builder: &file.Builder{},
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some build description",
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
BucketLabels: map[string]string{},
|
|
BuildLabels: map[string]string{},
|
|
},
|
|
},
|
|
Provisioners: []packer.CoreBuildProvisioner{},
|
|
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
|
{
|
|
{
|
|
PostProcessor: &packer.RegistryPostProcessor{
|
|
BuilderType: "file.test",
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "Some build description",
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
BucketLabels: map[string]string{},
|
|
BuildLabels: map[string]string{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
map[string]string{
|
|
"HCP_PACKER_REGISTRY": "1",
|
|
"HCP_PACKER_BUCKET_NAME": "bucket-slug",
|
|
},
|
|
},
|
|
{
|
|
"Legacy JSON - hcp enabled build",
|
|
"test-fixtures/hcp/hcp_build.json",
|
|
[]packersdk.Build{
|
|
&packer.CoreBuild{
|
|
Type: "file",
|
|
Prepared: false,
|
|
BuildName: "",
|
|
BuilderType: "file",
|
|
BuilderConfig: map[string]interface{}{
|
|
"content": " ",
|
|
"target": "output",
|
|
},
|
|
Builder: &packer.RegistryBuilder{
|
|
Name: "file",
|
|
Builder: &file.Builder{},
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "",
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
BucketLabels: map[string]string{},
|
|
BuildLabels: map[string]string{},
|
|
},
|
|
},
|
|
Provisioners: []packer.CoreBuildProvisioner{},
|
|
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
|
{
|
|
{
|
|
PostProcessor: &packer.RegistryPostProcessor{
|
|
BuilderType: "file",
|
|
ArtifactMetadataPublisher: ®istry.Bucket{
|
|
Slug: "bucket-slug",
|
|
Description: "",
|
|
Iteration: ®istry.Iteration{},
|
|
SourceImagesToParentIterations: map[string]registry.ParentIteration{},
|
|
BucketLabels: map[string]string{},
|
|
BuildLabels: map[string]string{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
map[string]string{
|
|
"HCP_PACKER_REGISTRY": "1",
|
|
"HCP_PACKER_BUCKET_NAME": "bucket-slug",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
runRegistryTest(t, tt)
|
|
})
|
|
}
|
|
}
|
|
|
|
func runRegistryTest(t *testing.T, args registryTestArgs) {
|
|
for evar, val := range args.envvars {
|
|
os.Setenv(evar, val)
|
|
}
|
|
defer func() {
|
|
for evar := range args.envvars {
|
|
os.Setenv(evar, "")
|
|
}
|
|
}()
|
|
|
|
defaultMeta := TestMetaFile(t)
|
|
|
|
c := &BuildCommand{
|
|
Meta: defaultMeta,
|
|
}
|
|
|
|
cla := &BuildArgs{
|
|
MetaArgs: MetaArgs{
|
|
Path: args.inputFilePath,
|
|
},
|
|
}
|
|
|
|
packerStarter, ret := c.GetConfig(&cla.MetaArgs)
|
|
if ret != 0 {
|
|
t.Fatalf("failed to get packer config")
|
|
}
|
|
|
|
diags := packerStarter.Initialize(packer.InitializeOptions{})
|
|
if diagCheck(diags, t) {
|
|
return
|
|
}
|
|
|
|
diags = TrySetupHCP(packerStarter)
|
|
if diagCheck(diags, t) {
|
|
if !args.expectError {
|
|
t.Errorf("SetupRegistry unexpectedly failed")
|
|
}
|
|
return
|
|
}
|
|
|
|
builds, diags := packerStarter.GetBuilds(packer.GetBuildsOptions{
|
|
Only: cla.Only,
|
|
Except: cla.Except,
|
|
Debug: cla.Debug,
|
|
Force: cla.Force,
|
|
OnError: cla.OnError,
|
|
})
|
|
if diagCheck(diags, t) {
|
|
if !args.expectError {
|
|
t.Errorf("SetupRegistry unexpectedly failed")
|
|
}
|
|
return
|
|
}
|
|
|
|
diff := cmp.Diff(builds, args.expectedBuilds, registryCmpOpts...)
|
|
if diff != "" {
|
|
t.Error(diff)
|
|
}
|
|
}
|
|
|
|
func severityString(sev hcl.DiagnosticSeverity) string {
|
|
switch sev {
|
|
case hcl.DiagInvalid:
|
|
return "UNKNOWN"
|
|
case hcl.DiagError:
|
|
return "ERROR"
|
|
case hcl.DiagWarning:
|
|
return "WARNING"
|
|
}
|
|
panic("unknown severity")
|
|
}
|
|
|
|
// diagCheck errors for each diagnostic received and returns if a diag was processed
|
|
func diagCheck(diags hcl.Diagnostics, t *testing.T) bool {
|
|
if len(diags) == 0 {
|
|
return false
|
|
}
|
|
|
|
for _, d := range diags {
|
|
t.Logf(
|
|
"%s: %s - %s",
|
|
severityString(d.Severity),
|
|
d.Summary,
|
|
d.Detail,
|
|
)
|
|
}
|
|
return true
|
|
}
|