diff --git a/cmd/buildx/main.go b/cmd/buildx/main.go index 69124a3aeb4e..cbed27ea8c98 100644 --- a/cmd/buildx/main.go +++ b/cmd/buildx/main.go @@ -6,6 +6,7 @@ import ( "os" "github.com/docker/buildx/commands" + controllererrors "github.com/docker/buildx/controller/errdefs" "github.com/docker/buildx/util/desktop" "github.com/docker/buildx/version" "github.com/docker/cli/cli" @@ -16,6 +17,7 @@ import ( cliflags "github.com/docker/cli/cli/flags" "github.com/moby/buildkit/solver/errdefs" "github.com/moby/buildkit/util/stack" + "github.com/pkg/errors" "go.opentelemetry.io/otel" //nolint:staticcheck // vendored dependencies may still use this @@ -106,8 +108,15 @@ func main() { } else { fmt.Fprintf(cmd.Err(), "ERROR: %v\n", err) } - if ebr, ok := err.(*desktop.ErrorWithBuildRef); ok { + + var ebr *desktop.ErrorWithBuildRef + if errors.As(err, &ebr) { ebr.Print(cmd.Err()) + } else { + var be *controllererrors.BuildError + if errors.As(err, &be) { + be.PrintBuildDetails(cmd.Err()) + } } os.Exit(1) diff --git a/controller/errdefs/build.go b/controller/errdefs/build.go index ffa5f6da8f00..471adbac5176 100644 --- a/controller/errdefs/build.go +++ b/controller/errdefs/build.go @@ -1,7 +1,10 @@ package errdefs import ( + "io" + "github.com/containerd/typeurl/v2" + "github.com/docker/buildx/util/desktop" "github.com/moby/buildkit/util/grpcerrors" ) @@ -22,11 +25,22 @@ func (e *BuildError) ToProto() grpcerrors.TypedErrorProto { return e.Build } -func WrapBuild(err error, ref string) error { +func (e *BuildError) PrintBuildDetails(w io.Writer) error { + if e.BuildRef == "" { + return nil + } + ebr := &desktop.ErrorWithBuildRef{ + Ref: e.BuildRef, + Err: e.error, + } + return ebr.Print(w) +} + +func WrapBuild(err error, ref string, buildRef string) error { if err == nil { return nil } - return &BuildError{Build: &Build{Ref: ref}, error: err} + return &BuildError{Build: &Build{Ref: ref, BuildRef: buildRef}, error: err} } func (b *Build) WrapError(err error) error { diff --git a/controller/errdefs/errdefs.pb.go b/controller/errdefs/errdefs.pb.go index ead4df646a76..40505a99fdb1 100644 --- a/controller/errdefs/errdefs.pb.go +++ b/controller/errdefs/errdefs.pb.go @@ -25,7 +25,8 @@ type Build struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"` + Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"` + BuildRef string `protobuf:"bytes,2,opt,name=BuildRef,proto3" json:"BuildRef,omitempty"` } func (x *Build) Reset() { @@ -67,6 +68,13 @@ func (x *Build) GetRef() string { return "" } +func (x *Build) GetBuildRef() string { + if x != nil { + return x.BuildRef + } + return "" +} + var File_github_com_docker_buildx_controller_errdefs_errdefs_proto protoreflect.FileDescriptor var file_github_com_docker_buildx_controller_errdefs_errdefs_proto_rawDesc = []byte{ @@ -75,12 +83,13 @@ var file_github_com_docker_buildx_controller_errdefs_errdefs_proto_rawDesc = []b 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, 0x2f, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x78, 0x2e, 0x65, 0x72, 0x72, 0x64, 0x65, - 0x66, 0x73, 0x22, 0x19, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x52, - 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x42, 0x2d, 0x5a, - 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x63, 0x6b, - 0x65, 0x72, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x78, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x66, 0x73, 0x22, 0x35, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x52, + 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x12, 0x1a, 0x0a, + 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x2f, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x78, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x2f, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/controller/errdefs/errdefs.proto b/controller/errdefs/errdefs.proto index f99b5953543f..ded837e94a56 100644 --- a/controller/errdefs/errdefs.proto +++ b/controller/errdefs/errdefs.proto @@ -6,4 +6,5 @@ option go_package = "github.com/docker/buildx/controller/errdefs"; message Build { string Ref = 1; + string BuildRef = 2; } diff --git a/controller/local/controller.go b/controller/local/controller.go index 48e7e00da2c0..68c5a809bacf 100644 --- a/controller/local/controller.go +++ b/controller/local/controller.go @@ -11,6 +11,7 @@ import ( controllererrors "github.com/docker/buildx/controller/errdefs" controllerapi "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/controller/processes" + "github.com/docker/buildx/util/desktop" "github.com/docker/buildx/util/ioset" "github.com/docker/buildx/util/progress" "github.com/docker/cli/cli/command" @@ -56,7 +57,12 @@ func (b *localController) Build(ctx context.Context, options *controllerapi.Buil buildOptions: options, } if buildErr != nil { - buildErr = controllererrors.WrapBuild(buildErr, b.ref) + var buildRef string + var ebr *desktop.ErrorWithBuildRef + if errors.As(buildErr, &ebr) { + buildRef = ebr.Ref + } + buildErr = controllererrors.WrapBuild(buildErr, b.ref, buildRef) } } if buildErr != nil { diff --git a/controller/remote/server.go b/controller/remote/server.go index b0b82bef1388..f586571b58ea 100644 --- a/controller/remote/server.go +++ b/controller/remote/server.go @@ -11,6 +11,7 @@ import ( controllererrors "github.com/docker/buildx/controller/errdefs" "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/controller/processes" + "github.com/docker/buildx/util/desktop" "github.com/docker/buildx/util/ioset" "github.com/docker/buildx/util/progress" "github.com/docker/buildx/version" @@ -210,7 +211,12 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp s.buildOptions = req.Options m.session[ref] = s if buildErr != nil { - buildErr = controllererrors.WrapBuild(buildErr, ref) + var buildRef string + var ebr *desktop.ErrorWithBuildRef + if errors.As(buildErr, &ebr) { + buildRef = ebr.Ref + } + buildErr = controllererrors.WrapBuild(buildErr, ref, buildRef) } } } else { diff --git a/tests/build.go b/tests/build.go index 207f52d338a7..292024a85546 100644 --- a/tests/build.go +++ b/tests/build.go @@ -492,11 +492,6 @@ RUN echo foo > /bar`) require.NoError(t, err, string(out)) require.True(t, buildDetailsPattern.MatchString(string(out)), fmt.Sprintf("expected build details link in output, got %q", out)) - if isExperimental() { - // FIXME: https://github.com/docker/buildx/issues/2382 - t.Skip("build details link not displayed in experimental mode when build fails: https://github.com/docker/buildx/issues/2382") - } - // build erroneous dockerfile dockerfile = []byte(`FROM busybox:latest RUN exit 1`) diff --git a/util/desktop/desktop.go b/util/desktop/desktop.go index 7fa4ee6d8024..563b8f2fd3e2 100644 --- a/util/desktop/desktop.go +++ b/util/desktop/desktop.go @@ -65,7 +65,6 @@ func hyperlink(url string) string { type ErrorWithBuildRef struct { Ref string Err error - Msg string } func (e *ErrorWithBuildRef) Error() string {