dap: attempt to find multiple digests when a failure happens

The solve error that gets returned sometimes has a platform when the LLB
returned by `ToState` doesn't. In order to ensure we find the failed
digest, we now search for both the digest of what was returned and also
clear out the platform and search for the digest without that in case
that one matches instead.

Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
This commit is contained in:
Jonathan A. Sternberg
2025-10-29 16:08:46 -05:00
parent 00502c0199
commit 9099a030f4
+23 -13
View File
@@ -4,6 +4,7 @@ import (
"context"
"path"
"path/filepath"
"slices"
"sync"
"github.com/docker/buildx/build"
@@ -646,29 +647,38 @@ func (t *thread) rewind(ctx Context, inErr error) (k string, result *step, mount
return "", nil, nil, inErr
}
dt, err := solveErr.Op.Marshal()
if err != nil {
return "", nil, nil, err
// Find the error digests we might have failed on.
var digests []digest.Digest
if dt, err := solveErr.Op.Marshal(); err == nil {
digests = append(digests, digest.FromBytes(dt))
}
// Find the error digest.
errDgst := digest.FromBytes(dt)
// Include a version of the digest without the platform
// if this is a file op.
if _, ok := solveErr.Op.Op.(*pb.Op_File); ok && solveErr.Op.Platform != nil {
op := solveErr.Op.CloneVT()
op.Platform = nil
if dt, err := op.Marshal(); err == nil {
digests = append(digests, digest.FromBytes(dt))
}
}
if len(digests) == 0 {
return "", nil, nil, inErr
}
// Iterate from the first step to find the one we failed on.
result = t.entrypoint
for result != nil && result.dgst != errDgst {
for result != nil && !slices.Contains(digests, result.dgst) {
result = result.in
}
if result == nil {
return "", nil, nil, inErr
}
// Seek to this step. This should succeed because otherwise
// we wouldn't have been able to even fail on it to begin with.
k, result, mounts, err = t.seek(ctx, result)
if err != nil {
return k, result, mounts, err
k, result, mounts, retErr = t.seek(ctx, result)
if retErr != nil {
return k, result, mounts, retErr
}
return k, result, mounts, inErr
}