From dad07c6097f5095948674a0a7f70eb86e0a2d017 Mon Sep 17 00:00:00 2001 From: Lucas Bajolet Date: Tue, 30 Aug 2022 15:52:47 -0400 Subject: [PATCH] hcp: keep map of build names for hcp tracking To be able to track HCP builds during a Packer build, we need to propagate the name used for registering the build to HCP. This works out-of-the-box for JSON templates, as the build's name is always the builder's, so there's no confusion on that. For HCP templates however, there's a possibility for a template to define a name for the build, which is returned by a CoreBuild's Name() function, in addition to the source's Type/Name. The builds are registered to HCP with the source.String() function however, which does not contain the build's name. This prevents any build containing a name to work, as their name/source.String does not match. The name we registered the build with is stored in a CoreBuild as the Type attribute, but cannot be safely accessed, as builds are types within the command as packersdk.Build, which only exposes Name() for this purpose. In order to circumvent this problem, and as a way to present a prototype of solution that will likely have to be discussed before we merge it, this commit hotfixes the issue. --- command/build.go | 6 +++--- command/registry_test.go | 2 +- command/validate.go | 2 +- hcl2template/common_test.go | 2 +- hcl2template/types.packer_config.go | 13 +++++++++---- packer/core.go | 7 +++++-- packer/run_interfaces.go | 2 +- 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/command/build.go b/command/build.go index c0c43a86f..4a3278ad8 100644 --- a/command/build.go +++ b/command/build.go @@ -119,7 +119,7 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int } } - builds, diags := packerStarter.GetBuilds(packer.GetBuildsOptions{ + builds, hcpMap, diags := packerStarter.GetBuilds(packer.GetBuildsOptions{ Only: cla.Only, Except: cla.Except, Debug: cla.Debug, @@ -249,7 +249,7 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int defer limitParallel.Release(1) if ArtifactMetadataPublisher != nil { - err := ArtifactMetadataPublisher.BuildStart(buildCtx, name) + err := ArtifactMetadataPublisher.BuildStart(buildCtx, hcpMap[name]) if err != nil { msg := err.Error() if strings.Contains(msg, "already done") { @@ -275,7 +275,7 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int if ArtifactMetadataPublisher != nil { runArtifacts, err = ArtifactMetadataPublisher.BuildDone( buildCtx, - name, + hcpMap[name], runArtifacts, err, ) diff --git a/command/registry_test.go b/command/registry_test.go index a05ba1d7d..5997880b9 100644 --- a/command/registry_test.go +++ b/command/registry_test.go @@ -242,7 +242,7 @@ func runRegistryTest(t *testing.T, args registryTestArgs) { return } - builds, diags := packerStarter.GetBuilds(packer.GetBuildsOptions{ + builds, _, diags := packerStarter.GetBuilds(packer.GetBuildsOptions{ Only: cla.Only, Except: cla.Except, Debug: cla.Debug, diff --git a/command/validate.go b/command/validate.go index 8bef1ffc6..c8ac93710 100644 --- a/command/validate.go +++ b/command/validate.go @@ -64,7 +64,7 @@ func (c *ValidateCommand) RunContext(ctx context.Context, cla *ValidateArgs) int return ret } - _, diags = packerStarter.GetBuilds(packer.GetBuildsOptions{ + _, _, diags = packerStarter.GetBuilds(packer.GetBuildsOptions{ Only: cla.Only, Except: cla.Except, }) diff --git a/hcl2template/common_test.go b/hcl2template/common_test.go index 2dd0ef6ba..33b302524 100644 --- a/hcl2template/common_test.go +++ b/hcl2template/common_test.go @@ -107,7 +107,7 @@ func testParse(t *testing.T, tests []parseTest) { return } - gotBuilds, gotDiags := gotCfg.GetBuilds(packer.GetBuildsOptions{}) + gotBuilds, _, gotDiags := gotCfg.GetBuilds(packer.GetBuildsOptions{}) if tt.getBuildsWantDiags == (gotDiags == nil) { t.Fatalf("Parser.getBuilds() unexpected diagnostics. %s", gotDiags) } diff --git a/hcl2template/types.packer_config.go b/hcl2template/types.packer_config.go index ffa95089f..b135ac89a 100644 --- a/hcl2template/types.packer_config.go +++ b/hcl2template/types.packer_config.go @@ -563,11 +563,14 @@ func (cfg *PackerConfig) getCoreBuildPostProcessors(source SourceUseBlock, block // GetBuilds returns a list of packer Build based on the HCL2 parsed build // blocks. All Builders, Provisioners and Post Processors will be started and // configured. -func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packersdk.Build, hcl.Diagnostics) { +func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packersdk.Build, map[string]string, hcl.Diagnostics) { res := []packersdk.Build{} var diags hcl.Diagnostics possibleBuildNames := []string{} + // hcpTranslationMap maps the local name of a Corebuild to its HCP name + hcpTranslationMap := map[string]string{} + cfg.debug = opts.Debug cfg.force = opts.Force cfg.onError = opts.OnError @@ -598,6 +601,8 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packersdk.Bu Type: srcUsage.String(), } + hcpTranslationMap[pcb.Name()] = srcUsage.String() + pcb.SetDebug(cfg.debug) pcb.SetForce(cfg.force) pcb.SetOnError(cfg.onError) @@ -609,7 +614,7 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packersdk.Bu if len(opts.Only) > 0 { onlyGlobs, diags := convertFilterOption(opts.Only, "only") if diags.HasErrors() { - return nil, diags + return nil, nil, diags } cfg.only = onlyGlobs include := false @@ -629,7 +634,7 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packersdk.Bu if len(opts.Except) > 0 { exceptGlobs, diags := convertFilterOption(opts.Except, "except") if diags.HasErrors() { - return nil, diags + return nil, nil, diags } cfg.except = exceptGlobs exclude := false @@ -726,7 +731,7 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packersdk.Bu "These could also be matched with a glob pattern like: 'happycloud.*'", possibleBuildNames), }) } - return res, diags + return res, hcpTranslationMap, diags } var PackerConsoleHelp = strings.TrimSpace(` diff --git a/packer/core.go b/packer/core.go index a634bffde..47cfe45cf 100644 --- a/packer/core.go +++ b/packer/core.go @@ -246,9 +246,10 @@ func (c *Core) generateCoreBuildProvisioner(rawP *template.Provisioner, rawName // This is used for json templates to launch the build plugins. // They will be prepared via b.Prepare() later. -func (c *Core) GetBuilds(opts GetBuildsOptions) ([]packersdk.Build, hcl.Diagnostics) { +func (c *Core) GetBuilds(opts GetBuildsOptions) ([]packersdk.Build, map[string]string, hcl.Diagnostics) { buildNames := c.BuildNames(opts.Only, opts.Except) builds := []packersdk.Build{} + hcpTranslationMap := map[string]string{} diags := hcl.Diagnostics{} for _, n := range buildNames { b, err := c.Build(n) @@ -261,6 +262,8 @@ func (c *Core) GetBuilds(opts GetBuildsOptions) ([]packersdk.Build, hcl.Diagnost continue } + hcpTranslationMap[n] = HCPName(c.builds[n]) + // Now that build plugin has been launched, call Prepare() log.Printf("Preparing build: %s", b.Name()) b.SetDebug(opts.Debug) @@ -290,7 +293,7 @@ func (c *Core) GetBuilds(opts GetBuildsOptions) ([]packersdk.Build, hcl.Diagnost } } } - return builds, diags + return builds, hcpTranslationMap, diags } // HCPName is a helper to get a curated HCP name for a legacy JSON builder. diff --git a/packer/run_interfaces.go b/packer/run_interfaces.go index 60acc97ac..aa1d69dd0 100644 --- a/packer/run_interfaces.go +++ b/packer/run_interfaces.go @@ -22,7 +22,7 @@ type BuildGetter interface { // GetBuilds return all possible builds for a config. It also starts all // builders. // TODO(azr): rename to builder starter ? - GetBuilds(GetBuildsOptions) ([]packersdk.Build, hcl.Diagnostics) + GetBuilds(GetBuildsOptions) ([]packersdk.Build, map[string]string, hcl.Diagnostics) } type Evaluator interface {