diff --git a/command/debug.go b/command/debug.go index 5ea2c9f44a270cad9b7627398b0de1c97193181d..f3f2484b0baff382fc8d949196649fb32c0f3cd9 100644 --- a/command/debug.go +++ b/command/debug.go @@ -6,7 +6,6 @@ import ( "archive/tar" "compress/gzip" "context" - "encoding/hex" "fmt" "io" "io/ioutil" @@ -19,6 +18,10 @@ import ( "github.com/ethereum/go-ethereum/command/flagset" "github.com/ethereum/go-ethereum/command/server/proto" + "github.com/golang/protobuf/jsonpb" + gproto "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes/empty" + grpc_net_conn "github.com/mitchellh/go-grpc-net-conn" ) type DebugCommand struct { @@ -118,16 +121,35 @@ func (d *DebugCommand) Run(args []string) int { req.Type = proto.PprofRequest_LOOKUP req.Profile = profile } - resp, err := clt.Pprof(ctx, req) + stream, err := clt.Pprof(ctx, req) if err != nil { return err } - // write file - raw, err := hex.DecodeString(resp.Payload) + // wait for open request + msg, err := stream.Recv() if err != nil { return err } - if err := ioutil.WriteFile(filepath.Join(tmp, filename+".prof"), raw, 0755); err != nil { + if _, ok := msg.Event.(*proto.PprofResponse_Open_); !ok { + return fmt.Errorf("expected open message") + } + + // create the stream + conn := &grpc_net_conn.Conn{ + Stream: stream, + Response: &proto.PprofResponse_Input{}, + Decode: grpc_net_conn.SimpleDecoder(func(msg gproto.Message) *[]byte { + return &msg.(*proto.PprofResponse_Input).Data + }), + } + + file, err := os.OpenFile(filepath.Join(tmp, filename+".prof"), os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return err + } + defer file.Close() + + if _, err := io.Copy(file, conn); err != nil { return err } return nil @@ -148,6 +170,25 @@ func (d *DebugCommand) Run(args []string) int { } } + // append the status + { + statusResp, err := clt.Status(ctx, &empty.Empty{}) + if err != nil { + d.UI.Output(fmt.Sprintf("Failed to get status: %v", err)) + return 1 + } + m := jsonpb.Marshaler{} + data, err := m.MarshalToString(statusResp) + if err != nil { + d.UI.Output(err.Error()) + return 1 + } + if err := ioutil.WriteFile(filepath.Join(tmp, "status.json"), []byte(data), 0644); err != nil { + d.UI.Output(fmt.Sprintf("Failed to write status: %v", err)) + return 1 + } + } + // Exit before archive if output directory was specified if d.output != "" { d.UI.Output(fmt.Sprintf("Created debug directory: %s", tmp)) diff --git a/command/server/proto/server.pb.go b/command/server/proto/server.pb.go index bfa0b7eaf99ceba0c3116b417929a60b5b0e7f2b..d1a5ed77b2b3b25a947df24c4c7cff9b30a6ba40 100644 --- a/command/server/proto/server.pb.go +++ b/command/server/proto/server.pb.go @@ -830,8 +830,11 @@ type PprofResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Payload string `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` - Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Types that are assignable to Event: + // *PprofResponse_Open_ + // *PprofResponse_Input_ + // *PprofResponse_Eof + Event isPprofResponse_Event `protobuf_oneof:"event"` } func (x *PprofResponse) Reset() { @@ -866,20 +869,56 @@ func (*PprofResponse) Descriptor() ([]byte, []int) { return file_command_server_proto_server_proto_rawDescGZIP(), []int{14} } -func (x *PprofResponse) GetPayload() string { - if x != nil { - return x.Payload +func (m *PprofResponse) GetEvent() isPprofResponse_Event { + if m != nil { + return m.Event } - return "" + return nil } -func (x *PprofResponse) GetHeaders() map[string]string { - if x != nil { - return x.Headers +func (x *PprofResponse) GetOpen() *PprofResponse_Open { + if x, ok := x.GetEvent().(*PprofResponse_Open_); ok { + return x.Open } return nil } +func (x *PprofResponse) GetInput() *PprofResponse_Input { + if x, ok := x.GetEvent().(*PprofResponse_Input_); ok { + return x.Input + } + return nil +} + +func (x *PprofResponse) GetEof() *empty.Empty { + if x, ok := x.GetEvent().(*PprofResponse_Eof); ok { + return x.Eof + } + return nil +} + +type isPprofResponse_Event interface { + isPprofResponse_Event() +} + +type PprofResponse_Open_ struct { + Open *PprofResponse_Open `protobuf:"bytes,1,opt,name=open,proto3,oneof"` +} + +type PprofResponse_Input_ struct { + Input *PprofResponse_Input `protobuf:"bytes,2,opt,name=input,proto3,oneof"` +} + +type PprofResponse_Eof struct { + Eof *empty.Empty `protobuf:"bytes,3,opt,name=eof,proto3,oneof"` +} + +func (*PprofResponse_Open_) isPprofResponse_Event() {} + +func (*PprofResponse_Input_) isPprofResponse_Event() {} + +func (*PprofResponse_Eof) isPprofResponse_Event() {} + type StatusResponse_Fork struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1006,6 +1045,108 @@ func (x *StatusResponse_Syncing) GetCurrentBlock() int64 { return 0 } +type PprofResponse_Open struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Headers map[string]string `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` +} + +func (x *PprofResponse_Open) Reset() { + *x = PprofResponse_Open{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PprofResponse_Open) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PprofResponse_Open) ProtoMessage() {} + +func (x *PprofResponse_Open) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PprofResponse_Open.ProtoReflect.Descriptor instead. +func (*PprofResponse_Open) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{14, 0} +} + +func (x *PprofResponse_Open) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +func (x *PprofResponse_Open) GetSize() int64 { + if x != nil { + return x.Size + } + return 0 +} + +type PprofResponse_Input struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *PprofResponse_Input) Reset() { + *x = PprofResponse_Input{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PprofResponse_Input) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PprofResponse_Input) ProtoMessage() {} + +func (x *PprofResponse_Input) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PprofResponse_Input.ProtoReflect.Descriptor instead. +func (*PprofResponse_Input) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{14, 1} +} + +func (x *PprofResponse_Input) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + var File_command_server_proto_server_proto protoreflect.FileDescriptor var file_command_server_proto_server_proto_rawDesc = []byte{ @@ -1093,47 +1234,60 @@ var file_command_server_proto_server_proto_rawDesc = []byte{ 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, - 0x45, 0x10, 0x02, 0x22, 0xa2, 0x01, 0x0a, 0x0d, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, - 0x3b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xc4, 0x03, 0x0a, 0x03, 0x42, 0x6f, 0x72, - 0x12, 0x32, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, - 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, 0x73, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, - 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, - 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, - 0x0c, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, - 0x17, 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x45, 0x10, 0x02, 0x22, 0xe1, 0x02, 0x0a, 0x0d, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, + 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x48, 0x00, + 0x52, 0x04, 0x6f, 0x70, 0x65, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, + 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x70, 0x75, + 0x74, 0x48, 0x00, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x2a, 0x0a, 0x03, 0x65, 0x6f, + 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, + 0x00, 0x52, 0x03, 0x65, 0x6f, 0x66, 0x1a, 0x98, 0x01, 0x0a, 0x04, 0x4f, 0x70, 0x65, 0x6e, 0x12, + 0x40, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x2e, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x1a, 0x1b, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x07, + 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x32, 0xc6, 0x03, 0x0a, 0x03, 0x42, 0x6f, 0x72, 0x12, + 0x34, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, + 0x64, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, + 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, + 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x12, 0x1a, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, + 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x17, 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1149,7 +1303,7 @@ func file_command_server_proto_server_proto_rawDescGZIP() []byte { } var file_command_server_proto_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_command_server_proto_server_proto_goTypes = []interface{}{ (PprofRequest_Type)(0), // 0: proto.PprofRequest.Type (*PeersAddRequest)(nil), // 1: proto.PeersAddRequest @@ -1169,8 +1323,10 @@ var file_command_server_proto_server_proto_goTypes = []interface{}{ (*PprofResponse)(nil), // 15: proto.PprofResponse (*StatusResponse_Fork)(nil), // 16: proto.StatusResponse.Fork (*StatusResponse_Syncing)(nil), // 17: proto.StatusResponse.Syncing - nil, // 18: proto.PprofResponse.HeadersEntry - (*empty.Empty)(nil), // 19: google.protobuf.Empty + (*PprofResponse_Open)(nil), // 18: proto.PprofResponse.Open + (*PprofResponse_Input)(nil), // 19: proto.PprofResponse.Input + nil, // 20: proto.PprofResponse.Open.HeadersEntry + (*empty.Empty)(nil), // 21: google.protobuf.Empty } var file_command_server_proto_server_proto_depIdxs = []int32{ 9, // 0: proto.PeersListResponse.peers:type_name -> proto.Peer @@ -1180,26 +1336,29 @@ var file_command_server_proto_server_proto_depIdxs = []int32{ 17, // 4: proto.StatusResponse.syncing:type_name -> proto.StatusResponse.Syncing 16, // 5: proto.StatusResponse.forks:type_name -> proto.StatusResponse.Fork 0, // 6: proto.PprofRequest.type:type_name -> proto.PprofRequest.Type - 18, // 7: proto.PprofResponse.headers:type_name -> proto.PprofResponse.HeadersEntry - 14, // 8: proto.Bor.Pprof:input_type -> proto.PprofRequest - 1, // 9: proto.Bor.PeersAdd:input_type -> proto.PeersAddRequest - 3, // 10: proto.Bor.PeersRemove:input_type -> proto.PeersRemoveRequest - 5, // 11: proto.Bor.PeersList:input_type -> proto.PeersListRequest - 7, // 12: proto.Bor.PeersStatus:input_type -> proto.PeersStatusRequest - 10, // 13: proto.Bor.ChainSetHead:input_type -> proto.ChainSetHeadRequest - 19, // 14: proto.Bor.Status:input_type -> google.protobuf.Empty - 15, // 15: proto.Bor.Pprof:output_type -> proto.PprofResponse - 2, // 16: proto.Bor.PeersAdd:output_type -> proto.PeersAddResponse - 4, // 17: proto.Bor.PeersRemove:output_type -> proto.PeersRemoveResponse - 6, // 18: proto.Bor.PeersList:output_type -> proto.PeersListResponse - 8, // 19: proto.Bor.PeersStatus:output_type -> proto.PeersStatusResponse - 11, // 20: proto.Bor.ChainSetHead:output_type -> proto.ChainSetHeadResponse - 12, // 21: proto.Bor.Status:output_type -> proto.StatusResponse - 15, // [15:22] is the sub-list for method output_type - 8, // [8:15] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 18, // 7: proto.PprofResponse.open:type_name -> proto.PprofResponse.Open + 19, // 8: proto.PprofResponse.input:type_name -> proto.PprofResponse.Input + 21, // 9: proto.PprofResponse.eof:type_name -> google.protobuf.Empty + 20, // 10: proto.PprofResponse.Open.headers:type_name -> proto.PprofResponse.Open.HeadersEntry + 14, // 11: proto.Bor.Pprof:input_type -> proto.PprofRequest + 1, // 12: proto.Bor.PeersAdd:input_type -> proto.PeersAddRequest + 3, // 13: proto.Bor.PeersRemove:input_type -> proto.PeersRemoveRequest + 5, // 14: proto.Bor.PeersList:input_type -> proto.PeersListRequest + 7, // 15: proto.Bor.PeersStatus:input_type -> proto.PeersStatusRequest + 10, // 16: proto.Bor.ChainSetHead:input_type -> proto.ChainSetHeadRequest + 21, // 17: proto.Bor.Status:input_type -> google.protobuf.Empty + 15, // 18: proto.Bor.Pprof:output_type -> proto.PprofResponse + 2, // 19: proto.Bor.PeersAdd:output_type -> proto.PeersAddResponse + 4, // 20: proto.Bor.PeersRemove:output_type -> proto.PeersRemoveResponse + 6, // 21: proto.Bor.PeersList:output_type -> proto.PeersListResponse + 8, // 22: proto.Bor.PeersStatus:output_type -> proto.PeersStatusResponse + 11, // 23: proto.Bor.ChainSetHead:output_type -> proto.ChainSetHeadResponse + 12, // 24: proto.Bor.Status:output_type -> proto.StatusResponse + 18, // [18:25] is the sub-list for method output_type + 11, // [11:18] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_command_server_proto_server_proto_init() } @@ -1412,6 +1571,35 @@ func file_command_server_proto_server_proto_init() { return nil } } + file_command_server_proto_server_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofResponse_Open); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofResponse_Input); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_command_server_proto_server_proto_msgTypes[14].OneofWrappers = []interface{}{ + (*PprofResponse_Open_)(nil), + (*PprofResponse_Input_)(nil), + (*PprofResponse_Eof)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1419,7 +1607,7 @@ func file_command_server_proto_server_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_command_server_proto_server_proto_rawDesc, NumEnums: 1, - NumMessages: 18, + NumMessages: 20, NumExtensions: 0, NumServices: 1, }, diff --git a/command/server/proto/server.proto b/command/server/proto/server.proto index 96b14ccf750f57948800206a34c8c8d0b1d1f4fd..de4fb13dd403ee89201b59fac0579e2ed21fd30a 100644 --- a/command/server/proto/server.proto +++ b/command/server/proto/server.proto @@ -7,7 +7,7 @@ import "google/protobuf/empty.proto"; option go_package = "/command/server/proto"; service Bor { - rpc Pprof(PprofRequest) returns (PprofResponse); + rpc Pprof(PprofRequest) returns (stream PprofResponse); rpc PeersAdd(PeersAddRequest) returns (PeersAddResponse); @@ -112,6 +112,18 @@ message PprofRequest { } message PprofResponse { - string payload = 1; - map<string, string> headers = 2; + oneof event { + Open open = 1; + Input input = 2; + google.protobuf.Empty eof = 3; + } + + message Open { + map<string, string> headers = 1; + int64 size = 2; + } + + message Input { + bytes data = 1; + } } diff --git a/command/server/proto/server_grpc.pb.go b/command/server/proto/server_grpc.pb.go index e385a16968d2ffd579b9bdae49fcc18baa74826f..7c2540d772fc741e401c622cad6099e1767fc8e5 100644 --- a/command/server/proto/server_grpc.pb.go +++ b/command/server/proto/server_grpc.pb.go @@ -19,7 +19,7 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type BorClient interface { - Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) + Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (Bor_PprofClient, error) PeersAdd(ctx context.Context, in *PeersAddRequest, opts ...grpc.CallOption) (*PeersAddResponse, error) PeersRemove(ctx context.Context, in *PeersRemoveRequest, opts ...grpc.CallOption) (*PeersRemoveResponse, error) PeersList(ctx context.Context, in *PeersListRequest, opts ...grpc.CallOption) (*PeersListResponse, error) @@ -36,13 +36,36 @@ func NewBorClient(cc grpc.ClientConnInterface) BorClient { return &borClient{cc} } -func (c *borClient) Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) { - out := new(PprofResponse) - err := c.cc.Invoke(ctx, "/proto.Bor/Pprof", in, out, opts...) +func (c *borClient) Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (Bor_PprofClient, error) { + stream, err := c.cc.NewStream(ctx, &Bor_ServiceDesc.Streams[0], "/proto.Bor/Pprof", opts...) if err != nil { return nil, err } - return out, nil + x := &borPprofClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Bor_PprofClient interface { + Recv() (*PprofResponse, error) + grpc.ClientStream +} + +type borPprofClient struct { + grpc.ClientStream +} + +func (x *borPprofClient) Recv() (*PprofResponse, error) { + m := new(PprofResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil } func (c *borClient) PeersAdd(ctx context.Context, in *PeersAddRequest, opts ...grpc.CallOption) (*PeersAddResponse, error) { @@ -103,7 +126,7 @@ func (c *borClient) Status(ctx context.Context, in *empty.Empty, opts ...grpc.Ca // All implementations must embed UnimplementedBorServer // for forward compatibility type BorServer interface { - Pprof(context.Context, *PprofRequest) (*PprofResponse, error) + Pprof(*PprofRequest, Bor_PprofServer) error PeersAdd(context.Context, *PeersAddRequest) (*PeersAddResponse, error) PeersRemove(context.Context, *PeersRemoveRequest) (*PeersRemoveResponse, error) PeersList(context.Context, *PeersListRequest) (*PeersListResponse, error) @@ -117,8 +140,8 @@ type BorServer interface { type UnimplementedBorServer struct { } -func (UnimplementedBorServer) Pprof(context.Context, *PprofRequest) (*PprofResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Pprof not implemented") +func (UnimplementedBorServer) Pprof(*PprofRequest, Bor_PprofServer) error { + return status.Errorf(codes.Unimplemented, "method Pprof not implemented") } func (UnimplementedBorServer) PeersAdd(context.Context, *PeersAddRequest) (*PeersAddResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method PeersAdd not implemented") @@ -151,22 +174,25 @@ func RegisterBorServer(s grpc.ServiceRegistrar, srv BorServer) { s.RegisterService(&Bor_ServiceDesc, srv) } -func _Bor_Pprof_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PprofRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(BorServer).Pprof(ctx, in) +func _Bor_Pprof_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(PprofRequest) + if err := stream.RecvMsg(m); err != nil { + return err } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/proto.Bor/Pprof", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BorServer).Pprof(ctx, req.(*PprofRequest)) - } - return interceptor(ctx, in, info, handler) + return srv.(BorServer).Pprof(m, &borPprofServer{stream}) +} + +type Bor_PprofServer interface { + Send(*PprofResponse) error + grpc.ServerStream +} + +type borPprofServer struct { + grpc.ServerStream +} + +func (x *borPprofServer) Send(m *PprofResponse) error { + return x.ServerStream.SendMsg(m) } func _Bor_PeersAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { @@ -284,10 +310,6 @@ var Bor_ServiceDesc = grpc.ServiceDesc{ ServiceName: "proto.Bor", HandlerType: (*BorServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "Pprof", - Handler: _Bor_Pprof_Handler, - }, { MethodName: "PeersAdd", Handler: _Bor_PeersAdd_Handler, @@ -313,6 +335,12 @@ var Bor_ServiceDesc = grpc.ServiceDesc{ Handler: _Bor_Status_Handler, }, }, - Streams: []grpc.StreamDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Pprof", + Handler: _Bor_Pprof_Handler, + ServerStreams: true, + }, + }, Metadata: "command/server/proto/server.proto", } diff --git a/command/server/service.go b/command/server/service.go index 30df05857de28c362ea30d403bbdddfbb11fddb9..fe70029aa9741b1eb4b520de3d037ba94a3f61fe 100644 --- a/command/server/service.go +++ b/command/server/service.go @@ -2,7 +2,6 @@ package server import ( "context" - "encoding/hex" "fmt" "math/big" "reflect" @@ -13,14 +12,17 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/enode" + gproto "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes/empty" + grpc_net_conn "github.com/mitchellh/go-grpc-net-conn" ) -func (s *Server) Pprof(ctx context.Context, req *proto.PprofRequest) (*proto.PprofResponse, error) { +func (s *Server) Pprof(req *proto.PprofRequest, stream proto.Bor_PprofServer) error { var payload []byte var headers map[string]string var err error + ctx := context.Background() switch req.Type { case proto.PprofRequest_CPU: payload, headers, err = pprof.CPUProfile(ctx, int(req.Seconds)) @@ -30,14 +32,42 @@ func (s *Server) Pprof(ctx context.Context, req *proto.PprofRequest) (*proto.Ppr payload, headers, err = pprof.Profile(req.Profile, 0, 0) } if err != nil { - return nil, err + return err } - resp := &proto.PprofResponse{ - Payload: hex.EncodeToString(payload), - Headers: headers, + // open the stream and send the headers + err = stream.Send(&proto.PprofResponse{ + Event: &proto.PprofResponse_Open_{ + Open: &proto.PprofResponse_Open{ + Headers: headers, + Size: int64(len(payload)), + }, + }, + }) + if err != nil { + return err } - return resp, nil + + // Wrap our conn around the response. + conn := &grpc_net_conn.Conn{ + Stream: stream, + Request: &proto.PprofResponse_Input{}, + Encode: grpc_net_conn.SimpleEncoder(func(msg gproto.Message) *[]byte { + return &msg.(*proto.PprofResponse_Input).Data + }), + } + if _, err := conn.Write(payload); err != nil { + return err + } + + // send the eof + err = stream.Send(&proto.PprofResponse{ + Event: &proto.PprofResponse_Eof{}, + }) + if err != nil { + return err + } + return nil } func (s *Server) PeersAdd(ctx context.Context, req *proto.PeersAddRequest) (*proto.PeersAddResponse, error) { diff --git a/go.mod b/go.mod index c7718bbbbd81eef006840236c105b02feae452be..8ffc4d00d065832c12c36e8579b1a974e5a04f41 100644 --- a/go.mod +++ b/go.mod @@ -53,6 +53,7 @@ require ( github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-isatty v0.0.12 github.com/mitchellh/cli v1.1.2 + github.com/mitchellh/go-grpc-net-conn v0.0.0-20200427190222-eb030e4876f0 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 diff --git a/go.sum b/go.sum index 96d83f3fcc925fd8f3034f8c4a49a7cbe5dcaca2..4fc75e79b09c93496ee4b6e9e91f61ac50d122ce 100644 --- a/go.sum +++ b/go.sum @@ -375,6 +375,8 @@ github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw= github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-grpc-net-conn v0.0.0-20200427190222-eb030e4876f0 h1:oZuel4h7224ILBLg2SlTxdaMYXDyqcVfL4Cg1PJQHZs= +github.com/mitchellh/go-grpc-net-conn v0.0.0-20200427190222-eb030e4876f0/go.mod h1:ZCzL0JMR6qfm7VrDC8HGwVtPA8D2Ijc/edUSBw58x94= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= @@ -732,6 +734,7 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= diff --git a/scripts/tools-protobuf.sh b/scripts/tools-protobuf.sh old mode 100644 new mode 100755 index 020639f9d9406760d14376afa7023bfdc7c1093a..fe03cab3cb4a1d746099c08368ae348d4cbf8927 --- a/scripts/tools-protobuf.sh +++ b/scripts/tools-protobuf.sh @@ -1,5 +1,16 @@ -curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/protoc-3.12.0-linux-x86_64.zip -sudo unzip protoc-3.12.0-linux-x86_64.zip -d /usr/local/bin +#!/bin/bash +# Install protobuf +PROTOC_ZIP=protoc-3.12.0-linux-x86_64.zip +curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/$PROTOC_ZIP +sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc +sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*' +rm -f $PROTOC_ZIP + +# Change permissions to use the binary +sudo chmod 755 -R /usr/local/bin/protoc +sudo chmod 755 -R /usr/local/include + +# Install golang extensions (DO NOT CHANGE THE VERSIONS) go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.25.0 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1