diff --git a/go.mod b/go.mod index 4ca1dde8..4bc4f8fb 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b // indirect github.com/containerd/go-cni v1.0.0 github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328 + github.com/containerd/typeurl v1.0.1 github.com/coreos/go-systemd/v22 v22.1.0 github.com/docker/cli v0.0.0-20200227165822-2298e6a3fe24 github.com/docker/distribution v2.7.1+incompatible diff --git a/solver/errdefs/vertex.go b/solver/errdefs/vertex.go index 71fdb6ca..4ec37516 100644 --- a/solver/errdefs/vertex.go +++ b/solver/errdefs/vertex.go @@ -1,14 +1,14 @@ package errdefs import ( - proto "github.com/golang/protobuf/proto" + "github.com/containerd/typeurl" "github.com/moby/buildkit/util/grpcerrors" digest "github.com/opencontainers/go-digest" ) func init() { - proto.RegisterType((*Vertex)(nil), "errdefs.Vertex") - proto.RegisterType((*Source)(nil), "errdefs.Source") + typeurl.Register((*Vertex)(nil), "github.com/moby/buildkit", "errdefs.Vertex+json") + typeurl.Register((*Source)(nil), "github.com/moby/buildkit", "errdefs.Source+json") } type VertexError struct { diff --git a/util/grpcerrors/grpcerrors.go b/util/grpcerrors/grpcerrors.go index acba2750..28bc1a58 100644 --- a/util/grpcerrors/grpcerrors.go +++ b/util/grpcerrors/grpcerrors.go @@ -1,11 +1,15 @@ package grpcerrors import ( + "encoding/json" + "errors" + + "github.com/containerd/typeurl" gogotypes "github.com/gogo/protobuf/types" "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/any" "github.com/moby/buildkit/util/stack" + "github.com/sirupsen/logrus" spb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -47,7 +51,7 @@ func ToGRPC(err error) error { }) if len(details) > 0 { - if st2, err := st.WithDetails(details...); err == nil { + if st2, err := withDetails(st, details...); err == nil { st = st2 } } @@ -55,6 +59,26 @@ func ToGRPC(err error) error { return st.Err() } +func withDetails(s *status.Status, details ...proto.Message) (*status.Status, error) { + if s.Code() == codes.OK { + return nil, errors.New("no error details for status with code OK") + } + p := s.Proto() + for _, detail := range details { + url, err := typeurl.TypeURL(detail) + if err != nil { + logrus.Warnf("ignoring typed error %T: not registered", detail) + continue + } + dt, err := json.Marshal(detail) + if err != nil { + return nil, err + } + p.Details = append(p.Details, &any.Any{TypeUrl: url, Value: dt}) + } + return status.FromProto(p), nil +} + func Code(err error) codes.Code { if se, ok := err.(interface { Code() codes.Code @@ -123,17 +147,9 @@ func FromGRPC(err error) error { // details that we don't understand are copied as proto for _, d := range pb.Details { - var m interface{} - detail := &ptypes.DynamicAny{} - if err := ptypes.UnmarshalAny(d, detail); err != nil { - detail := &gogotypes.DynamicAny{} - if err := gogotypes.UnmarshalAny(gogoAny(d), detail); err != nil { - n.Details = append(n.Details, d) - continue - } - m = detail.Message - } else { - m = detail.Message + m, err := typeurl.UnmarshalAny(gogoAny(d)) + if err != nil { + continue } switch v := m.(type) { @@ -144,7 +160,6 @@ func FromGRPC(err error) error { default: n.Details = append(n.Details, d) } - } err = status.FromProto(n).Err() diff --git a/util/stack/stack.go b/util/stack/stack.go index 6d3cfc83..b56b0b9f 100644 --- a/util/stack/stack.go +++ b/util/stack/stack.go @@ -7,9 +7,14 @@ import ( "strconv" "strings" + "github.com/containerd/typeurl" "github.com/pkg/errors" ) +func init() { + typeurl.Register((*Stack)(nil), "github.com/moby/buildkit", "stack.Stack+json") +} + var version string var revision string