diff --git a/acctest/testing.go b/acctest/testing.go index dc0af792c29..bce9f9612fc 100644 --- a/acctest/testing.go +++ b/acctest/testing.go @@ -146,7 +146,7 @@ func Test(t TestT, c TestCase) { }, Template: tpl, }) - err = core.Initialize() + err = core.Initialize(packer.InitializeOptions{}) if err != nil { t.Fatal(fmt.Sprintf("Failed to init core: %s", err)) return diff --git a/command/build.go b/command/build.go index 6f1f53dc613..c59cc39323a 100644 --- a/command/build.go +++ b/command/build.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/hcl/v2" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" + "github.com/hashicorp/packer/hcp" "github.com/hashicorp/packer/packer" "golang.org/x/sync/semaphore" @@ -88,33 +89,16 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int return ret } - diags = TrySetupHCP(packerStarter) - ret = writeDiags(c.Ui, nil, diags) - if ret != 0 { - return ret - } - - // This build currently enforces a 1:1 mapping that one publisher can be assigned to a single packer config file. - // It also requires that each config type implements this ConfiguredArtifactMetadataPublisher to return a configured bucket. - // TODO find an option that is not managed by a globally shared Publisher. - ArtifactMetadataPublisher, diags := packerStarter.ConfiguredArtifactMetadataPublisher() - if diags.HasErrors() { - return writeDiags(c.Ui, nil, diags) + hcpHandler, err := hcp.GetHCPHandler(packerStarter) + if err != nil { + c.Ui.Error(fmt.Sprintf("HCP setup failed: %s", err)) + return -1 } - // We need to create a bucket and an empty iteration before we retrieve builds - // so that we can add the iteration ID to the build's eval context - if ArtifactMetadataPublisher != nil { - if err := ArtifactMetadataPublisher.Initialize(buildCtx); err != nil { - diags := hcl.Diagnostics{ - &hcl.Diagnostic{ - Summary: "HCP Packer Registry iteration initialization failed", - Detail: fmt.Sprintf("Failed to initialize iteration for %q\n %s", ArtifactMetadataPublisher.Slug, err), - Severity: hcl.DiagError, - }, - } - return writeDiags(c.Ui, nil, diags) - } + err = hcpHandler.PopulateIteration(buildCtx) + if err != nil { + c.Ui.Error(fmt.Sprintf("HCP populating iteration failed: %s", err)) + return -1 } builds, hcpMap, diags := packerStarter.GetBuilds(packer.GetBuildsOptions{ @@ -133,21 +117,6 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int c.Ui.Say("Debug mode enabled. Builds will not be parallelized.") } - // Now that builds have been retrieved, we can populate the iteration with - // the builds we expect to run. - if ArtifactMetadataPublisher != nil { - if err := ArtifactMetadataPublisher.PopulateIteration(buildCtx); err != nil { - diags := hcl.Diagnostics{ - &hcl.Diagnostic{ - Summary: "HCP Packer Registry build initialization failed", - Detail: fmt.Sprintf("Failed to initialize build for %q\n %s", ArtifactMetadataPublisher.Slug, err), - Severity: hcl.DiagError, - }, - } - return writeDiags(c.Ui, nil, diags) - } - } - // Compile all the UIs for the builds colors := [5]packer.UiColor{ packer.UiColorGreen, @@ -225,26 +194,20 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int // Get the start of the build buildStart := time.Now() + err := hcpHandler.BuildStart(buildCtx, hcpMap[name]) + if err != nil { + if strings.Contains(err.Error(), "already done") { + ui.Say(fmt.Sprintf( + "skipping HCP-enabled build %q: already done.", + name)) + return + } + } + defer wg.Done() defer limitParallel.Release(1) - if ArtifactMetadataPublisher != nil { - err := ArtifactMetadataPublisher.BuildStart(buildCtx, hcpMap[name]) - if err != nil { - msg := err.Error() - if strings.Contains(msg, "already done") { - ui.Say(fmt.Sprintf( - "Build %q already done for bucket %q, skipping to prevent drift: %q", - name, - ArtifactMetadataPublisher.Slug, - err)) - return - } - - } - } - log.Printf("Starting build run: %s", name) runArtifacts, err := b.Run(buildCtx, ui) @@ -253,17 +216,16 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int buildDuration := buildEnd.Sub(buildStart) fmtBuildDuration := durafmt.Parse(buildDuration).LimitFirstN(2) - if ArtifactMetadataPublisher != nil { - runArtifacts, err = ArtifactMetadataPublisher.BuildDone( - buildCtx, - hcpMap[name], - runArtifacts, - err, - ) - if err != nil { - ui.Error(fmt.Sprintf("failed to complete HCP build %q: %s", - name, err)) - } + runArtifacts, hcperr := hcpHandler.BuildDone( + buildCtx, + hcpMap[name], + runArtifacts, + err) + if hcperr != nil { + ui.Error(fmt.Sprintf( + "failed to complete HCP-enabled build %q: %s.", + name, + hcperr)) } if err != nil { diff --git a/command/core_wrapper.go b/command/core_wrapper.go deleted file mode 100644 index f782903facd..00000000000 --- a/command/core_wrapper.go +++ /dev/null @@ -1,68 +0,0 @@ -package command - -import ( - "github.com/hashicorp/hcl/v2" - packerregistry "github.com/hashicorp/packer/internal/registry" - "github.com/hashicorp/packer/packer" - plugingetter "github.com/hashicorp/packer/packer/plugin-getter" -) - -// CoreWrapper wraps a packer.Core in order to have it's Initialize func return -// a diagnostic. -type CoreWrapper struct { - *packer.Core -} - -func (c *CoreWrapper) Initialize(_ packer.InitializeOptions) hcl.Diagnostics { - err := c.Core.Initialize() - if err != nil { - return hcl.Diagnostics{ - &hcl.Diagnostic{ - Detail: err.Error(), - Severity: hcl.DiagError, - }, - } - } - return nil -} - -func (c *CoreWrapper) PluginRequirements() (plugingetter.Requirements, hcl.Diagnostics) { - return nil, hcl.Diagnostics{ - &hcl.Diagnostic{ - Summary: "Packer plugins currently only works with HCL2 configuration templates", - Detail: "Please manually install plugins with the plugins command or use a HCL2 configuration that will do that for you.", - Severity: hcl.DiagError, - }, - } -} - -// ConfiguredArtifactMetadataPublisher returns a configured image bucket that can be used for publishing -// build image artifacts to a configured Packer Registry destination. -func (c *CoreWrapper) ConfiguredArtifactMetadataPublisher() (*packerregistry.Bucket, hcl.Diagnostics) { - bucket := c.Core.GetRegistryBucket() - - // If at this point the bucket is nil, it means the HCP Packer registry is not enabled - if bucket == nil { - return nil, hcl.Diagnostics{ - &hcl.Diagnostic{ - Summary: "Publishing build artifacts to HCP Packer Registry not enabled", - Detail: "No Packer Registry configuration detected; skipping all publishing steps " + - "See publishing to a Packer registry for Packer configuration details", - Severity: hcl.DiagWarning, - }, - } - } - - err := bucket.Validate() - if err != nil { - return nil, hcl.Diagnostics{ - &hcl.Diagnostic{ - Summary: "Invalid HCP Packer Registry configuration", - Detail: err.Error(), - Severity: hcl.DiagError, - }, - } - } - - return bucket, nil -} diff --git a/command/hcl2_upgrade.go b/command/hcl2_upgrade.go index 5e0a8b1a3b9..a0435fe76b2 100644 --- a/command/hcl2_upgrade.go +++ b/command/hcl2_upgrade.go @@ -158,8 +158,8 @@ func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs) return 1 } - core := hdl.(*CoreWrapper).Core - if err := core.Initialize(); err != nil { + core := hdl.(*packer.Core) + if err := core.Initialize(packer.InitializeOptions{}); err != nil { c.Ui.Error(fmt.Sprintf("Ignoring following initialization error: %v", err)) } tpl := core.Template diff --git a/command/meta.go b/command/meta.go index bf5a6d662d4..d6ad45ae96b 100644 --- a/command/meta.go +++ b/command/meta.go @@ -169,5 +169,5 @@ func (m *Meta) GetConfigFromJSON(cla *MetaArgs) (packer.Handler, int) { m.Ui.Error(err.Error()) ret = 1 } - return &CoreWrapper{core}, ret + return core, ret } diff --git a/command/registry_test.go b/command/registry_test.go deleted file mode 100644 index 8a501caf9b4..00000000000 --- a/command/registry_test.go +++ /dev/null @@ -1,295 +0,0 @@ -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{}, - ), -} - -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: &file.Builder{}, - Provisioners: []packer.CoreBuildProvisioner{}, - PostProcessors: [][]packer.CoreBuildPostProcessor{}, - }, - &packer.CoreBuild{ - BuildName: "bucket-slug", - Type: "file.other", - Prepared: true, - Builder: &file.Builder{}, - Provisioners: []packer.CoreBuildProvisioner{}, - PostProcessors: [][]packer.CoreBuildPostProcessor{}, - }, - }, - 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: &file.Builder{}, - Provisioners: []packer.CoreBuildProvisioner{}, - PostProcessors: [][]packer.CoreBuildPostProcessor{}, - }, - }, - 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: &file.Builder{}, - Provisioners: []packer.CoreBuildProvisioner{}, - PostProcessors: [][]packer.CoreBuildPostProcessor{}, - }, - }, - 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: &file.Builder{}, - Provisioners: []packer.CoreBuildProvisioner{}, - PostProcessors: [][]packer.CoreBuildPostProcessor{}, - }, - }, - 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: &file.Builder{}, - Provisioners: []packer.CoreBuildProvisioner{}, - PostProcessors: [][]packer.CoreBuildPostProcessor{}, - }, - }, - 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: &file.Builder{}, - Provisioners: []packer.CoreBuildProvisioner{}, - PostProcessors: [][]packer.CoreBuildPostProcessor{}, - }, - }, - 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: &file.Builder{}, - Provisioners: []packer.CoreBuildProvisioner{}, - PostProcessors: [][]packer.CoreBuildPostProcessor{}, - }, - }, - 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 -} diff --git a/hcl2template/common_test.go b/hcl2template/common_test.go index 71cad837a19..a269fc167de 100644 --- a/hcl2template/common_test.go +++ b/hcl2template/common_test.go @@ -360,7 +360,8 @@ var cmpOpts = []cmp.Option{ packerregistry.Iteration{}, ), cmpopts.IgnoreFields(PackerConfig{}, - "Cwd", // Cwd will change for every os type + "Cwd", // Cwd will change for every os type + "HCPVars", // HCPVars will not be filled-in during parsing ), cmpopts.IgnoreFields(packerregistry.Iteration{}, "Fingerprint", // Fingerprint will change everytime diff --git a/hcl2template/parser.go b/hcl2template/parser.go index 76831731eba..95b18ad1b61 100644 --- a/hcl2template/parser.go +++ b/hcl2template/parser.go @@ -137,6 +137,7 @@ func (p *Parser) Parse(filename string, varFiles []string, argVars map[string]st Basedir: basedir, Cwd: wd, CorePackerVersionString: p.CorePackerVersionString, + HCPVars: map[string]cty.Value{}, parser: p, files: files, } diff --git a/hcl2template/registry.go b/hcl2template/registry.go deleted file mode 100644 index 464ac50f363..00000000000 --- a/hcl2template/registry.go +++ /dev/null @@ -1,36 +0,0 @@ -package hcl2template - -import ( - "github.com/hashicorp/hcl/v2" - packerregistry "github.com/hashicorp/packer/internal/registry" -) - -// ConfiguredArtifactMetadataPublisher returns a configured image bucket that can be used for publishing -// build image artifacts to a configured Packer Registry destination. -func (cfg *PackerConfig) ConfiguredArtifactMetadataPublisher() (*packerregistry.Bucket, hcl.Diagnostics) { - // If this was a PAR (HCP Packer registry) build either the env. variables are set, or if there is a hcp_packer_registry block - // defined we would have a non-nil bucket. So if nil assume we are not in a some sort of PAR mode. - if cfg.Bucket == nil { - return nil, hcl.Diagnostics{ - &hcl.Diagnostic{ - Summary: "Publishing build artifacts to HCP Packer Registry not enabled", - Detail: "No Packer Registry configuration detected; skipping all publishing steps " + - "See publishing to a Packer registry for Packer configuration details", - Severity: hcl.DiagWarning, - }, - } - } - - err := cfg.Bucket.Validate() - if err != nil { - return nil, hcl.Diagnostics{ - &hcl.Diagnostic{ - Summary: "Invalid HCP Packer Registry configuration", - Detail: err.Error(), - Severity: hcl.DiagError, - }, - } - } - - return cfg.Bucket, nil -} diff --git a/hcl2template/types.packer_config.go b/hcl2template/types.packer_config.go index 936fca6a6fe..e7627acd5a7 100644 --- a/hcl2template/types.packer_config.go +++ b/hcl2template/types.packer_config.go @@ -7,12 +7,11 @@ import ( "strings" "github.com/gobwas/glob" - "github.com/hashicorp/hcl/v2" + hcl "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hcldec" "github.com/hashicorp/hcl/v2/hclsyntax" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" pkrfunction "github.com/hashicorp/packer/hcl2template/function" - packerregistry "github.com/hashicorp/packer/internal/registry" "github.com/hashicorp/packer/packer" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/function" @@ -54,8 +53,8 @@ type PackerConfig struct { // Builds is the list of Build blocks defined in the config files. Builds Builds - // Represents registry bucket defined in the config files. - Bucket *packerregistry.Bucket + // HCPVars is the list of HCP-set variables for use later in a template + HCPVars map[string]cty.Value parser *Parser files []*hcl.File @@ -119,11 +118,13 @@ func (cfg *PackerConfig) EvalContext(ctx BlockContext, variables map[string]cty. }, } - // Store the iteration_id, if it exists. Otherwise, it'll be "unknown" - if cfg.Bucket != nil { + iterID, ok := cfg.HCPVars["iterationID"] + if ok { + log.Printf("iterationID set: %q", iterID) + ectx.Variables[packerAccessor] = cty.ObjectVal(map[string]cty.Value{ "version": cty.StringVal(cfg.CorePackerVersionString), - "iterationID": cty.StringVal(cfg.Bucket.Iteration.ID), + "iterationID": iterID, }) } diff --git a/hcp/common.go b/hcp/common.go new file mode 100644 index 00000000000..02b9bb121f8 --- /dev/null +++ b/hcp/common.go @@ -0,0 +1,145 @@ +package hcp + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/hcp-sdk-go/clients/cloud-packer-service/stable/2021-04-30/models" + sdkpacker "github.com/hashicorp/packer-plugin-sdk/packer" + "github.com/hashicorp/packer/internal/registry" + "github.com/mitchellh/mapstructure" + + registryimage "github.com/hashicorp/packer-plugin-sdk/packer/registry/image" +) + +func populateIteration( + ctx context.Context, + handler HCPHandler, +) error { + err := handler.Bucket().Initialize(ctx) + if err != nil { + return fmt.Errorf("HCP Packer Registry build initialization failed: %s", err) + } + + err = handler.Bucket().PopulateIteration(ctx) + if err != nil { + return fmt.Errorf("HCP Packer Registry build initialization failed: %s", err) + } + + return nil +} + +func buildStart( + ctx context.Context, + handler HCPHandler, + buildName string, +) error { + b := handler.Bucket() + + if !b.IsExpectingBuildForComponent(buildName) { + return fmt.Errorf("already done") + } + + err := b.UpdateBuildStatus(ctx, buildName, models.HashicorpCloudPackerBuildStatusRUNNING) + if err != nil { + return fmt.Errorf("failed to update HCP Packer registry status for %q: %s", buildName, err) + } + + cleanupHeartbeat, err := b.HeartbeatBuild(ctx, buildName) + if err != nil { + log.Printf("[ERROR] failed to start heartbeat function") + } + + buildDone := make(chan struct{}, 1) + go func() { + log.Printf("[TRACE] waiting for heartbeat completion") + select { + case <-ctx.Done(): + cleanupHeartbeat() + err := b.UpdateBuildStatus( + context.Background(), + buildName, + models.HashicorpCloudPackerBuildStatusCANCELLED) + if err != nil { + log.Printf( + "[ERROR] failed to update HCP Packer registry status for %q: %s", + buildName, + err) + } + case <-buildDone: + cleanupHeartbeat() + } + log.Printf("[TRACE] done waiting for heartbeat completion") + }() + + b.RunningBuilds[buildName] = buildDone + + return nil +} + +func buildDone( + ctx context.Context, + handler HCPHandler, + buildName string, + artifacts []sdkpacker.Artifact, + buildErr error, +) ([]sdkpacker.Artifact, error) { + b := handler.Bucket() + + doneCh, ok := b.RunningBuilds[buildName] + if !ok { + log.Print("[ERROR] done build does not have an entry in the heartbeat table, state will be inconsistent.") + } else { + log.Printf("[TRACE] signal stopping heartbeats") + // Stop heartbeating + doneCh <- struct{}{} + log.Printf("[TRACE] stopped heartbeats") + } + + if buildErr != nil { + err := b.UpdateBuildStatus(ctx, buildName, models.HashicorpCloudPackerBuildStatusFAILED) + if err != nil { + log.Printf("[ERROR] failed to update build %q status to FAILED: %s", buildName, err) + } + return artifacts, fmt.Errorf("build failed, not uploading artifacts") + } + + for _, art := range artifacts { + var images []registryimage.Image + decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ + Result: &images, + WeaklyTypedInput: true, + ErrorUnused: false, + }) + if err != nil { + return artifacts, fmt.Errorf("failed to create decoder for HCP Packer registry image: %w", err) + } + + state := art.State(registryimage.ArtifactStateURI) + err = decoder.Decode(state) + if err != nil { + return artifacts, fmt.Errorf("failed to obtain HCP Packer registry image from post-processor artifact: %w", err) + } + log.Printf("[TRACE] updating artifacts for build %q", buildName) + err = b.UpdateImageForBuild(buildName, images...) + + if err != nil { + return artifacts, fmt.Errorf("failed to add image artifact for %q: %s", buildName, err) + } + } + + parErr := b.CompleteBuild(ctx, buildName) + if parErr != nil { + return artifacts, fmt.Errorf( + "failed to update Packer registry with image artifacts for %q: %s", + buildName, + parErr) + } + + return append(artifacts, ®istry.RegistryArtifact{ + BuildName: buildName, + BucketSlug: b.Slug, + IterationID: b.Iteration.ID, + }), nil +} diff --git a/hcp/handler.go b/hcp/handler.go new file mode 100644 index 00000000000..9c464c31a04 --- /dev/null +++ b/hcp/handler.go @@ -0,0 +1,33 @@ +package hcp + +import ( + "context" + + sdkpacker "github.com/hashicorp/packer-plugin-sdk/packer" + "github.com/hashicorp/packer/hcl2template" + "github.com/hashicorp/packer/internal/registry" + "github.com/hashicorp/packer/packer" +) + +type HCPHandler interface { + Bucket() *registry.Bucket + PopulateIteration(context.Context) error + BuildStart(context.Context, string) error + BuildDone(ctx context.Context, buildName string, artifacts []sdkpacker.Artifact, buildErr error) ([]sdkpacker.Artifact, error) +} + +// TrySetupHCP attempts to setup the HCP-related structures if HCP is enabled +// for the command +func GetHCPHandler(cfg packer.Handler) (HCPHandler, error) { + var handler HCPHandler + var err error + + switch cfg := cfg.(type) { + case *hcl2template.PackerConfig: + handler, err = newHCLHandler(cfg) + case *packer.Core: + handler, err = newLegacyHCPHandler(cfg) + } + + return handler, err +} diff --git a/command/registry.go b/hcp/hcl_handler.go similarity index 53% rename from command/registry.go rename to hcp/hcl_handler.go index b197303fd3d..989870de101 100644 --- a/command/registry.go +++ b/hcp/hcl_handler.go @@ -1,17 +1,16 @@ -package command +package hcp import ( + "context" "fmt" - "path/filepath" + "log" - "github.com/hashicorp/hcl/v2" + sdkpacker "github.com/hashicorp/packer-plugin-sdk/packer" imgds "github.com/hashicorp/packer/datasource/hcp-packer-image" iterds "github.com/hashicorp/packer/datasource/hcp-packer-iteration" "github.com/hashicorp/packer/hcl2template" "github.com/hashicorp/packer/internal/registry" "github.com/hashicorp/packer/internal/registry/env" - "github.com/hashicorp/packer/packer" - "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/gocty" ) @@ -23,48 +22,57 @@ const ( buildLabel string = "build" ) -// TrySetupHCP attempts to setup the HCP-related structures if HCP is enabled -// for the command -func TrySetupHCP(cfg packer.Handler) hcl.Diagnostics { - switch cfg := cfg.(type) { - case *hcl2template.PackerConfig: - return setupRegistryForPackerConfig(cfg) - case *CoreWrapper: - return setupRegistryForPackerCore(cfg) - } +type HCLHandler struct { + Configuration *hcl2template.PackerConfig + bucket *registry.Bucket +} + +func (h *HCLHandler) Bucket() *registry.Bucket { + return h.bucket +} - return hcl.Diagnostics{ - &hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "unknown Handler type", - Detail: "SetupRegistry called with an unknown Handler. " + - "This is a Packer bug and should be brought to the attention " + - "of the Packer team, please consider opening an issue for this.", - }, +func (h *HCLHandler) PopulateIteration(ctx context.Context) error { + err := populateIteration(ctx, h) + if err != nil { + return err } + + iterationID := h.bucket.Iteration.ID + + log.Printf("PopulateIteration: setting iteration ID to %q", iterationID) + + h.Configuration.HCPVars["iterationID"] = cty.StringVal(iterationID) + + return nil +} + +func (h *HCLHandler) BuildStart(ctx context.Context, buildName string) error { + return buildStart(ctx, h, buildName) } -func setupRegistryForPackerConfig(pc *hcl2template.PackerConfig) hcl.Diagnostics { - var diags hcl.Diagnostics +func (h *HCLHandler) BuildDone( + ctx context.Context, + buildName string, + artifacts []sdkpacker.Artifact, + buildErr error, +) ([]sdkpacker.Artifact, error) { + return buildDone(ctx, h, buildName, artifacts, buildErr) +} +func newHCLHandler(config *hcl2template.PackerConfig) (HCPHandler, error) { hasHCP := false - for _, build := range pc.Builds { + for _, build := range config.Builds { if build.HCPPackerRegistry != nil { hasHCP = true } } - if hasHCP && len(pc.Builds) > 1 { - diags = append(diags, &hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Multiple " + buildLabel + " blocks", - Detail: fmt.Sprintf("For Packer Registry enabled builds, only one " + buildLabel + - " block can be defined. Please remove any additional " + buildLabel + - " block(s). If this " + buildLabel + " is not meant for the Packer registry please " + - "clear any HCP_PACKER_* environment variables."), - }) - return diags + if hasHCP && len(config.Builds) > 1 { + return nil, fmt.Errorf("For Packer Registry enabled builds, only one " + buildLabel + + " block can be defined. Please remove any additional " + buildLabel + + " block(s). If this " + buildLabel + " is not meant for the Packer registry please " + + "clear any HCP_PACKER_* environment variables or `hcp_packer_registry` block.") } if env.IsPAREnabled() { @@ -72,48 +80,48 @@ func setupRegistryForPackerConfig(pc *hcl2template.PackerConfig) hcl.Diagnostics } if !hasHCP { - return diags + return newNoopHandler(), nil } - var err error - pc.Bucket, err = registry.NewBucketWithIteration(registry.IterationOptions{ - TemplateBaseDir: pc.Basedir, + bucket, err := registry.NewBucketWithIteration(registry.IterationOptions{ + TemplateBaseDir: config.Basedir, }) if err != nil { - diags = append(diags, &hcl.Diagnostic{ - Summary: "Unable to create a valid bucket object for HCP Packer Registry", - Detail: fmt.Sprintf("%s", err), - Severity: hcl.DiagError, - }) - - return diags + return nil, fmt.Errorf( + "Unable to create a valid bucket object for HCP Packer Registry: %s", + err) } - pc.Bucket.LoadDefaultSettingsFromEnv() + bucket.LoadDefaultSettingsFromEnv() - for _, build := range pc.Builds { - build.HCPPackerRegistry.WriteToBucketConfig(pc.Bucket) + for _, build := range config.Builds { + build.HCPPackerRegistry.WriteToBucketConfig(bucket) // If at this point the bucket.Slug is still empty, // last try is to use the build.Name if present - if pc.Bucket.Slug == "" && build.Name != "" { - pc.Bucket.Slug = build.Name + if bucket.Slug == "" && build.Name != "" { + bucket.Slug = build.Name } // If the description is empty, use the one from the build block - if pc.Bucket.Description == "" { - pc.Bucket.Description = build.Description + if bucket.Description == "" { + bucket.Description = build.Description } for _, source := range build.Sources { - pc.Bucket.RegisterBuildForComponent(source.String()) + bucket.RegisterBuildForComponent(source.String()) } } - vals, diags := pc.Datasources.Values() + handler := &HCLHandler{ + Configuration: config, + bucket: bucket, + } + + vals, diags := config.Datasources.Values() if diags != nil { - return diags + return nil, diags } imageDS, imageOK := vals[hcpImageDatasourceType] @@ -121,7 +129,7 @@ func setupRegistryForPackerConfig(pc *hcl2template.PackerConfig) hcl.Diagnostics // If we don't have any image or iteration defined, we can return directly if !imageOK && !iterOK { - return nil + return handler, nil } iterations := map[string]iterds.DatasourceOutput{} @@ -130,12 +138,7 @@ func setupRegistryForPackerConfig(pc *hcl2template.PackerConfig) hcl.Diagnostics hcpData := map[string]cty.Value{} err = gocty.FromCtyValue(iterDS, &hcpData) if err != nil { - diags = append(diags, &hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Invalid HCP datasources", - Detail: fmt.Sprintf("Failed to decode hcp_packer_iteration datasources: %s", err), - }) - return diags + return nil, fmt.Errorf("Failed to decode hcp_packer_iteration datasources: %s", err) } for k, v := range hcpData { @@ -151,12 +154,7 @@ func setupRegistryForPackerConfig(pc *hcl2template.PackerConfig) hcl.Diagnostics hcpData := map[string]cty.Value{} err = gocty.FromCtyValue(imageDS, &hcpData) if err != nil { - diags = append(diags, &hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Invalid HCP datasources", - Detail: fmt.Sprintf("Failed to decode hcp_packer_image datasources: %s", err), - }) - return diags + return nil, fmt.Errorf("Failed to decode hcp_packer_image datasources: %s", err) } for k, v := range hcpData { @@ -182,10 +180,10 @@ func setupRegistryForPackerConfig(pc *hcl2template.PackerConfig) hcl.Diagnostics } } - pc.Bucket.SourceImagesToParentIterations[img.ID] = sourceIteration + bucket.SourceImagesToParentIterations[img.ID] = sourceIteration } - return diags + return handler, nil } func imageValueToDSOutput(imageVal map[string]cty.Value) imgds.DatasourceOutput { @@ -252,34 +250,3 @@ func iterValueToDSOutput(iterVal map[string]cty.Value) iterds.DatasourceOutput { } return dso } - -func setupRegistryForPackerCore(cfg *CoreWrapper) hcl.Diagnostics { - if !env.IsPAREnabled() { - return nil - } - - var diags hcl.Diagnostics - - var err error - - core := cfg.Core - - core.Bucket, err = registry.NewBucketWithIteration(registry.IterationOptions{ - TemplateBaseDir: filepath.Dir(core.Template.Path), - }) - if err != nil { - return append(diags, &hcl.Diagnostic{ - Summary: "bucket creation failure", - Detail: fmt.Sprintf("failed to create Bucket: %s", err), - Severity: hcl.DiagError, - }) - } - core.Bucket.LoadDefaultSettingsFromEnv() - - for _, b := range core.Template.Builders { - // Get all builds slated within config ignoring any only or exclude flags. - core.Bucket.RegisterBuildForComponent(b.Name) - } - - return nil -} diff --git a/hcp/legacy_handler.go b/hcp/legacy_handler.go new file mode 100644 index 00000000000..0b1bcce0102 --- /dev/null +++ b/hcp/legacy_handler.go @@ -0,0 +1,67 @@ +package hcp + +import ( + "context" + "fmt" + "path/filepath" + + sdkpacker "github.com/hashicorp/packer-plugin-sdk/packer" + "github.com/hashicorp/packer/internal/registry" + "github.com/hashicorp/packer/internal/registry/env" + "github.com/hashicorp/packer/packer" +) + +type LegacyHCPHandler struct { + Configuration *packer.Core + bucket *registry.Bucket +} + +func newLegacyHCPHandler(config *packer.Core) (HCPHandler, error) { + if !env.IsPAREnabled() { + return newNoopHandler(), nil + } + + bucket, err := registry.NewBucketWithIteration(registry.IterationOptions{ + TemplateBaseDir: filepath.Dir(config.Template.Path), + }) + if err != nil { + return nil, fmt.Errorf("failed to create Bucket: %s", err) + } + bucket.LoadDefaultSettingsFromEnv() + + for _, b := range config.Template.Builders { + // Get all builds slated within config ignoring any only or exclude flags. + bucket.RegisterBuildForComponent(b.Name) + } + + err = bucket.Validate() + if err != nil { + return nil, err + } + + return &LegacyHCPHandler{ + Configuration: config, + bucket: bucket, + }, nil +} + +func (h *LegacyHCPHandler) Bucket() *registry.Bucket { + return h.bucket +} + +func (h *LegacyHCPHandler) PopulateIteration(ctx context.Context) error { + return populateIteration(ctx, h) +} + +func (h *LegacyHCPHandler) BuildStart(ctx context.Context, buildName string) error { + return buildStart(ctx, h, buildName) +} + +func (h *LegacyHCPHandler) BuildDone( + ctx context.Context, + buildName string, + artifacts []sdkpacker.Artifact, + buildErr error, +) ([]sdkpacker.Artifact, error) { + return buildDone(ctx, h, buildName, artifacts, buildErr) +} diff --git a/hcp/noop.go b/hcp/noop.go new file mode 100644 index 00000000000..d52dc0618cf --- /dev/null +++ b/hcp/noop.go @@ -0,0 +1,35 @@ +package hcp + +import ( + "context" + + sdkpacker "github.com/hashicorp/packer-plugin-sdk/packer" + "github.com/hashicorp/packer/internal/registry" +) + +type NOOPHandler struct{} + +func newNoopHandler() HCPHandler { + return NOOPHandler{} +} + +func (h NOOPHandler) Bucket() *registry.Bucket { + return nil +} + +func (h NOOPHandler) PopulateIteration(context.Context) error { + return nil +} + +func (h NOOPHandler) BuildStart(context.Context, string) error { + return nil +} + +func (h NOOPHandler) BuildDone( + ctx context.Context, + buildName string, + artifacts []sdkpacker.Artifact, + buildErr error, +) ([]sdkpacker.Artifact, error) { + return artifacts, nil +} diff --git a/internal/registry/types.bucket.go b/internal/registry/types.bucket.go index 17dda1283d3..66d9eaf4a48 100644 --- a/internal/registry/types.bucket.go +++ b/internal/registry/types.bucket.go @@ -11,10 +11,8 @@ import ( "github.com/hashicorp/go-multierror" "github.com/hashicorp/hcp-sdk-go/clients/cloud-packer-service/stable/2021-04-30/models" - "github.com/hashicorp/packer-plugin-sdk/packer" registryimage "github.com/hashicorp/packer-plugin-sdk/packer/registry/image" "github.com/hashicorp/packer/internal/registry/env" - "github.com/mitchellh/mapstructure" "google.golang.org/grpc/codes" ) @@ -477,108 +475,3 @@ func (b *Bucket) HeartbeatBuild(ctx context.Context, build string) (func(), erro close(heartbeatChan) }, nil } - -func (b *Bucket) BuildStart(ctx context.Context, buildName string) error { - if !b.IsExpectingBuildForComponent(buildName) { - return fmt.Errorf("already done") - } - - err := b.UpdateBuildStatus(ctx, buildName, models.HashicorpCloudPackerBuildStatusRUNNING) - if err != nil { - return fmt.Errorf("failed to update HCP Packer registry status for %q: %s", buildName, err) - } - - cleanupHeartbeat, err := b.HeartbeatBuild(ctx, buildName) - if err != nil { - log.Printf("[ERROR] failed to start heartbeat function") - } - - buildDone := make(chan struct{}, 1) - go func() { - log.Printf("[TRACE] waiting for heartbeat completion") - select { - case <-ctx.Done(): - cleanupHeartbeat() - err := b.UpdateBuildStatus( - context.Background(), - buildName, - models.HashicorpCloudPackerBuildStatusCANCELLED) - if err != nil { - log.Printf( - "[ERROR] failed to update HCP Packer registry status for %q: %s", - buildName, - err) - } - case <-buildDone: - cleanupHeartbeat() - } - log.Printf("[TRACE] done waiting for heartbeat completion") - }() - - b.RunningBuilds[buildName] = buildDone - - return nil -} - -func (b *Bucket) BuildDone( - ctx context.Context, - buildName string, - artifacts []packer.Artifact, - buildErr error, -) ([]packer.Artifact, error) { - doneCh, ok := b.RunningBuilds[buildName] - if !ok { - log.Print("[ERROR] done build does not have an entry in the heartbeat table, state will be inconsistent.") - } else { - log.Printf("[TRACE] signal stopping heartbeats") - // Stop heartbeating - doneCh <- struct{}{} - log.Printf("[TRACE] stopped heartbeats") - } - - if buildErr != nil { - err := b.UpdateBuildStatus(ctx, buildName, models.HashicorpCloudPackerBuildStatusFAILED) - if err != nil { - log.Printf("[ERROR] failed to update build %q status to FAILED: %s", buildName, err) - } - return artifacts, fmt.Errorf("build failed, not uploading artifacts") - } - - for _, art := range artifacts { - var images []registryimage.Image - decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ - Result: &images, - WeaklyTypedInput: true, - ErrorUnused: false, - }) - if err != nil { - return artifacts, fmt.Errorf("failed to create decoder for HCP Packer registry image: %w", err) - } - - state := art.State(registryimage.ArtifactStateURI) - err = decoder.Decode(state) - if err != nil { - return artifacts, fmt.Errorf("failed to obtain HCP Packer registry image from post-processor artifact: %w", err) - } - log.Printf("[TRACE] updating artifacts for build %q", buildName) - err = b.UpdateImageForBuild(buildName, images...) - - if err != nil { - return artifacts, fmt.Errorf("failed to add image artifact for %q: %s", buildName, err) - } - } - - parErr := b.CompleteBuild(ctx, buildName) - if parErr != nil { - return artifacts, fmt.Errorf( - "failed to update Packer registry with image artifacts for %q: %s", - buildName, - parErr) - } - - return append(artifacts, &RegistryArtifact{ - BuildName: buildName, - BucketSlug: b.Slug, - IterationID: b.Iteration.ID, - }), nil -} diff --git a/packer/core.go b/packer/core.go index 24cd8b9cb53..86df353fd15 100644 --- a/packer/core.go +++ b/packer/core.go @@ -14,11 +14,11 @@ import ( "github.com/google/go-cmp/cmp" multierror "github.com/hashicorp/go-multierror" version "github.com/hashicorp/go-version" - "github.com/hashicorp/hcl/v2" + hcl "github.com/hashicorp/hcl/v2" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" "github.com/hashicorp/packer-plugin-sdk/template" "github.com/hashicorp/packer-plugin-sdk/template/interpolate" - packerregistry "github.com/hashicorp/packer/internal/registry" + plugingetter "github.com/hashicorp/packer/packer/plugin-getter" packerversion "github.com/hashicorp/packer/version" ) @@ -27,8 +27,6 @@ import ( type Core struct { Template *template.Template - Bucket *packerregistry.Bucket - components ComponentFinder variables map[string]string builds map[string]*template.Builder @@ -131,7 +129,20 @@ func NewCore(c *CoreConfig) *Core { return core } -func (core *Core) Initialize() error { +func (c *Core) Initialize(_ InitializeOptions) hcl.Diagnostics { + err := c.initialize() + if err != nil { + return hcl.Diagnostics{ + &hcl.Diagnostic{ + Detail: err.Error(), + Severity: hcl.DiagError, + }, + } + } + return nil +} + +func (core *Core) initialize() error { if err := core.validate(); err != nil { return err } @@ -155,9 +166,20 @@ func (core *Core) Initialize() error { core.builds[v] = b } + return nil } +func (c *Core) PluginRequirements() (plugingetter.Requirements, hcl.Diagnostics) { + return nil, hcl.Diagnostics{ + &hcl.Diagnostic{ + Summary: "Packer plugins currently only works with HCL2 configuration templates", + Detail: "Please manually install plugins with the plugins command or use a HCL2 configuration that will do that for you.", + Severity: hcl.DiagError, + }, + } +} + // BuildNames returns the builds that are available in this configured core. func (c *Core) BuildNames(only, except []string) []string { @@ -871,9 +893,3 @@ func (c *Core) init() error { return nil } - -/// GetRegistryBucket returns a configured bucket that can be used for -// publishing build image artifacts to some HCP Packer Registry. -func (c *Core) GetRegistryBucket() *packerregistry.Bucket { - return c.Bucket -} diff --git a/packer/core_test.go b/packer/core_test.go index 5e43b5e6fa0..5de1ec589f7 100644 --- a/packer/core_test.go +++ b/packer/core_test.go @@ -43,9 +43,9 @@ func TestCoreBuildNames(t *testing.T) { Template: tpl, Variables: tc.Vars, }) - err = core.Initialize() - if err != nil { - t.Fatalf("err: %s\n\n%s", tc.File, err) + diags := core.Initialize(InitializeOptions{}) + if diags.HasErrors() { + t.Fatalf("err: %s\n\n%s", tc.File, diags) } names := core.BuildNames(nil, nil) @@ -495,9 +495,9 @@ func TestCoreValidate(t *testing.T) { Variables: tc.Vars, Version: "1.0.0", }) - err = core.Initialize() + diags := core.Initialize(InitializeOptions{}) - if (err != nil) != tc.Err { + if diags.HasErrors() != tc.Err { t.Fatalf("err: %s\n\n%s", tc.File, err) } } @@ -543,13 +543,13 @@ func TestCore_InterpolateUserVars(t *testing.T) { Template: tpl, Version: "1.0.0", }) - err = ccf.Initialize() + diags := ccf.Initialize(InitializeOptions{}) - if (err != nil) != tc.Err { + if diags.HasErrors() != tc.Err { if tc.Err == false { - t.Fatalf("Error interpolating %s: Expected no error, but got: %s", tc.File, err) + t.Fatalf("Error interpolating %s: Expected no error, but got: %s", tc.File, diags) } else { - t.Fatalf("Error interpolating %s: Expected an error, but got: %s", tc.File, err) + t.Fatalf("Error interpolating %s: Expected an error, but got: %s", tc.File, diags) } } @@ -616,10 +616,10 @@ func TestCore_InterpolateUserVars_VarFile(t *testing.T) { Version: "1.0.0", Variables: tc.Variables, }) - err = ccf.Initialize() + diags := ccf.Initialize(InitializeOptions{}) - if (err != nil) != tc.Err { - t.Fatalf("err: %s\n\n%s", tc.File, err) + if diags.HasErrors() != tc.Err { + t.Fatalf("err: %s\n\n%s", tc.File, diags) } if !tc.Err { for k, v := range ccf.variables { @@ -676,10 +676,10 @@ func TestSensitiveVars(t *testing.T) { Variables: tc.Vars, Version: "1.0.0", }) - err = ccf.Initialize() + diags := ccf.Initialize(InitializeOptions{}) - if (err != nil) != tc.Err { - t.Fatalf("err: %s\n\n%s", tc.File, err) + if diags.HasErrors() != tc.Err { + t.Fatalf("err: %s\n\n%s", tc.File, diags) } // Check that filter correctly manipulates strings: filtered := packersdk.LogSecretFilter.FilterString("the foo jumped over the bar_extra_sensitive_probably_a_password") @@ -758,7 +758,7 @@ func TestEnvAndFileVars(t *testing.T) { "final_var": "{{user `env_1`}}/{{user `env_2`}}/{{user `env_4`}}{{user `env_3`}}-{{user `var_1`}}/vmware/{{user `var_2`}}.vmx", }, }) - err = ccf.Initialize() + diags := ccf.Initialize(InitializeOptions{}) expected := map[string]string{ "var_1": "partyparrot", @@ -769,8 +769,8 @@ func TestEnvAndFileVars(t *testing.T) { "env_3": "/path/to/nowhere", "env_4": "bananas", } - if err != nil { - t.Fatalf("err: %s\n\n%s", "complex-recursed-env-user-var-file.json", err) + if diags.HasErrors() { + t.Fatalf("err: %s\n\n%s", "complex-recursed-env-user-var-file.json", diags) } for k, v := range ccf.variables { if expected[k] != v { diff --git a/packer/run_interfaces.go b/packer/run_interfaces.go index aa1d69dd0c1..0eff3fa4c34 100644 --- a/packer/run_interfaces.go +++ b/packer/run_interfaces.go @@ -1,9 +1,8 @@ package packer import ( - "github.com/hashicorp/hcl/v2" + hcl "github.com/hashicorp/hcl/v2" packersdk "github.com/hashicorp/packer-plugin-sdk/packer" - packerregistry "github.com/hashicorp/packer/internal/registry" plugingetter "github.com/hashicorp/packer/packer/plugin-getter" ) @@ -51,14 +50,6 @@ type Handler interface { BuildGetter ConfigFixer ConfigInspector - HCPHandler -} - -// The HCPHandler handles Packer things needed for communicating with a HCP Packer Registry. -type HCPHandler interface { - // ConfiguredArtifactMetadataPublisher returns a configured Bucket that can be used to publish - // build artifacts to the said image bucket. - ConfiguredArtifactMetadataPublisher() (*packerregistry.Bucket, hcl.Diagnostics) } //go:generate enumer -type FixConfigMode diff --git a/packer/testing.go b/packer/testing.go index 40780297106..dcdcf2a3023 100644 --- a/packer/testing.go +++ b/packer/testing.go @@ -25,7 +25,7 @@ func TestCoreConfig(t *testing.T) *CoreConfig { func TestCore(t *testing.T, c *CoreConfig) *Core { core := NewCore(c) - err := core.Initialize() + err := core.Initialize(InitializeOptions{}) if err != nil { t.Fatalf("err: %s", err) }