mirror of https://github.com/docker/buildx.git
build: fix build details link in experimental mode
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
parent
746eadd16e
commit
1060328a96
|
@ -6,6 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/docker/buildx/commands"
|
"github.com/docker/buildx/commands"
|
||||||
|
controllererrors "github.com/docker/buildx/controller/errdefs"
|
||||||
"github.com/docker/buildx/util/desktop"
|
"github.com/docker/buildx/util/desktop"
|
||||||
"github.com/docker/buildx/version"
|
"github.com/docker/buildx/version"
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -16,6 +17,7 @@ import (
|
||||||
cliflags "github.com/docker/cli/cli/flags"
|
cliflags "github.com/docker/cli/cli/flags"
|
||||||
"github.com/moby/buildkit/solver/errdefs"
|
"github.com/moby/buildkit/solver/errdefs"
|
||||||
"github.com/moby/buildkit/util/stack"
|
"github.com/moby/buildkit/util/stack"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"go.opentelemetry.io/otel"
|
"go.opentelemetry.io/otel"
|
||||||
|
|
||||||
//nolint:staticcheck // vendored dependencies may still use this
|
//nolint:staticcheck // vendored dependencies may still use this
|
||||||
|
@ -109,8 +111,15 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(cmd.Err(), "ERROR: %v\n", err)
|
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())
|
ebr.Print(cmd.Err())
|
||||||
|
} else {
|
||||||
|
var be *controllererrors.BuildError
|
||||||
|
if errors.As(err, &be) {
|
||||||
|
be.PrintBuildDetails(cmd.Err())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package errdefs
|
package errdefs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/containerd/typeurl/v2"
|
"github.com/containerd/typeurl/v2"
|
||||||
|
"github.com/docker/buildx/util/desktop"
|
||||||
"github.com/moby/buildkit/util/grpcerrors"
|
"github.com/moby/buildkit/util/grpcerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,11 +25,22 @@ func (e *BuildError) ToProto() grpcerrors.TypedErrorProto {
|
||||||
return e.Build
|
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 {
|
if err == nil {
|
||||||
return 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 {
|
func (b *Build) WrapError(err error) error {
|
||||||
|
|
|
@ -26,6 +26,7 @@ type Build struct {
|
||||||
unknownFields protoimpl.UnknownFields
|
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() {
|
func (x *Build) Reset() {
|
||||||
|
@ -67,6 +68,13 @@ func (x *Build) GetRef() string {
|
||||||
return ""
|
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 protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_github_com_docker_buildx_controller_errdefs_errdefs_proto_rawDesc = []byte{
|
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,
|
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,
|
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,
|
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,
|
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, 0x42, 0x2d, 0x5a,
|
0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x12, 0x1a, 0x0a,
|
||||||
0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x63, 0x6b,
|
0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
0x65, 0x72, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x78, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
0x08, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74,
|
||||||
0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x65, 0x72, 0x72, 0x64, 0x65, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72,
|
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x2f, 0x62,
|
||||||
0x6f, 0x74, 0x6f, 0x33,
|
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 (
|
var (
|
||||||
|
|
|
@ -6,4 +6,5 @@ option go_package = "github.com/docker/buildx/controller/errdefs";
|
||||||
|
|
||||||
message Build {
|
message Build {
|
||||||
string Ref = 1;
|
string Ref = 1;
|
||||||
|
string BuildRef = 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ func (m *Build) CloneVT() *Build {
|
||||||
}
|
}
|
||||||
r := new(Build)
|
r := new(Build)
|
||||||
r.Ref = m.Ref
|
r.Ref = m.Ref
|
||||||
|
r.BuildRef = m.BuildRef
|
||||||
if len(m.unknownFields) > 0 {
|
if len(m.unknownFields) > 0 {
|
||||||
r.unknownFields = make([]byte, len(m.unknownFields))
|
r.unknownFields = make([]byte, len(m.unknownFields))
|
||||||
copy(r.unknownFields, m.unknownFields)
|
copy(r.unknownFields, m.unknownFields)
|
||||||
|
@ -45,6 +46,9 @@ func (this *Build) EqualVT(that *Build) bool {
|
||||||
if this.Ref != that.Ref {
|
if this.Ref != that.Ref {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if this.BuildRef != that.BuildRef {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return string(this.unknownFields) == string(that.unknownFields)
|
return string(this.unknownFields) == string(that.unknownFields)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +89,13 @@ func (m *Build) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
|
||||||
i -= len(m.unknownFields)
|
i -= len(m.unknownFields)
|
||||||
copy(dAtA[i:], m.unknownFields)
|
copy(dAtA[i:], m.unknownFields)
|
||||||
}
|
}
|
||||||
|
if len(m.BuildRef) > 0 {
|
||||||
|
i -= len(m.BuildRef)
|
||||||
|
copy(dAtA[i:], m.BuildRef)
|
||||||
|
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.BuildRef)))
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x12
|
||||||
|
}
|
||||||
if len(m.Ref) > 0 {
|
if len(m.Ref) > 0 {
|
||||||
i -= len(m.Ref)
|
i -= len(m.Ref)
|
||||||
copy(dAtA[i:], m.Ref)
|
copy(dAtA[i:], m.Ref)
|
||||||
|
@ -105,6 +116,10 @@ func (m *Build) SizeVT() (n int) {
|
||||||
if l > 0 {
|
if l > 0 {
|
||||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
}
|
}
|
||||||
|
l = len(m.BuildRef)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||||
|
}
|
||||||
n += len(m.unknownFields)
|
n += len(m.unknownFields)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
@ -170,6 +185,38 @@ func (m *Build) UnmarshalVT(dAtA []byte) error {
|
||||||
}
|
}
|
||||||
m.Ref = string(dAtA[iNdEx:postIndex])
|
m.Ref = string(dAtA[iNdEx:postIndex])
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 2:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field BuildRef", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return protohelpers.ErrIntOverflow
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= uint64(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return protohelpers.ErrInvalidLength
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex < 0 {
|
||||||
|
return protohelpers.ErrInvalidLength
|
||||||
|
}
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.BuildRef = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
|
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
controllererrors "github.com/docker/buildx/controller/errdefs"
|
controllererrors "github.com/docker/buildx/controller/errdefs"
|
||||||
controllerapi "github.com/docker/buildx/controller/pb"
|
controllerapi "github.com/docker/buildx/controller/pb"
|
||||||
"github.com/docker/buildx/controller/processes"
|
"github.com/docker/buildx/controller/processes"
|
||||||
|
"github.com/docker/buildx/util/desktop"
|
||||||
"github.com/docker/buildx/util/ioset"
|
"github.com/docker/buildx/util/ioset"
|
||||||
"github.com/docker/buildx/util/progress"
|
"github.com/docker/buildx/util/progress"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
|
@ -56,7 +57,12 @@ func (b *localController) Build(ctx context.Context, options *controllerapi.Buil
|
||||||
buildOptions: options,
|
buildOptions: options,
|
||||||
}
|
}
|
||||||
if buildErr != nil {
|
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 {
|
if buildErr != nil {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
controllererrors "github.com/docker/buildx/controller/errdefs"
|
controllererrors "github.com/docker/buildx/controller/errdefs"
|
||||||
"github.com/docker/buildx/controller/pb"
|
"github.com/docker/buildx/controller/pb"
|
||||||
"github.com/docker/buildx/controller/processes"
|
"github.com/docker/buildx/controller/processes"
|
||||||
|
"github.com/docker/buildx/util/desktop"
|
||||||
"github.com/docker/buildx/util/ioset"
|
"github.com/docker/buildx/util/ioset"
|
||||||
"github.com/docker/buildx/util/progress"
|
"github.com/docker/buildx/util/progress"
|
||||||
"github.com/docker/buildx/version"
|
"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
|
s.buildOptions = req.Options
|
||||||
m.session[ref] = s
|
m.session[ref] = s
|
||||||
if buildErr != nil {
|
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 {
|
} else {
|
||||||
|
|
|
@ -493,11 +493,6 @@ RUN echo foo > /bar`)
|
||||||
require.NoError(t, err, string(out))
|
require.NoError(t, err, string(out))
|
||||||
require.True(t, buildDetailsPattern.MatchString(string(out)), fmt.Sprintf("expected build details link in output, got %q", 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
|
// build erroneous dockerfile
|
||||||
dockerfile = []byte(`FROM busybox:latest
|
dockerfile = []byte(`FROM busybox:latest
|
||||||
RUN exit 1`)
|
RUN exit 1`)
|
||||||
|
|
|
@ -65,7 +65,6 @@ func hyperlink(url string) string {
|
||||||
type ErrorWithBuildRef struct {
|
type ErrorWithBuildRef struct {
|
||||||
Ref string
|
Ref string
|
||||||
Err error
|
Err error
|
||||||
Msg string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ErrorWithBuildRef) Error() string {
|
func (e *ErrorWithBuildRef) Error() string {
|
||||||
|
|
Loading…
Reference in New Issue