build: don't suggest lack of HCP support on fail

When running a build with HCP Packer enabled, Packer attempts to push
the build status to HCP.
If the build fails, we update the status to BUILD_FAILED, and that's the
end of it.
If however the build succeeds, Packer attempts to get the HCP artifact
from the builder, which will only succeed if the builder supports it.
Otherwise, we'll get either nil, or an artifact type that is not
compatible with what is expected for HCP support.

When either of those happens, we warn that the builder may not support
HCP Packer at all, so users are aware of the problem.

However, when the error was introduced, it only looked at the fact that
an error was produced, independently of the type of error. This caused
legitimate errors while building to be reported as potential
incompatibility between the builder and HCP, which was confusing to
users.

This commit changes this by introducing a new error type, only produced
when the artifact either is nil, or failed to be deserialised into a HCP
artifact, which lets us produce the incompatibility warning with more
accuracy.
pull/12845/head
Lucas Bajolet 2 years ago committed by Lucas Bajolet
parent 9b01bfa486
commit 548893bbee

@ -207,7 +207,6 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int
}{m: make(map[string]error)}
limitParallel := semaphore.NewWeighted(cla.ParallelBuilds)
var hasPossibleIncompatibleHCPIntegration bool
for i := range builds {
if err := buildCtx.Err(); err != nil {
log.Println("Interrupted, not going to start any more builds.")
@ -270,16 +269,29 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int
runArtifacts,
err)
if hcperr != nil {
writeDiags(c.Ui, nil, hcl.Diagnostics{
&hcl.Diagnostic{
Summary: fmt.Sprintf(
"publishing build metadata to HCP Packer for %q failed",
name),
Severity: hcl.DiagError,
Detail: hcperr.Error(),
},
})
hasPossibleIncompatibleHCPIntegration = true
if _, ok := hcperr.(*registry.NotAHCPArtifactError); ok {
writeDiags(c.Ui, nil, hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: fmt.Sprintf("The %q builder produced an artifact that cannot be pushed to HCP Packer", b.Name()),
Detail: fmt.Sprintf(
`%s
Check that you are using an HCP Ready integration before trying again:
%s`,
hcperr, hcpReadyIntegrationURL),
},
})
} else {
writeDiags(c.Ui, nil, hcl.Diagnostics{
&hcl.Diagnostic{
Summary: fmt.Sprintf(
"publishing build metadata to HCP Packer for %q failed",
name),
Severity: hcl.DiagError,
Detail: hcperr.Error(),
},
})
}
}
if err != nil {
@ -391,15 +403,6 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int
c.Ui.Say("\n==> Builds finished but no artifacts were created.")
}
if hasPossibleIncompatibleHCPIntegration {
msg := fmt.Sprintf(`
It looks like one or more plugins in your build may be incompatible with HCP Packer.
Check that you are using an HCP Ready integration before trying again:
%s`, hcpReadyIntegrationURL)
c.Ui.Error(msg)
}
if len(errs.m) > 0 {
// If any errors occurred, exit with a non-zero exit status
ret = 1

@ -595,6 +595,10 @@ func (bucket *Bucket) startBuild(ctx context.Context, buildName string) error {
return nil
}
type NotAHCPArtifactError struct {
error
}
func (bucket *Bucket) completeBuild(
ctx context.Context,
buildName string,
@ -638,12 +642,19 @@ func (bucket *Bucket) completeBuild(
}
state := art.State(packerSDKRegistry.ArtifactStateURI)
if state == nil {
return packerSDKArtifacts, &NotAHCPArtifactError{
fmt.Errorf("The HCP artifact returned by the builder is nil, this is likely because the builder does not support HCP Packer."),
}
}
err = decoder.Decode(state)
if err != nil {
return packerSDKArtifacts, fmt.Errorf(
"failed to obtain HCP Packer compliant artifact: %w",
err)
return packerSDKArtifacts, &NotAHCPArtifactError{
fmt.Errorf("Failed to obtain HCP Packer compliant artifact: %s", err),
}
}
log.Printf("[TRACE] updating artifacts for build %q", buildName)
err = bucket.UpdateArtifactForBuild(buildName, sdkImages...)

Loading…
Cancel
Save