From 98990fc34e933ad935e589fede79cd8d2ceccb51 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 3 Jun 2021 13:41:16 +0200 Subject: [PATCH] hcl2_upgrade: allow to hcl2_upgrade with unknown builders, just log errors (#11049) --- command/hcl2_upgrade.go | 41 ++++++++------- command/hcl2_upgrade_test.go | 14 ++++-- .../unknown_builder/expected.pkr.hcl | 50 +++++++++++++++++++ .../hcl2_upgrade/unknown_builder/input.json | 48 ++++++++++++++++++ 4 files changed, 131 insertions(+), 22 deletions(-) create mode 100644 command/test-fixtures/hcl2_upgrade/unknown_builder/expected.pkr.hcl create mode 100644 command/test-fixtures/hcl2_upgrade/unknown_builder/input.json diff --git a/command/hcl2_upgrade.go b/command/hcl2_upgrade.go index 5c7ee1bcc..5b91a4a24 100644 --- a/command/hcl2_upgrade.go +++ b/command/hcl2_upgrade.go @@ -153,7 +153,7 @@ func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs) hdl, ret := c.GetConfigFromJSON(&cla.MetaArgs) if ret != 0 { - return ret + c.Ui.Error(fmt.Sprintf("Failed to get config from JSON")) } core := hdl.(*CoreWrapper).Core @@ -168,16 +168,16 @@ func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs) WithAnnotations: cla.WithAnnotations, } if err := packerBlock.Parse(tpl); err != nil { - c.Ui.Error(err.Error()) - return 1 + c.Ui.Error(fmt.Sprintf("Ignoring following Parse error: %v", err)) + ret = 1 } variables := &VariableParser{ WithAnnotations: cla.WithAnnotations, } if err := variables.Parse(tpl); err != nil { - c.Ui.Error(err.Error()) - return 1 + c.Ui.Error(fmt.Sprintf("Ignoring following variables.Parse error: %v", err)) + ret = 1 } locals := &LocalsParser{ @@ -185,8 +185,8 @@ func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs) WithAnnotations: cla.WithAnnotations, } if err := locals.Parse(tpl); err != nil { - c.Ui.Error(err.Error()) - return 1 + c.Ui.Error(fmt.Sprintf("Ignoring following locals.Parse error: %v", err)) + ret = 1 } builders := []*template.Builder{} @@ -205,8 +205,8 @@ func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs) WithAnnotations: cla.WithAnnotations, } if err := amazonAmiDatasource.Parse(tpl); err != nil { - c.Ui.Error(err.Error()) - return 1 + c.Ui.Error(fmt.Sprintf("Ignoring following amazonAmiDatasource.Parse error: %v", err)) + ret = 1 } sources := &SourceParser{ @@ -215,8 +215,8 @@ func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs) WithAnnotations: cla.WithAnnotations, } if err := sources.Parse(tpl); err != nil { - c.Ui.Error(err.Error()) - return 1 + c.Ui.Error(fmt.Sprintf("Ignoring following sources.Parse error: %v", err)) + ret = 1 } build := &BuildParser{ @@ -224,16 +224,16 @@ func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs) WithAnnotations: cla.WithAnnotations, } if err := build.Parse(tpl); err != nil { - c.Ui.Error(err.Error()) - return 1 + c.Ui.Error(fmt.Sprintf("Ignoring following build.Parse error: %v", err)) + ret = 1 } amazonSecretsDatasource := &AmazonSecretsDatasourceParser{ WithAnnotations: cla.WithAnnotations, } if err := amazonSecretsDatasource.Parse(tpl); err != nil { - c.Ui.Error(err.Error()) - return 1 + c.Ui.Error(fmt.Sprintf("Ignoring following amazonSecretsDatasource.Parse error: %v", err)) + ret = 1 } // Write file @@ -255,8 +255,8 @@ func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs) return 1 } - c.Ui.Say(fmt.Sprintf("Successfully created %s ", cla.OutputFile)) - return 0 + c.Ui.Say(fmt.Sprintf("Successfully created %s. Exit %d", cla.OutputFile, ret)) + return ret } type UnhandleableArgumentError struct { @@ -971,6 +971,7 @@ type SourceParser struct { } func (p *SourceParser) Parse(tpl *template.Template) error { + var unknownBuilders []string if p.out == nil { p.out = []byte{} } @@ -980,7 +981,8 @@ func (p *SourceParser) Parse(tpl *template.Template) error { body.AppendNewline() if !p.BuilderPlugins.Has(builderCfg.Type) { - return fmt.Errorf("unknown builder type: %q\n", builderCfg.Type) + unknownBuilders = append(unknownBuilders, builderCfg.Type) + } if builderCfg.Name == "" || builderCfg.Name == builderCfg.Type { builderCfg.Name = fmt.Sprintf("autogenerated_%d", i+1) @@ -993,6 +995,9 @@ func (p *SourceParser) Parse(tpl *template.Template) error { p.out = append(p.out, transposeTemplatingCalls(sourcesContent.Bytes())...) } + if len(unknownBuilders) > 0 { + return fmt.Errorf("unknown builder type(s): %v\n", unknownBuilders) + } return nil } diff --git a/command/hcl2_upgrade_test.go b/command/hcl2_upgrade_test.go index 35fabe816..e3ca4a0a6 100644 --- a/command/hcl2_upgrade_test.go +++ b/command/hcl2_upgrade_test.go @@ -17,9 +17,11 @@ func Test_hcl2_upgrade(t *testing.T) { _ = cwd tc := []struct { - folder string - flags []string + folder string + flags []string + exitCode int }{ + {folder: "unknown_builder", flags: []string{}, exitCode: 1}, {folder: "complete", flags: []string{"-with-annotations"}}, {folder: "without-annotations", flags: []string{}}, {folder: "minimal", flags: []string{"-with-annotations"}}, @@ -43,9 +45,9 @@ func Test_hcl2_upgrade(t *testing.T) { } args = append(args, inputPath) p := helperCommand(t, args...) - bs, err := p.CombinedOutput() + err := p.Run() if err != nil { - t.Fatalf("%v %s", err, bs) + t.Logf("run returned an error: %s", err) } expected := string(mustBytes(ioutil.ReadFile(expectedPath))) actual := string(mustBytes(ioutil.ReadFile(outputPath))) @@ -53,6 +55,10 @@ func Test_hcl2_upgrade(t *testing.T) { if diff := cmp.Diff(expected, actual); diff != "" { t.Fatalf("unexpected output: %s", diff) } + actualExitCode := p.ProcessState.ExitCode() + if tc.exitCode != actualExitCode { + t.Fatalf("unexpected exit code: %d found; expected %d ", actualExitCode, tc.exitCode) + } os.Remove(outputPath) }) } diff --git a/command/test-fixtures/hcl2_upgrade/unknown_builder/expected.pkr.hcl b/command/test-fixtures/hcl2_upgrade/unknown_builder/expected.pkr.hcl new file mode 100644 index 000000000..62e07e64e --- /dev/null +++ b/command/test-fixtures/hcl2_upgrade/unknown_builder/expected.pkr.hcl @@ -0,0 +1,50 @@ +packer { + required_version = ">= 1.6.0" +} + +variable "aws_access_key" { + type = string + default = "" +} + +variable "aws_region" { + type = string +} + +variable "aws_secret_key" { + type = string + default = "" +} + +source "potatoes" "autogenerated_1" { + access_key = "${var.aws_access_key}" + ami_description = "Ubuntu 16.04 LTS - expand root partition" + ami_name = "ubuntu-16-04-test" + encrypt_boot = true + launch_block_device_mappings { + delete_on_termination = true + device_name = "/dev/sda1" + volume_size = 48 + volume_type = "gp2" + } + region = "${var.aws_region}" + secret_key = "${var.aws_secret_key}" + source_ami = "ami1234567" + spot_instance_types = ["t2.small", "t2.medium", "t2.large"] + spot_price = "0.0075" + ssh_interface = "session_manager" + ssh_username = "ubuntu" + temporary_iam_instance_profile_policy_document { + Statement { + Action = ["*"] + Effect = "Allow" + Resource = ["*"] + } + Version = "2012-10-17" + } +} + +build { + sources = ["source.potatoes.autogenerated_1"] + +} diff --git a/command/test-fixtures/hcl2_upgrade/unknown_builder/input.json b/command/test-fixtures/hcl2_upgrade/unknown_builder/input.json new file mode 100644 index 000000000..774dac4e6 --- /dev/null +++ b/command/test-fixtures/hcl2_upgrade/unknown_builder/input.json @@ -0,0 +1,48 @@ +{ + "min_packer_version": "1.6.0", + "variables": { + "aws_region": null, + "aws_secret_key": "", + "aws_access_key": "" + }, + "builders": [ + { + "type": "potatoes", + "region": "{{ user `aws_region` }}", + "secret_key": "{{ user `aws_secret_key` }}", + "access_key": "{{ user `aws_access_key` }}", + "ami_name": "ubuntu-16-04-test", + "ami_description": "Ubuntu 16.04 LTS - expand root partition", + "source_ami": "ami1234567", + "launch_block_device_mappings": [ + { + "delete_on_termination": true, + "device_name": "/dev/sda1", + "volume_type": "gp2", + "volume_size": 48 + } + ], + "spot_price": "0.0075", + "spot_instance_types": [ + "t2.small", + "t2.medium", + "t2.large" + ], + "encrypt_boot": true, + "ssh_username": "ubuntu", + "temporary_iam_instance_profile_policy_document": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "*" + ], + "Resource": ["*"] + } + ] + }, + "ssh_interface": "session_manager" + } + ] +} \ No newline at end of file