diff --git a/api/proto/flows.pb.go b/api/proto/flows.pb.go index c302feb2f9..2a4e73beb8 100644 --- a/api/proto/flows.pb.go +++ b/api/proto/flows.pb.go @@ -19,6 +19,69 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type ContainerMemberStats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + UncompressedSize uint64 `protobuf:"varint,2,opt,name=uncompressed_size,json=uncompressedSize,proto3" json:"uncompressed_size,omitempty"` + CompressedSize uint64 `protobuf:"varint,3,opt,name=compressed_size,json=compressedSize,proto3" json:"compressed_size,omitempty"` +} + +func (x *ContainerMemberStats) Reset() { + *x = ContainerMemberStats{} + if protoimpl.UnsafeEnabled { + mi := &file_flows_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContainerMemberStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContainerMemberStats) ProtoMessage() {} + +func (x *ContainerMemberStats) ProtoReflect() protoreflect.Message { + mi := &file_flows_proto_msgTypes[0] + 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 ContainerMemberStats.ProtoReflect.Descriptor instead. +func (*ContainerMemberStats) Descriptor() ([]byte, []int) { + return file_flows_proto_rawDescGZIP(), []int{0} +} + +func (x *ContainerMemberStats) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ContainerMemberStats) GetUncompressedSize() uint64 { + if x != nil { + return x.UncompressedSize + } + return 0 +} + +func (x *ContainerMemberStats) GetCompressedSize() uint64 { + if x != nil { + return x.CompressedSize + } + return 0 +} + // Stats about exported containers type ContainerStats struct { state protoimpl.MessageState @@ -46,13 +109,14 @@ type ContainerStats struct { Type string `protobuf:"bytes,10,opt,name=type,proto3" json:"type,omitempty"` Error string `protobuf:"bytes,11,opt,name=error,proto3" json:"error,omitempty"` // A string representation of the file path - VfsPath string `protobuf:"bytes,12,opt,name=vfs_path,json=vfsPath,proto3" json:"vfs_path,omitempty"` + VfsPath string `protobuf:"bytes,12,opt,name=vfs_path,json=vfsPath,proto3" json:"vfs_path,omitempty"` + ActiveMembers []*ContainerMemberStats `protobuf:"bytes,13,rep,name=active_members,json=activeMembers,proto3" json:"active_members,omitempty"` } func (x *ContainerStats) Reset() { *x = ContainerStats{} if protoimpl.UnsafeEnabled { - mi := &file_flows_proto_msgTypes[0] + mi := &file_flows_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -65,7 +129,7 @@ func (x *ContainerStats) String() string { func (*ContainerStats) ProtoMessage() {} func (x *ContainerStats) ProtoReflect() protoreflect.Message { - mi := &file_flows_proto_msgTypes[0] + mi := &file_flows_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -78,7 +142,7 @@ func (x *ContainerStats) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerStats.ProtoReflect.Descriptor instead. func (*ContainerStats) Descriptor() ([]byte, []int) { - return file_flows_proto_rawDescGZIP(), []int{0} + return file_flows_proto_rawDescGZIP(), []int{1} } func (x *ContainerStats) GetTimestamp() uint64 { @@ -165,6 +229,13 @@ func (x *ContainerStats) GetVfsPath() string { return "" } +func (x *ContainerStats) GetActiveMembers() []*ContainerMemberStats { + if x != nil { + return x.ActiveMembers + } + return nil +} + type AvailableDownloadFile struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -183,7 +254,7 @@ type AvailableDownloadFile struct { func (x *AvailableDownloadFile) Reset() { *x = AvailableDownloadFile{} if protoimpl.UnsafeEnabled { - mi := &file_flows_proto_msgTypes[1] + mi := &file_flows_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -196,7 +267,7 @@ func (x *AvailableDownloadFile) String() string { func (*AvailableDownloadFile) ProtoMessage() {} func (x *AvailableDownloadFile) ProtoReflect() protoreflect.Message { - mi := &file_flows_proto_msgTypes[1] + mi := &file_flows_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -209,7 +280,7 @@ func (x *AvailableDownloadFile) ProtoReflect() protoreflect.Message { // Deprecated: Use AvailableDownloadFile.ProtoReflect.Descriptor instead. func (*AvailableDownloadFile) Descriptor() ([]byte, []int) { - return file_flows_proto_rawDescGZIP(), []int{1} + return file_flows_proto_rawDescGZIP(), []int{2} } func (x *AvailableDownloadFile) GetName() string { @@ -272,7 +343,7 @@ type AvailableDownloads struct { func (x *AvailableDownloads) Reset() { *x = AvailableDownloads{} if protoimpl.UnsafeEnabled { - mi := &file_flows_proto_msgTypes[2] + mi := &file_flows_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -285,7 +356,7 @@ func (x *AvailableDownloads) String() string { func (*AvailableDownloads) ProtoMessage() {} func (x *AvailableDownloads) ProtoReflect() protoreflect.Message { - mi := &file_flows_proto_msgTypes[2] + mi := &file_flows_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -298,7 +369,7 @@ func (x *AvailableDownloads) ProtoReflect() protoreflect.Message { // Deprecated: Use AvailableDownloads.ProtoReflect.Descriptor instead. func (*AvailableDownloads) Descriptor() ([]byte, []int) { - return file_flows_proto_rawDescGZIP(), []int{2} + return file_flows_proto_rawDescGZIP(), []int{3} } func (x *AvailableDownloads) GetFiles() []*AvailableDownloadFile { @@ -320,7 +391,7 @@ type FlowDetails struct { func (x *FlowDetails) Reset() { *x = FlowDetails{} if protoimpl.UnsafeEnabled { - mi := &file_flows_proto_msgTypes[3] + mi := &file_flows_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -333,7 +404,7 @@ func (x *FlowDetails) String() string { func (*FlowDetails) ProtoMessage() {} func (x *FlowDetails) ProtoReflect() protoreflect.Message { - mi := &file_flows_proto_msgTypes[3] + mi := &file_flows_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -346,7 +417,7 @@ func (x *FlowDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use FlowDetails.ProtoReflect.Descriptor instead. func (*FlowDetails) Descriptor() ([]byte, []int) { - return file_flows_proto_rawDescGZIP(), []int{3} + return file_flows_proto_rawDescGZIP(), []int{4} } func (x *FlowDetails) GetContext() *proto.ArtifactCollectorContext { @@ -380,7 +451,7 @@ type ApiFlowRequestDetails struct { func (x *ApiFlowRequestDetails) Reset() { *x = ApiFlowRequestDetails{} if protoimpl.UnsafeEnabled { - mi := &file_flows_proto_msgTypes[4] + mi := &file_flows_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -393,7 +464,7 @@ func (x *ApiFlowRequestDetails) String() string { func (*ApiFlowRequestDetails) ProtoMessage() {} func (x *ApiFlowRequestDetails) ProtoReflect() protoreflect.Message { - mi := &file_flows_proto_msgTypes[4] + mi := &file_flows_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -406,7 +477,7 @@ func (x *ApiFlowRequestDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use ApiFlowRequestDetails.ProtoReflect.Descriptor instead. func (*ApiFlowRequestDetails) Descriptor() ([]byte, []int) { - return file_flows_proto_rawDescGZIP(), []int{4} + return file_flows_proto_rawDescGZIP(), []int{5} } func (x *ApiFlowRequestDetails) GetItems() []*proto1.VeloMessage { @@ -441,7 +512,7 @@ type ApiFlowResultDetails struct { func (x *ApiFlowResultDetails) Reset() { *x = ApiFlowResultDetails{} if protoimpl.UnsafeEnabled { - mi := &file_flows_proto_msgTypes[5] + mi := &file_flows_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -454,7 +525,7 @@ func (x *ApiFlowResultDetails) String() string { func (*ApiFlowResultDetails) ProtoMessage() {} func (x *ApiFlowResultDetails) ProtoReflect() protoreflect.Message { - mi := &file_flows_proto_msgTypes[5] + mi := &file_flows_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -467,7 +538,7 @@ func (x *ApiFlowResultDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use ApiFlowResultDetails.ProtoReflect.Descriptor instead. func (*ApiFlowResultDetails) Descriptor() ([]byte, []int) { - return file_flows_proto_rawDescGZIP(), []int{5} + return file_flows_proto_rawDescGZIP(), []int{6} } func (x *ApiFlowResultDetails) GetItems() []*proto1.VeloMessage { @@ -488,7 +559,7 @@ type ApiFlowLogDetails struct { func (x *ApiFlowLogDetails) Reset() { *x = ApiFlowLogDetails{} if protoimpl.UnsafeEnabled { - mi := &file_flows_proto_msgTypes[6] + mi := &file_flows_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -501,7 +572,7 @@ func (x *ApiFlowLogDetails) String() string { func (*ApiFlowLogDetails) ProtoMessage() {} func (x *ApiFlowLogDetails) ProtoReflect() protoreflect.Message { - mi := &file_flows_proto_msgTypes[6] + mi := &file_flows_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -514,7 +585,7 @@ func (x *ApiFlowLogDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use ApiFlowLogDetails.ProtoReflect.Descriptor instead. func (*ApiFlowLogDetails) Descriptor() ([]byte, []int) { - return file_flows_proto_rawDescGZIP(), []int{6} + return file_flows_proto_rawDescGZIP(), []int{7} } func (x *ApiFlowLogDetails) GetItems() []*proto1.LogMessage { @@ -541,7 +612,7 @@ type ApiFlowRequest struct { func (x *ApiFlowRequest) Reset() { *x = ApiFlowRequest{} if protoimpl.UnsafeEnabled { - mi := &file_flows_proto_msgTypes[7] + mi := &file_flows_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -554,7 +625,7 @@ func (x *ApiFlowRequest) String() string { func (*ApiFlowRequest) ProtoMessage() {} func (x *ApiFlowRequest) ProtoReflect() protoreflect.Message { - mi := &file_flows_proto_msgTypes[7] + mi := &file_flows_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -567,7 +638,7 @@ func (x *ApiFlowRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApiFlowRequest.ProtoReflect.Descriptor instead. func (*ApiFlowRequest) Descriptor() ([]byte, []int) { - return file_flows_proto_rawDescGZIP(), []int{7} + return file_flows_proto_rawDescGZIP(), []int{8} } func (x *ApiFlowRequest) GetClientId() string { @@ -624,7 +695,7 @@ type ApiFlowResponse struct { func (x *ApiFlowResponse) Reset() { *x = ApiFlowResponse{} if protoimpl.UnsafeEnabled { - mi := &file_flows_proto_msgTypes[8] + mi := &file_flows_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -637,7 +708,7 @@ func (x *ApiFlowResponse) String() string { func (*ApiFlowResponse) ProtoMessage() {} func (x *ApiFlowResponse) ProtoReflect() protoreflect.Message { - mi := &file_flows_proto_msgTypes[8] + mi := &file_flows_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -650,7 +721,7 @@ func (x *ApiFlowResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApiFlowResponse.ProtoReflect.Descriptor instead. func (*ApiFlowResponse) Descriptor() ([]byte, []int) { - return file_flows_proto_rawDescGZIP(), []int{8} + return file_flows_proto_rawDescGZIP(), []int{9} } func (x *ApiFlowResponse) GetTotal() uint64 { @@ -675,100 +746,112 @@ var file_flows_proto_rawDesc = []byte{ 0x74, 0x6f, 0x2f, 0x6a, 0x6f, 0x62, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0xd6, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, - 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, - 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, - 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, - 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6d, - 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x22, 0xc4, 0x01, 0x0a, - 0x15, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, - 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x73, 0x22, 0x48, 0x0a, 0x12, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, - 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x05, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x94, 0x01, - 0x0a, 0x0b, 0x46, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x39, 0x0a, - 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, - 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x4a, 0x0a, 0x13, 0x61, 0x76, 0x61, 0x69, - 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, - 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x76, + 0x6f, 0x74, 0x6f, 0x22, 0x80, 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x2b, 0x0a, 0x11, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x75, 0x6e, 0x63, + 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x27, 0x0a, + 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x9a, 0x04, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, + 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x70, + 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, + 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, + 0x61, 0x73, 0x68, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x66, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x66, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x42, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x22, 0xc4, 0x01, 0x0a, 0x15, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x48, 0x0a, 0x12, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, - 0x52, 0x12, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, - 0x6f, 0x61, 0x64, 0x73, 0x22, 0x77, 0x0a, 0x15, 0x41, 0x70, 0x69, 0x46, 0x6c, 0x6f, 0x77, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x28, 0x0a, - 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, + 0x12, 0x32, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x22, 0x94, 0x01, 0x0a, 0x0b, 0x46, 0x6c, 0x6f, 0x77, 0x44, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, + 0x4a, 0x0a, 0x13, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x6f, 0x77, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x6f, + 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x52, 0x12, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x22, 0x77, 0x0a, 0x15, 0x41, + 0x70, 0x69, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x12, 0x28, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, + 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x66, + 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6c, + 0x6f, 0x77, 0x49, 0x64, 0x22, 0x40, 0x0a, 0x14, 0x41, 0x70, 0x69, 0x46, 0x6c, 0x6f, 0x77, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x28, 0x0a, 0x05, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3c, 0x0a, 0x11, 0x41, 0x70, 0x69, 0x46, 0x6c, 0x6f, + 0x77, 0x4c, 0x6f, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x27, 0x0a, 0x05, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x22, 0xbb, 0x01, 0x0a, 0x0e, 0x41, 0x70, 0x69, 0x46, 0x6c, 0x6f, 0x77, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x22, 0x40, 0x0a, - 0x14, 0x41, 0x70, 0x69, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x28, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x65, 0x6c, - 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, - 0x3c, 0x0a, 0x11, 0x41, 0x70, 0x69, 0x46, 0x6c, 0x6f, 0x77, 0x4c, 0x6f, 0x67, 0x44, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x12, 0x27, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0xbb, 0x01, - 0x0a, 0x0e, 0x41, 0x70, 0x69, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, - 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, - 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, - 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x22, 0x5e, 0x0a, 0x0f, 0x41, - 0x70, 0x69, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x35, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x77, - 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, - 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x22, 0x5e, 0x0a, 0x0f, 0x41, 0x70, 0x69, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x35, 0x0a, 0x05, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x6c, 0x6f, 0x63, 0x69, + 0x64, 0x65, 0x78, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x76, + 0x65, 0x6c, 0x6f, 0x63, 0x69, 0x72, 0x61, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -783,35 +866,37 @@ func file_flows_proto_rawDescGZIP() []byte { return file_flows_proto_rawDescData } -var file_flows_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_flows_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_flows_proto_goTypes = []interface{}{ - (*ContainerStats)(nil), // 0: proto.ContainerStats - (*AvailableDownloadFile)(nil), // 1: proto.AvailableDownloadFile - (*AvailableDownloads)(nil), // 2: proto.AvailableDownloads - (*FlowDetails)(nil), // 3: proto.FlowDetails - (*ApiFlowRequestDetails)(nil), // 4: proto.ApiFlowRequestDetails - (*ApiFlowResultDetails)(nil), // 5: proto.ApiFlowResultDetails - (*ApiFlowLogDetails)(nil), // 6: proto.ApiFlowLogDetails - (*ApiFlowRequest)(nil), // 7: proto.ApiFlowRequest - (*ApiFlowResponse)(nil), // 8: proto.ApiFlowResponse - (*proto.ArtifactCollectorContext)(nil), // 9: proto.ArtifactCollectorContext - (*proto1.VeloMessage)(nil), // 10: proto.VeloMessage - (*proto1.LogMessage)(nil), // 11: proto.LogMessage + (*ContainerMemberStats)(nil), // 0: proto.ContainerMemberStats + (*ContainerStats)(nil), // 1: proto.ContainerStats + (*AvailableDownloadFile)(nil), // 2: proto.AvailableDownloadFile + (*AvailableDownloads)(nil), // 3: proto.AvailableDownloads + (*FlowDetails)(nil), // 4: proto.FlowDetails + (*ApiFlowRequestDetails)(nil), // 5: proto.ApiFlowRequestDetails + (*ApiFlowResultDetails)(nil), // 6: proto.ApiFlowResultDetails + (*ApiFlowLogDetails)(nil), // 7: proto.ApiFlowLogDetails + (*ApiFlowRequest)(nil), // 8: proto.ApiFlowRequest + (*ApiFlowResponse)(nil), // 9: proto.ApiFlowResponse + (*proto.ArtifactCollectorContext)(nil), // 10: proto.ArtifactCollectorContext + (*proto1.VeloMessage)(nil), // 11: proto.VeloMessage + (*proto1.LogMessage)(nil), // 12: proto.LogMessage } var file_flows_proto_depIdxs = []int32{ - 0, // 0: proto.AvailableDownloadFile.stats:type_name -> proto.ContainerStats - 1, // 1: proto.AvailableDownloads.files:type_name -> proto.AvailableDownloadFile - 9, // 2: proto.FlowDetails.context:type_name -> proto.ArtifactCollectorContext - 2, // 3: proto.FlowDetails.available_downloads:type_name -> proto.AvailableDownloads - 10, // 4: proto.ApiFlowRequestDetails.items:type_name -> proto.VeloMessage - 10, // 5: proto.ApiFlowResultDetails.items:type_name -> proto.VeloMessage - 11, // 6: proto.ApiFlowLogDetails.items:type_name -> proto.LogMessage - 9, // 7: proto.ApiFlowResponse.items:type_name -> proto.ArtifactCollectorContext - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] 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 + 0, // 0: proto.ContainerStats.active_members:type_name -> proto.ContainerMemberStats + 1, // 1: proto.AvailableDownloadFile.stats:type_name -> proto.ContainerStats + 2, // 2: proto.AvailableDownloads.files:type_name -> proto.AvailableDownloadFile + 10, // 3: proto.FlowDetails.context:type_name -> proto.ArtifactCollectorContext + 3, // 4: proto.FlowDetails.available_downloads:type_name -> proto.AvailableDownloads + 11, // 5: proto.ApiFlowRequestDetails.items:type_name -> proto.VeloMessage + 11, // 6: proto.ApiFlowResultDetails.items:type_name -> proto.VeloMessage + 12, // 7: proto.ApiFlowLogDetails.items:type_name -> proto.LogMessage + 10, // 8: proto.ApiFlowResponse.items:type_name -> proto.ArtifactCollectorContext + 9, // [9:9] is the sub-list for method output_type + 9, // [9:9] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_flows_proto_init() } @@ -821,7 +906,7 @@ func file_flows_proto_init() { } if !protoimpl.UnsafeEnabled { file_flows_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerStats); i { + switch v := v.(*ContainerMemberStats); i { case 0: return &v.state case 1: @@ -833,7 +918,7 @@ func file_flows_proto_init() { } } file_flows_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AvailableDownloadFile); i { + switch v := v.(*ContainerStats); i { case 0: return &v.state case 1: @@ -845,7 +930,7 @@ func file_flows_proto_init() { } } file_flows_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AvailableDownloads); i { + switch v := v.(*AvailableDownloadFile); i { case 0: return &v.state case 1: @@ -857,7 +942,7 @@ func file_flows_proto_init() { } } file_flows_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FlowDetails); i { + switch v := v.(*AvailableDownloads); i { case 0: return &v.state case 1: @@ -869,7 +954,7 @@ func file_flows_proto_init() { } } file_flows_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiFlowRequestDetails); i { + switch v := v.(*FlowDetails); i { case 0: return &v.state case 1: @@ -881,7 +966,7 @@ func file_flows_proto_init() { } } file_flows_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiFlowResultDetails); i { + switch v := v.(*ApiFlowRequestDetails); i { case 0: return &v.state case 1: @@ -893,7 +978,7 @@ func file_flows_proto_init() { } } file_flows_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiFlowLogDetails); i { + switch v := v.(*ApiFlowResultDetails); i { case 0: return &v.state case 1: @@ -905,7 +990,7 @@ func file_flows_proto_init() { } } file_flows_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiFlowRequest); i { + switch v := v.(*ApiFlowLogDetails); i { case 0: return &v.state case 1: @@ -917,6 +1002,18 @@ func file_flows_proto_init() { } } file_flows_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApiFlowRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_flows_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApiFlowResponse); i { case 0: return &v.state @@ -935,7 +1032,7 @@ func file_flows_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_flows_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 10, NumExtensions: 0, NumServices: 0, }, diff --git a/api/proto/flows.proto b/api/proto/flows.proto index 22dff34530..fdc231f29b 100644 --- a/api/proto/flows.proto +++ b/api/proto/flows.proto @@ -7,6 +7,12 @@ package proto; option go_package = "www.velocidex.com/golang/velociraptor/api/proto"; +message ContainerMemberStats { + string name = 1; + uint64 uncompressed_size = 2; + uint64 compressed_size = 3; +} + // Stats about exported containers message ContainerStats { // Seconds since epoch @@ -39,6 +45,9 @@ message ContainerStats { // A string representation of the file path string vfs_path = 12; + + repeated ContainerMemberStats active_members = 13; + } message AvailableDownloadFile { diff --git a/gui/velociraptor/src/components/notebooks/downloads.jsx b/gui/velociraptor/src/components/notebooks/downloads.jsx index 734458cf59..c6587f31ff 100644 --- a/gui/velociraptor/src/components/notebooks/downloads.jsx +++ b/gui/velociraptor/src/components/notebooks/downloads.jsx @@ -6,6 +6,7 @@ import T from '../i8n/i8n.jsx'; import Card from 'react-bootstrap/Card'; import Alert from 'react-bootstrap/Alert'; import { getFormatter } from "../core/table.jsx"; +import Accordion from 'react-bootstrap/Accordion'; import api from '../core/api-service.jsx'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -37,6 +38,37 @@ export default class AvailableDownloads extends Component { ; } + renderActiveMembers = (stats)=>{ + let mb = getFormatter("mb"); + return + + + {T("Active Members")} + + + + + + + + + + + + {_.map(stats.active_members, (x, idx)=>{ + return + + + + ; + })} + +
{T("Name")}{T("Uncompressed")}{T("Compressed")}
{x.name}{mb(x.uncompressed_size || 0, x)}{mb(x.compressed_size || 0, x)}
+
+
+
; + }; + render() { if (_.isEmpty(this.props.files)) { return
{T("Select a download method")}
; @@ -90,15 +122,16 @@ export default class AvailableDownloads extends Component { {stats.total_duration || 0} - { stats.hash && - <> -
{T("SHA256 Hash")}
-
- {stats.hash} -
+ { stats.active_members && this.renderActiveMembers(stats) } + { stats.hash && + <> +
{T("SHA256 Hash")}
+
+ {stats.hash} +
- - } + + } ; diff --git a/reporting/container.go b/reporting/container.go index 854d377bc7..5a6a9b8417 100644 --- a/reporting/container.go +++ b/reporting/container.go @@ -681,6 +681,11 @@ func (self *Container) Close() error { logger.Info("Container hash %v", hash) } + + ContainerTracker.UpdateContainer(self.id, func(info *ContainerInfo) { + info.CloseTime = utils.GetTime().Now() + }) + return self.fd.Close() } @@ -695,11 +700,13 @@ func (self *Container) Stats() *api_proto.ContainerStats { self.stats_mu.Lock() // Take a copy stats := proto.Clone(&self.stats).(*api_proto.ContainerStats) + id := self.id self.stats_mu.Unlock() stats.TotalUploadedFiles = uint64(len(self.uploads)) stats.TotalCompressedBytes = uint64(self.writer.Count()) stats.TotalDuration = uint64(Clock.Now().Unix()) - stats.Timestamp + stats.ActiveMembers = ContainerTracker.GetActiveMembers(id) return stats } diff --git a/reporting/profile.go b/reporting/profile.go index 6616b9341e..a3bb6797fe 100644 --- a/reporting/profile.go +++ b/reporting/profile.go @@ -43,6 +43,31 @@ type _ContainerTracker struct { containers map[uint64]*ContainerInfo } +func (self *_ContainerTracker) GetActiveMembers( + id uint64) []*api_proto.ContainerMemberStats { + self.mu.Lock() + defer self.mu.Unlock() + + record, pres := self.containers[id] + if !pres { + return nil + } + + var res []*api_proto.ContainerMemberStats + for _, w := range record.InFlightWriters { + // Skip the files that are already closed. + if !w.Closed.IsZero() { + continue + } + res = append(res, &api_proto.ContainerMemberStats{ + Name: w.Name, + UncompressedSize: uint64(w.UncompressedSize), + CompressedSize: uint64(w.CompressedSize), + }) + } + return res +} + func (self *_ContainerTracker) UpdateContainerWriter( container_id, writer_id uint64, cb func(info *WriterInfo)) { diff --git a/utils/writers.go b/utils/writers.go index c826a4baab..2a62a5bbc3 100644 --- a/utils/writers.go +++ b/utils/writers.go @@ -3,6 +3,7 @@ package utils import ( "io" "sync" + "time" ) type TeeWriter struct { @@ -50,3 +51,12 @@ type NopWriteCloser struct { func (self NopWriteCloser) Close() error { return nil } + +type InstrumentedWriteCloser struct { + io.WriteCloser +} + +func (self InstrumentedWriteCloser) Write(p []byte) (n int, err error) { + time.Sleep(200 * time.Millisecond) + return self.WriteCloser.Write(p) +}