feat: add stats to repo view e.g. total size in storage

This commit is contained in:
Gareth George
2023-12-25 07:41:31 +00:00
parent cc111970ca
commit adb0e3f230
20 changed files with 697 additions and 366 deletions
+164 -78
View File
@@ -211,6 +211,7 @@ type Operation struct {
// *Operation_OperationForget
// *Operation_OperationPrune
// *Operation_OperationRestore
// *Operation_OperationStats
Op isOperation_Op `protobuf_oneof:"op"`
}
@@ -344,6 +345,13 @@ func (x *Operation) GetOperationRestore() *OperationRestore {
return nil
}
func (x *Operation) GetOperationStats() *OperationStats {
if x, ok := x.GetOp().(*Operation_OperationStats); ok {
return x.OperationStats
}
return nil
}
type isOperation_Op interface {
isOperation_Op()
}
@@ -368,6 +376,10 @@ type Operation_OperationRestore struct {
OperationRestore *OperationRestore `protobuf:"bytes,104,opt,name=operation_restore,json=operationRestore,proto3,oneof"`
}
type Operation_OperationStats struct {
OperationStats *OperationStats `protobuf:"bytes,105,opt,name=operation_stats,json=operationStats,proto3,oneof"`
}
func (*Operation_OperationBackup) isOperation_Op() {}
func (*Operation_OperationIndexSnapshot) isOperation_Op() {}
@@ -378,6 +390,8 @@ func (*Operation_OperationPrune) isOperation_Op() {}
func (*Operation_OperationRestore) isOperation_Op() {}
func (*Operation_OperationStats) isOperation_Op() {}
// OperationEvent is used in the wireformat to stream operation changes to clients
type OperationEvent struct {
state protoimpl.MessageState
@@ -712,6 +726,53 @@ func (x *OperationRestore) GetStatus() *RestoreProgressEntry {
return nil
}
type OperationStats struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Stats *RepoStats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"`
}
func (x *OperationStats) Reset() {
*x = OperationStats{}
if protoimpl.UnsafeEnabled {
mi := &file_v1_operations_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OperationStats) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OperationStats) ProtoMessage() {}
func (x *OperationStats) ProtoReflect() protoreflect.Message {
mi := &file_v1_operations_proto_msgTypes[8]
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 OperationStats.ProtoReflect.Descriptor instead.
func (*OperationStats) Descriptor() ([]byte, []int) {
return file_v1_operations_proto_rawDescGZIP(), []int{8}
}
func (x *OperationStats) GetStats() *RepoStats {
if x != nil {
return x.Stats
}
return nil
}
var File_v1_operations_proto protoreflect.FileDescriptor
var file_v1_operations_proto_rawDesc = []byte{
@@ -722,7 +783,7 @@ var file_v1_operations_proto_rawDesc = []byte{
0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x0a,
0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x0d, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x80, 0x05, 0x0a, 0x09,
0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xbf, 0x05, 0x0a, 0x09,
0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x70,
0x6f, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f,
@@ -762,65 +823,73 @@ var file_v1_operations_proto_rawDesc = []byte{
0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x68, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x74, 0x6f, 0x72, 0x65, 0x48, 0x00, 0x52, 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x04, 0x0a, 0x02, 0x6f, 0x70, 0x22, 0x69,
0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74,
0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16,
0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65,
0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x09,
0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0d, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09,
0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x4b, 0x0a, 0x0f, 0x4f, 0x70, 0x65,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x38, 0x0a, 0x0b,
0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f,
0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x82, 0x01, 0x0a, 0x16, 0x4f, 0x70, 0x65, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
0x74, 0x12, 0x2e, 0x0a, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63, 0x53,
0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
0x08, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x12, 0x20, 0x0a, 0x0c, 0x66, 0x6f, 0x72,
0x67, 0x6f, 0x74, 0x5f, 0x62, 0x79, 0x5f, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
0x0a, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x42, 0x79, 0x4f, 0x70, 0x22, 0x6a, 0x0a, 0x0f, 0x4f,
0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2a,
0x0a, 0x06, 0x66, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12,
0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68,
0x6f, 0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2b, 0x0a, 0x06, 0x70, 0x6f,
0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x31, 0x2e,
0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52,
0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x28, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75,
0x74, 0x22, 0x70, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72,
0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65,
0x74, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x18, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x72,
0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x73, 0x74, 0x61,
0x74, 0x75, 0x73, 0x2a, 0x60, 0x0a, 0x12, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x45, 0x56, 0x45,
0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d,
0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12,
0x11, 0x0a, 0x0d, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44,
0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45,
0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0xc2, 0x01, 0x0a, 0x0f, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41,
0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a,
0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10,
0x01, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x50, 0x52,
0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54,
0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e,
0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x07,
0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52,
0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x59, 0x53,
0x54, 0x45, 0x4d, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x12,
0x19, 0x0a, 0x15, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x43,
0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x06, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68, 0x67,
0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x72, 0x65, 0x73, 0x74, 0x2f, 0x67,
0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3d, 0x0a, 0x0f, 0x6f, 0x70, 0x65, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x69, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x53, 0x74, 0x61, 0x74, 0x73, 0x48, 0x00, 0x52, 0x0e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x42, 0x04, 0x0a, 0x02, 0x6f, 0x70, 0x22, 0x69, 0x0a,
0x0e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,
0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e,
0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e,
0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x09, 0x6f,
0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d,
0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f,
0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x4b, 0x0a, 0x0f, 0x4f, 0x70, 0x65, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x38, 0x0a, 0x0b, 0x6c,
0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x67,
0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x82, 0x01, 0x0a, 0x16, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,
0x12, 0x2e, 0x0a, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63, 0x53, 0x6e,
0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,
0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
0x52, 0x06, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x12, 0x20, 0x0a, 0x0c, 0x66, 0x6f, 0x72, 0x67,
0x6f, 0x74, 0x5f, 0x62, 0x79, 0x5f, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a,
0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74, 0x42, 0x79, 0x4f, 0x70, 0x22, 0x6a, 0x0a, 0x0f, 0x4f, 0x70,
0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2a, 0x0a,
0x06, 0x66, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e,
0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
0x74, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2b, 0x0a, 0x06, 0x70, 0x6f, 0x6c,
0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x31, 0x2e, 0x52,
0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06,
0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x28, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70,
0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
0x22, 0x70, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x74, 0x6f, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67,
0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x18, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x72, 0x6f,
0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74,
0x75, 0x73, 0x22, 0x35, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53,
0x74, 0x61, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x53, 0x74, 0x61,
0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2a, 0x60, 0x0a, 0x12, 0x4f, 0x70, 0x65,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12,
0x11, 0x0a, 0x0d, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e,
0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x52, 0x45, 0x41,
0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x55,
0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x45, 0x56, 0x45, 0x4e,
0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0xc2, 0x01, 0x0a, 0x0f,
0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
0x4e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45,
0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55,
0x53, 0x5f, 0x49, 0x4e, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x12,
0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53,
0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x57, 0x41, 0x52,
0x4e, 0x49, 0x4e, 0x47, 0x10, 0x07, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53,
0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x54, 0x41, 0x54,
0x55, 0x53, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c,
0x4c, 0x45, 0x44, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
0x55, 0x53, 0x45, 0x52, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x06,
0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67,
0x61, 0x72, 0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x62, 0x61, 0x63, 0x6b,
0x72, 0x65, 0x73, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -836,7 +905,7 @@ func file_v1_operations_proto_rawDescGZIP() []byte {
}
var file_v1_operations_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_v1_operations_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_v1_operations_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_v1_operations_proto_goTypes = []interface{}{
(OperationEventType)(0), // 0: v1.OperationEventType
(OperationStatus)(0), // 1: v1.OperationStatus
@@ -848,10 +917,12 @@ var file_v1_operations_proto_goTypes = []interface{}{
(*OperationForget)(nil), // 7: v1.OperationForget
(*OperationPrune)(nil), // 8: v1.OperationPrune
(*OperationRestore)(nil), // 9: v1.OperationRestore
(*BackupProgressEntry)(nil), // 10: v1.BackupProgressEntry
(*ResticSnapshot)(nil), // 11: v1.ResticSnapshot
(*RetentionPolicy)(nil), // 12: v1.RetentionPolicy
(*RestoreProgressEntry)(nil), // 13: v1.RestoreProgressEntry
(*OperationStats)(nil), // 10: v1.OperationStats
(*BackupProgressEntry)(nil), // 11: v1.BackupProgressEntry
(*ResticSnapshot)(nil), // 12: v1.ResticSnapshot
(*RetentionPolicy)(nil), // 13: v1.RetentionPolicy
(*RestoreProgressEntry)(nil), // 14: v1.RestoreProgressEntry
(*RepoStats)(nil), // 15: v1.RepoStats
}
var file_v1_operations_proto_depIdxs = []int32{
3, // 0: v1.OperationList.operations:type_name -> v1.Operation
@@ -861,18 +932,20 @@ var file_v1_operations_proto_depIdxs = []int32{
7, // 4: v1.Operation.operation_forget:type_name -> v1.OperationForget
8, // 5: v1.Operation.operation_prune:type_name -> v1.OperationPrune
9, // 6: v1.Operation.operation_restore:type_name -> v1.OperationRestore
0, // 7: v1.OperationEvent.type:type_name -> v1.OperationEventType
3, // 8: v1.OperationEvent.operation:type_name -> v1.Operation
10, // 9: v1.OperationBackup.last_status:type_name -> v1.BackupProgressEntry
11, // 10: v1.OperationIndexSnapshot.snapshot:type_name -> v1.ResticSnapshot
11, // 11: v1.OperationForget.forget:type_name -> v1.ResticSnapshot
12, // 12: v1.OperationForget.policy:type_name -> v1.RetentionPolicy
13, // 13: v1.OperationRestore.status:type_name -> v1.RestoreProgressEntry
14, // [14:14] is the sub-list for method output_type
14, // [14:14] is the sub-list for method input_type
14, // [14:14] is the sub-list for extension type_name
14, // [14:14] is the sub-list for extension extendee
0, // [0:14] is the sub-list for field type_name
10, // 7: v1.Operation.operation_stats:type_name -> v1.OperationStats
0, // 8: v1.OperationEvent.type:type_name -> v1.OperationEventType
3, // 9: v1.OperationEvent.operation:type_name -> v1.Operation
11, // 10: v1.OperationBackup.last_status:type_name -> v1.BackupProgressEntry
12, // 11: v1.OperationIndexSnapshot.snapshot:type_name -> v1.ResticSnapshot
12, // 12: v1.OperationForget.forget:type_name -> v1.ResticSnapshot
13, // 13: v1.OperationForget.policy:type_name -> v1.RetentionPolicy
14, // 14: v1.OperationRestore.status:type_name -> v1.RestoreProgressEntry
15, // 15: v1.OperationStats.stats:type_name -> v1.RepoStats
16, // [16:16] is the sub-list for method output_type
16, // [16:16] is the sub-list for method input_type
16, // [16:16] is the sub-list for extension type_name
16, // [16:16] is the sub-list for extension extendee
0, // [0:16] is the sub-list for field type_name
}
func init() { file_v1_operations_proto_init() }
@@ -979,6 +1052,18 @@ func file_v1_operations_proto_init() {
return nil
}
}
file_v1_operations_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OperationStats); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_v1_operations_proto_msgTypes[1].OneofWrappers = []interface{}{
(*Operation_OperationBackup)(nil),
@@ -986,6 +1071,7 @@ func file_v1_operations_proto_init() {
(*Operation_OperationForget)(nil),
(*Operation_OperationPrune)(nil),
(*Operation_OperationRestore)(nil),
(*Operation_OperationStats)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -993,7 +1079,7 @@ func file_v1_operations_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_v1_operations_proto_rawDesc,
NumEnums: 2,
NumMessages: 8,
NumMessages: 9,
NumExtensions: 0,
NumServices: 0,
},
+121 -125
View File
@@ -225,11 +225,10 @@ type RestoreSnapshotRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RepoId string `protobuf:"bytes,1,opt,name=repo_id,json=repoId,proto3" json:"repo_id,omitempty"`
PlanId string `protobuf:"bytes,2,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"`
SnapshotId string `protobuf:"bytes,3,opt,name=snapshot_id,json=snapshotId,proto3" json:"snapshot_id,omitempty"`
Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"`
Target string `protobuf:"bytes,5,opt,name=target,proto3" json:"target,omitempty"`
PlanId string `protobuf:"bytes,1,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"`
SnapshotId string `protobuf:"bytes,2,opt,name=snapshot_id,json=snapshotId,proto3" json:"snapshot_id,omitempty"`
Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"`
Target string `protobuf:"bytes,4,opt,name=target,proto3" json:"target,omitempty"`
}
func (x *RestoreSnapshotRequest) Reset() {
@@ -264,13 +263,6 @@ func (*RestoreSnapshotRequest) Descriptor() ([]byte, []int) {
return file_v1_service_proto_rawDescGZIP(), []int{3}
}
func (x *RestoreSnapshotRequest) GetRepoId() string {
if x != nil {
return x.RepoId
}
return ""
}
func (x *RestoreSnapshotRequest) GetPlanId() string {
if x != nil {
return x.PlanId
@@ -569,101 +561,103 @@ var file_v1_service_proto_rawDesc = []byte{
0x0a, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x69,
0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x03, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x15, 0x0a,
0x06, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c,
0x61, 0x73, 0x74, 0x4e, 0x22, 0x97, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65,
0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x17, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e,
0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49,
0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,
0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x68,
0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x69,
0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65,
0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x70,
0x6f, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f,
0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68,
0x6f, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x56, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74,
0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x25, 0x0a, 0x07, 0x65, 0x6e, 0x74,
0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x76, 0x31, 0x2e,
0x4c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73,
0x22, 0xd3, 0x01, 0x0a, 0x07, 0x4c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18,
0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x69,
0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x67, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04,
0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04,
0x6d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x74,
0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x74, 0x69, 0x6d, 0x65,
0x12, 0x14, 0x0a, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x32, 0xfd, 0x06, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x72,
0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
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, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x22, 0x00, 0x12, 0x25, 0x0a, 0x09, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x12, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a,
0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x00, 0x12, 0x21, 0x0a,
0x07, 0x41, 0x64, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65,
0x70, 0x6f, 0x1a, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x00,
0x12, 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x45, 0x76, 0x65, 0x6e, 0x74, 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, 0x12,
0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65,
0x6e, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3e, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x65,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e,
0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12, 0x18, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x16, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63, 0x53, 0x6e, 0x61,
0x70, 0x73, 0x68, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x11, 0x4c,
0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73,
0x12, 0x1c, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68,
0x6f, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d,
0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,
0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x36, 0x0a, 0x06, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65,
0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x05, 0x50, 0x72, 0x75, 0x6e, 0x65,
0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x36,
0x0a, 0x06, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73,
0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67,
0x61, 0x73, 0x74, 0x4e, 0x22, 0x7e, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53,
0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17,
0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73,
0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6e,
0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06,
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61,
0x72, 0x67, 0x65, 0x74, 0x22, 0x68, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70,
0x73, 0x68, 0x6f, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6e, 0x61,
0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61,
0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x56,
0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x69,
0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70,
0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12,
0x25, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x0b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65,
0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xd3, 0x01, 0x0a, 0x07, 0x4c, 0x73, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61,
0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x10,
0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64,
0x12, 0x10, 0x0a, 0x03, 0x67, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x67,
0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03,
0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x07,
0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x74,
0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x74, 0x69, 0x6d, 0x65,
0x12, 0x14, 0x0a, 0x05, 0x61, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x61, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x18,
0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x32, 0xb4, 0x07, 0x0a,
0x08, 0x42, 0x61, 0x63, 0x6b, 0x72, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x09, 0x47, 0x65, 0x74,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x0a,
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x00, 0x12, 0x25, 0x0a, 0x09,
0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x22, 0x00, 0x12, 0x21, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x08,
0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x65,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 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, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72,
0x65, 0x12, 0x1a, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x6e,
0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x06, 0x55, 0x6e, 0x6c, 0x6f, 0x63,
0x6b, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12,
0x35, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65,
0x73, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67,
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3e, 0x0a, 0x0d,
0x47, 0x65, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x2e,
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0d,
0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12, 0x18, 0x2e,
0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73,
0x74, 0x69, 0x63, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22,
0x00, 0x12, 0x52, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e,
0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x06, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12,
0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61,
0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a,
0x05, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53,
0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12,
0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x07,
0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x1a, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73,
0x74, 0x6f, 0x72, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a,
0x06, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x12,
0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x06,
0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49,
0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0c, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x48, 0x69, 0x73, 0x74,
0x6f, 0x72, 0x79, 0x12, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x48, 0x69,
0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0c, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x48,
0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x65, 0x61,
0x72, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x10, 0x50, 0x61, 0x74,
0x68, 0x41, 0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x12, 0x2e,
0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x1a, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67,
0x65, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x72, 0x65, 0x73, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67,
0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x10, 0x50, 0x61, 0x74, 0x68, 0x41, 0x75,
0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70,
0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x11,
0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73,
0x74, 0x22, 0x00, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x62,
0x61, 0x63, 0x6b, 0x72, 0x65, 0x73, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76,
0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -711,26 +705,28 @@ var file_v1_service_proto_depIdxs = []int32{
10, // 10: v1.Backrest.Forget:input_type -> types.StringValue
3, // 11: v1.Backrest.Restore:input_type -> v1.RestoreSnapshotRequest
10, // 12: v1.Backrest.Unlock:input_type -> types.StringValue
11, // 13: v1.Backrest.Cancel:input_type -> types.Int64Value
0, // 14: v1.Backrest.ClearHistory:input_type -> v1.ClearHistoryRequest
10, // 15: v1.Backrest.PathAutocomplete:input_type -> types.StringValue
8, // 16: v1.Backrest.GetConfig:output_type -> v1.Config
8, // 17: v1.Backrest.SetConfig:output_type -> v1.Config
8, // 18: v1.Backrest.AddRepo:output_type -> v1.Config
12, // 19: v1.Backrest.GetOperationEvents:output_type -> v1.OperationEvent
13, // 20: v1.Backrest.GetOperations:output_type -> v1.OperationList
14, // 21: v1.Backrest.ListSnapshots:output_type -> v1.ResticSnapshotList
5, // 22: v1.Backrest.ListSnapshotFiles:output_type -> v1.ListSnapshotFilesResponse
7, // 23: v1.Backrest.Backup:output_type -> google.protobuf.Empty
7, // 24: v1.Backrest.Prune:output_type -> google.protobuf.Empty
7, // 25: v1.Backrest.Forget:output_type -> google.protobuf.Empty
7, // 26: v1.Backrest.Restore:output_type -> google.protobuf.Empty
7, // 27: v1.Backrest.Unlock:output_type -> google.protobuf.Empty
7, // 28: v1.Backrest.Cancel:output_type -> google.protobuf.Empty
7, // 29: v1.Backrest.ClearHistory:output_type -> google.protobuf.Empty
15, // 30: v1.Backrest.PathAutocomplete:output_type -> types.StringList
16, // [16:31] is the sub-list for method output_type
1, // [1:16] is the sub-list for method input_type
10, // 13: v1.Backrest.Stats:input_type -> types.StringValue
11, // 14: v1.Backrest.Cancel:input_type -> types.Int64Value
0, // 15: v1.Backrest.ClearHistory:input_type -> v1.ClearHistoryRequest
10, // 16: v1.Backrest.PathAutocomplete:input_type -> types.StringValue
8, // 17: v1.Backrest.GetConfig:output_type -> v1.Config
8, // 18: v1.Backrest.SetConfig:output_type -> v1.Config
8, // 19: v1.Backrest.AddRepo:output_type -> v1.Config
12, // 20: v1.Backrest.GetOperationEvents:output_type -> v1.OperationEvent
13, // 21: v1.Backrest.GetOperations:output_type -> v1.OperationList
14, // 22: v1.Backrest.ListSnapshots:output_type -> v1.ResticSnapshotList
5, // 23: v1.Backrest.ListSnapshotFiles:output_type -> v1.ListSnapshotFilesResponse
7, // 24: v1.Backrest.Backup:output_type -> google.protobuf.Empty
7, // 25: v1.Backrest.Prune:output_type -> google.protobuf.Empty
7, // 26: v1.Backrest.Forget:output_type -> google.protobuf.Empty
7, // 27: v1.Backrest.Restore:output_type -> google.protobuf.Empty
7, // 28: v1.Backrest.Unlock:output_type -> google.protobuf.Empty
7, // 29: v1.Backrest.Stats:output_type -> google.protobuf.Empty
7, // 30: v1.Backrest.Cancel:output_type -> google.protobuf.Empty
7, // 31: v1.Backrest.ClearHistory:output_type -> google.protobuf.Empty
15, // 32: v1.Backrest.PathAutocomplete:output_type -> types.StringList
17, // [17:33] is the sub-list for method output_type
1, // [1:17] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
+41
View File
@@ -33,6 +33,7 @@ const (
Backrest_Forget_FullMethodName = "/v1.Backrest/Forget"
Backrest_Restore_FullMethodName = "/v1.Backrest/Restore"
Backrest_Unlock_FullMethodName = "/v1.Backrest/Unlock"
Backrest_Stats_FullMethodName = "/v1.Backrest/Stats"
Backrest_Cancel_FullMethodName = "/v1.Backrest/Cancel"
Backrest_ClearHistory_FullMethodName = "/v1.Backrest/ClearHistory"
Backrest_PathAutocomplete_FullMethodName = "/v1.Backrest/PathAutocomplete"
@@ -59,8 +60,11 @@ type BackrestClient interface {
Restore(ctx context.Context, in *RestoreSnapshotRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Unlock synchronously attempts to unlock the repo. Will block if other operations are in progress.
Unlock(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Stats runs 'restic stats` on the repository and appends the results to the operations log.
Stats(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Cancel attempts to cancel a task with the given operation ID. Not guaranteed to succeed.
Cancel(ctx context.Context, in *types.Int64Value, opts ...grpc.CallOption) (*emptypb.Empty, error)
// Clears the history of operations
ClearHistory(ctx context.Context, in *ClearHistoryRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// PathAutocomplete provides path autocompletion options for a given filesystem path.
PathAutocomplete(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*types.StringList, error)
@@ -205,6 +209,15 @@ func (c *backrestClient) Unlock(ctx context.Context, in *types.StringValue, opts
return out, nil
}
func (c *backrestClient) Stats(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, Backrest_Stats_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *backrestClient) Cancel(ctx context.Context, in *types.Int64Value, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, Backrest_Cancel_FullMethodName, in, out, opts...)
@@ -253,8 +266,11 @@ type BackrestServer interface {
Restore(context.Context, *RestoreSnapshotRequest) (*emptypb.Empty, error)
// Unlock synchronously attempts to unlock the repo. Will block if other operations are in progress.
Unlock(context.Context, *types.StringValue) (*emptypb.Empty, error)
// Stats runs 'restic stats` on the repository and appends the results to the operations log.
Stats(context.Context, *types.StringValue) (*emptypb.Empty, error)
// Cancel attempts to cancel a task with the given operation ID. Not guaranteed to succeed.
Cancel(context.Context, *types.Int64Value) (*emptypb.Empty, error)
// Clears the history of operations
ClearHistory(context.Context, *ClearHistoryRequest) (*emptypb.Empty, error)
// PathAutocomplete provides path autocompletion options for a given filesystem path.
PathAutocomplete(context.Context, *types.StringValue) (*types.StringList, error)
@@ -301,6 +317,9 @@ func (UnimplementedBackrestServer) Restore(context.Context, *RestoreSnapshotRequ
func (UnimplementedBackrestServer) Unlock(context.Context, *types.StringValue) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Unlock not implemented")
}
func (UnimplementedBackrestServer) Stats(context.Context, *types.StringValue) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Stats not implemented")
}
func (UnimplementedBackrestServer) Cancel(context.Context, *types.Int64Value) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Cancel not implemented")
}
@@ -542,6 +561,24 @@ func _Backrest_Unlock_Handler(srv interface{}, ctx context.Context, dec func(int
return interceptor(ctx, in, info, handler)
}
func _Backrest_Stats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(types.StringValue)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BackrestServer).Stats(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Backrest_Stats_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BackrestServer).Stats(ctx, req.(*types.StringValue))
}
return interceptor(ctx, in, info, handler)
}
func _Backrest_Cancel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(types.Int64Value)
if err := dec(in); err != nil {
@@ -647,6 +684,10 @@ var Backrest_ServiceDesc = grpc.ServiceDesc{
MethodName: "Unlock",
Handler: _Backrest_Unlock_Handler,
},
{
MethodName: "Stats",
Handler: _Backrest_Stats_Handler,
},
{
MethodName: "Cancel",
Handler: _Backrest_Cancel_Handler,
+33
View File
@@ -61,6 +61,8 @@ const (
BackrestRestoreProcedure = "/v1.Backrest/Restore"
// BackrestUnlockProcedure is the fully-qualified name of the Backrest's Unlock RPC.
BackrestUnlockProcedure = "/v1.Backrest/Unlock"
// BackrestStatsProcedure is the fully-qualified name of the Backrest's Stats RPC.
BackrestStatsProcedure = "/v1.Backrest/Stats"
// BackrestCancelProcedure is the fully-qualified name of the Backrest's Cancel RPC.
BackrestCancelProcedure = "/v1.Backrest/Cancel"
// BackrestClearHistoryProcedure is the fully-qualified name of the Backrest's ClearHistory RPC.
@@ -85,6 +87,7 @@ var (
backrestForgetMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Forget")
backrestRestoreMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Restore")
backrestUnlockMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Unlock")
backrestStatsMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Stats")
backrestCancelMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Cancel")
backrestClearHistoryMethodDescriptor = backrestServiceDescriptor.Methods().ByName("ClearHistory")
backrestPathAutocompleteMethodDescriptor = backrestServiceDescriptor.Methods().ByName("PathAutocomplete")
@@ -109,8 +112,11 @@ type BackrestClient interface {
Restore(context.Context, *connect.Request[v1.RestoreSnapshotRequest]) (*connect.Response[emptypb.Empty], error)
// Unlock synchronously attempts to unlock the repo. Will block if other operations are in progress.
Unlock(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error)
// Stats runs 'restic stats` on the repository and appends the results to the operations log.
Stats(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error)
// Cancel attempts to cancel a task with the given operation ID. Not guaranteed to succeed.
Cancel(context.Context, *connect.Request[types.Int64Value]) (*connect.Response[emptypb.Empty], error)
// Clears the history of operations
ClearHistory(context.Context, *connect.Request[v1.ClearHistoryRequest]) (*connect.Response[emptypb.Empty], error)
// PathAutocomplete provides path autocompletion options for a given filesystem path.
PathAutocomplete(context.Context, *connect.Request[types.StringValue]) (*connect.Response[types.StringList], error)
@@ -198,6 +204,12 @@ func NewBackrestClient(httpClient connect.HTTPClient, baseURL string, opts ...co
connect.WithSchema(backrestUnlockMethodDescriptor),
connect.WithClientOptions(opts...),
),
stats: connect.NewClient[types.StringValue, emptypb.Empty](
httpClient,
baseURL+BackrestStatsProcedure,
connect.WithSchema(backrestStatsMethodDescriptor),
connect.WithClientOptions(opts...),
),
cancel: connect.NewClient[types.Int64Value, emptypb.Empty](
httpClient,
baseURL+BackrestCancelProcedure,
@@ -233,6 +245,7 @@ type backrestClient struct {
forget *connect.Client[types.StringValue, emptypb.Empty]
restore *connect.Client[v1.RestoreSnapshotRequest, emptypb.Empty]
unlock *connect.Client[types.StringValue, emptypb.Empty]
stats *connect.Client[types.StringValue, emptypb.Empty]
cancel *connect.Client[types.Int64Value, emptypb.Empty]
clearHistory *connect.Client[v1.ClearHistoryRequest, emptypb.Empty]
pathAutocomplete *connect.Client[types.StringValue, types.StringList]
@@ -298,6 +311,11 @@ func (c *backrestClient) Unlock(ctx context.Context, req *connect.Request[types.
return c.unlock.CallUnary(ctx, req)
}
// Stats calls v1.Backrest.Stats.
func (c *backrestClient) Stats(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) {
return c.stats.CallUnary(ctx, req)
}
// Cancel calls v1.Backrest.Cancel.
func (c *backrestClient) Cancel(ctx context.Context, req *connect.Request[types.Int64Value]) (*connect.Response[emptypb.Empty], error) {
return c.cancel.CallUnary(ctx, req)
@@ -332,8 +350,11 @@ type BackrestHandler interface {
Restore(context.Context, *connect.Request[v1.RestoreSnapshotRequest]) (*connect.Response[emptypb.Empty], error)
// Unlock synchronously attempts to unlock the repo. Will block if other operations are in progress.
Unlock(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error)
// Stats runs 'restic stats` on the repository and appends the results to the operations log.
Stats(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error)
// Cancel attempts to cancel a task with the given operation ID. Not guaranteed to succeed.
Cancel(context.Context, *connect.Request[types.Int64Value]) (*connect.Response[emptypb.Empty], error)
// Clears the history of operations
ClearHistory(context.Context, *connect.Request[v1.ClearHistoryRequest]) (*connect.Response[emptypb.Empty], error)
// PathAutocomplete provides path autocompletion options for a given filesystem path.
PathAutocomplete(context.Context, *connect.Request[types.StringValue]) (*connect.Response[types.StringList], error)
@@ -417,6 +438,12 @@ func NewBackrestHandler(svc BackrestHandler, opts ...connect.HandlerOption) (str
connect.WithSchema(backrestUnlockMethodDescriptor),
connect.WithHandlerOptions(opts...),
)
backrestStatsHandler := connect.NewUnaryHandler(
BackrestStatsProcedure,
svc.Stats,
connect.WithSchema(backrestStatsMethodDescriptor),
connect.WithHandlerOptions(opts...),
)
backrestCancelHandler := connect.NewUnaryHandler(
BackrestCancelProcedure,
svc.Cancel,
@@ -461,6 +488,8 @@ func NewBackrestHandler(svc BackrestHandler, opts ...connect.HandlerOption) (str
backrestRestoreHandler.ServeHTTP(w, r)
case BackrestUnlockProcedure:
backrestUnlockHandler.ServeHTTP(w, r)
case BackrestStatsProcedure:
backrestStatsHandler.ServeHTTP(w, r)
case BackrestCancelProcedure:
backrestCancelHandler.ServeHTTP(w, r)
case BackrestClearHistoryProcedure:
@@ -524,6 +553,10 @@ func (UnimplementedBackrestHandler) Unlock(context.Context, *connect.Request[typ
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.Unlock is not implemented"))
}
func (UnimplementedBackrestHandler) Stats(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.Stats is not implemented"))
}
func (UnimplementedBackrestHandler) Cancel(context.Context, *connect.Request[types.Int64Value]) (*connect.Response[emptypb.Empty], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.Cancel is not implemented"))
}
+4 -5
View File
@@ -267,7 +267,7 @@ func (s *Server) Forget(ctx context.Context, req *connect.Request[types.StringVa
at := time.Now()
s.orchestrator.ScheduleTask(orchestrator.NewOneofForgetTask(s.orchestrator, plan, "", at), orchestrator.TaskPriorityInteractive+orchestrator.TaskPriorityForget)
s.orchestrator.ScheduleTask(orchestrator.NewOneofForgetTask(s.orchestrator, plan, "", at), orchestrator.TaskPriorityInteractive+orchestrator.TaskPriorityIndexSnapshots)
s.orchestrator.ScheduleTask(orchestrator.NewOneofIndexSnapshotsTask(s.orchestrator, plan, at), orchestrator.TaskPriorityInteractive+orchestrator.TaskPriorityIndexSnapshots)
return connect.NewResponse(&emptypb.Empty{}), nil
}
@@ -285,9 +285,9 @@ func (s *Server) Prune(ctx context.Context, req *connect.Request[types.StringVal
}
func (s *Server) Restore(ctx context.Context, req *connect.Request[v1.RestoreSnapshotRequest]) (*connect.Response[emptypb.Empty], error) {
_, err := s.orchestrator.GetRepo(req.Msg.RepoId)
plan, err := s.orchestrator.GetPlan(req.Msg.PlanId)
if err != nil {
return nil, fmt.Errorf("failed to get repo %q: %w", req.Msg.RepoId, err)
return nil, fmt.Errorf("failed to get plan %q: %w", req.Msg.PlanId, err)
}
if req.Msg.Target == "" {
@@ -303,8 +303,7 @@ func (s *Server) Restore(ctx context.Context, req *connect.Request[v1.RestoreSna
at := time.Now()
s.orchestrator.ScheduleTask(orchestrator.NewOneofRestoreTask(s.orchestrator, orchestrator.RestoreTaskOpts{
PlanId: req.Msg.PlanId,
RepoId: req.Msg.RepoId,
Plan: plan,
SnapshotId: req.Msg.SnapshotId,
Path: req.Msg.Path,
Target: target,
+6 -5
View File
@@ -22,11 +22,12 @@ var ErrRepoInitializationFailed = errors.New("repo initialization failed")
var ErrPlanNotFound = errors.New("plan not found")
const (
TaskPriorityDefault = iota
TaskPriorityIndexSnapshots
TaskPriorityPrune
TaskPriorityForget
TaskPriorityInteractive // highest priority (add other priorities to this value for offsets)
TaskPriorityDefault = 0
TaskPriorityInteractive = 10
TaskPriorityIndexSnapshots = 101
TaskPriorityForget = 102
TaskPriorityPrune = 103
TaskPriorityStats = 104
)
// Orchestrator is responsible for managing repos and backups.
+13
View File
@@ -195,6 +195,19 @@ func (r *RepoOrchestrator) Unlock(ctx context.Context) error {
return nil
}
func (r *RepoOrchestrator) Stats(ctx context.Context) (*v1.RepoStats, error) {
r.mu.Lock()
defer r.mu.Unlock()
r.l.Debug("Get Stats")
stats, err := r.repo.Stats(ctx)
if err != nil {
return nil, fmt.Errorf("stats for repo %v: %w", r.repoConfig.Id, err)
}
return protoutil.RepoStatsToProto(stats), nil
}
func tagForPlan(plan *v1.Plan) string {
return fmt.Sprintf("plan:%s", plan.Id)
}
+1
View File
@@ -146,6 +146,7 @@ func backupHelper(ctx context.Context, orchestrator *Orchestrator, plan *v1.Plan
}
orchestrator.ScheduleTask(NewOneofIndexSnapshotsTask(orchestrator, plan, at), TaskPriorityIndexSnapshots)
orchestrator.ScheduleTask(NewOneofStatsTask(orchestrator, plan, op.SnapshotId, at), TaskPriorityStats)
return nil
}
+6 -7
View File
@@ -10,8 +10,7 @@ import (
)
type RestoreTaskOpts struct {
PlanId string
RepoId string
Plan *v1.Plan
SnapshotId string
Path string
Target string
@@ -37,7 +36,7 @@ func NewOneofRestoreTask(orchestrator *Orchestrator, opts RestoreTaskOpts, at ti
}
func (t *RestoreTask) Name() string {
return fmt.Sprintf("restore snapshot %v in repo %v", t.restoreOpts.SnapshotId, t.restoreOpts.RepoId)
return fmt.Sprintf("restore snapshot %v in repo %v", t.restoreOpts.SnapshotId, t.restoreOpts.Plan.Repo)
}
func (t *RestoreTask) Next(now time.Time) *time.Time {
@@ -45,8 +44,8 @@ func (t *RestoreTask) Next(now time.Time) *time.Time {
if ret != nil {
t.at = nil
if err := t.setOperation(&v1.Operation{
PlanId: t.restoreOpts.PlanId,
RepoId: t.restoreOpts.RepoId,
PlanId: t.restoreOpts.Plan.Id,
RepoId: t.restoreOpts.Plan.Repo,
SnapshotId: t.restoreOpts.SnapshotId,
UnixTimeStartMs: timeToUnixMillis(*ret),
Status: v1.OperationStatus_STATUS_PENDING,
@@ -70,9 +69,9 @@ func (t *RestoreTask) Run(ctx context.Context) error {
op.Op = forgetOp
op.UnixTimeStartMs = curTimeMillis()
repo, err := t.orch.GetRepo(t.restoreOpts.RepoId)
repo, err := t.orch.GetRepo(t.restoreOpts.Plan.Repo)
if err != nil {
return fmt.Errorf("couldn't get repo %q: %w", t.restoreOpts.RepoId, err)
return fmt.Errorf("couldn't get repo %q: %w", t.restoreOpts.Plan.Repo, err)
}
lastSent := time.Now() // debounce progress updates, these can endup being very frequent.
+81
View File
@@ -0,0 +1,81 @@
package orchestrator
import (
"context"
"errors"
"fmt"
"time"
v1 "github.com/garethgeorge/backrest/gen/go/v1"
"go.uber.org/zap"
)
// StatsTask tracks a restic stats operation.
type StatsTask struct {
TaskWithOperation
plan *v1.Plan
linkSnapshot string // snapshot to link the task to (if any)
at *time.Time
}
var _ Task = &ForgetTask{}
func NewOneofStatsTask(orchestrator *Orchestrator, plan *v1.Plan, linkSnapshot string, at time.Time) *StatsTask {
return &StatsTask{
TaskWithOperation: TaskWithOperation{
orch: orchestrator,
},
plan: plan,
at: &at,
linkSnapshot: linkSnapshot,
}
}
func (t *StatsTask) Name() string {
return fmt.Sprintf("stats for plan %q", t.plan.Id)
}
func (t *StatsTask) Next(now time.Time) *time.Time {
ret := t.at
if ret != nil {
t.at = nil
if err := t.setOperation(&v1.Operation{
PlanId: t.plan.Id,
RepoId: t.plan.Repo,
SnapshotId: t.linkSnapshot,
UnixTimeStartMs: timeToUnixMillis(*ret),
Status: v1.OperationStatus_STATUS_PENDING,
Op: &v1.Operation_OperationStats{},
}); err != nil {
zap.S().Errorf("task %v failed to add operation to oplog: %v", t.Name(), err)
return nil
}
}
return ret
}
func (t *StatsTask) Run(ctx context.Context) error {
if t.plan.Retention == nil {
return errors.New("plan does not have a retention policy")
}
return t.runWithOpAndContext(ctx, func(ctx context.Context, op *v1.Operation) error {
repo, err := t.orch.GetRepo(t.plan.Repo)
if err != nil {
return fmt.Errorf("get repo %q: %w", t.plan.Repo, err)
}
stats, err := repo.Stats(ctx)
if err != nil {
return fmt.Errorf("get stats: %w", err)
}
op.Op = &v1.Operation_OperationStats{
OperationStats: &v1.OperationStats{
Stats: stats,
},
}
return err
})
}
+5
View File
@@ -34,6 +34,7 @@ message Operation {
OperationForget operation_forget = 102;
OperationPrune operation_prune = 103;
OperationRestore operation_restore = 104;
OperationStats operation_stats = 105;
}
}
@@ -88,4 +89,8 @@ message OperationRestore {
string path = 1; // path in the snapshot to restore.
string target = 2; // location to restore it to.
RestoreProgressEntry status = 3; // status of the restore.
}
message OperationStats {
RepoStats stats = 1;
}
+7 -5
View File
@@ -41,6 +41,9 @@ service Backrest {
// Unlock synchronously attempts to unlock the repo. Will block if other operations are in progress.
rpc Unlock(types.StringValue) returns (google.protobuf.Empty) {}
// Stats runs 'restic stats` on the repository and appends the results to the operations log.
rpc Stats(types.StringValue) returns (google.protobuf.Empty) {}
// Cancel attempts to cancel a task with the given operation ID. Not guaranteed to succeed.
rpc Cancel(types.Int64Value) returns (google.protobuf.Empty) {}
@@ -71,11 +74,10 @@ message GetOperationsRequest {
}
message RestoreSnapshotRequest {
string repo_id = 1;
string plan_id = 2;
string snapshot_id = 3;
string path = 4;
string target = 5;
string plan_id = 1;
string snapshot_id = 2;
string path = 3;
string target = 4;
}
message ListSnapshotFilesRequest {
+45 -1
View File
@@ -5,7 +5,7 @@
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3, protoInt64 } from "@bufbuild/protobuf";
import { BackupProgressEntry, ResticSnapshot, RestoreProgressEntry } from "./restic_pb.js";
import { BackupProgressEntry, RepoStats, ResticSnapshot, RestoreProgressEntry } from "./restic_pb.js";
import { RetentionPolicy } from "./config_pb.js";
/**
@@ -242,6 +242,12 @@ export class Operation extends Message<Operation> {
*/
value: OperationRestore;
case: "operationRestore";
} | {
/**
* @generated from field: v1.OperationStats operation_stats = 105;
*/
value: OperationStats;
case: "operationStats";
} | { case: undefined; value?: undefined } = { case: undefined };
constructor(data?: PartialMessage<Operation>) {
@@ -265,6 +271,7 @@ export class Operation extends Message<Operation> {
{ no: 102, name: "operation_forget", kind: "message", T: OperationForget, oneof: "op" },
{ no: 103, name: "operation_prune", kind: "message", T: OperationPrune, oneof: "op" },
{ no: 104, name: "operation_restore", kind: "message", T: OperationRestore, oneof: "op" },
{ no: 105, name: "operation_stats", kind: "message", T: OperationStats, oneof: "op" },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Operation {
@@ -562,3 +569,40 @@ export class OperationRestore extends Message<OperationRestore> {
}
}
/**
* @generated from message v1.OperationStats
*/
export class OperationStats extends Message<OperationStats> {
/**
* @generated from field: v1.RepoStats stats = 1;
*/
stats?: RepoStats;
constructor(data?: PartialMessage<OperationStats>) {
super();
proto3.util.initPartial(data, this);
}
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "v1.OperationStats";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "stats", kind: "message", T: RepoStats },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): OperationStats {
return new OperationStats().fromBinary(bytes, options);
}
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): OperationStats {
return new OperationStats().fromJson(jsonValue, options);
}
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): OperationStats {
return new OperationStats().fromJsonString(jsonString, options);
}
static equals(a: OperationStats | PlainMessage<OperationStats> | undefined, b: OperationStats | PlainMessage<OperationStats> | undefined): boolean {
return proto3.util.equals(OperationStats, a, b);
}
}
+13
View File
@@ -134,6 +134,17 @@ export const Backrest = {
O: Empty,
kind: MethodKind.Unary,
},
/**
* Stats runs 'restic stats` on the repository and appends the results to the operations log.
*
* @generated from rpc v1.Backrest.Stats
*/
stats: {
name: "Stats",
I: StringValue,
O: Empty,
kind: MethodKind.Unary,
},
/**
* Cancel attempts to cancel a task with the given operation ID. Not guaranteed to succeed.
*
@@ -146,6 +157,8 @@ export const Backrest = {
kind: MethodKind.Unary,
},
/**
* Clears the history of operations
*
* @generated from rpc v1.Backrest.ClearHistory
*/
clearHistory: {
+8 -14
View File
@@ -166,27 +166,22 @@ export class GetOperationsRequest extends Message<GetOperationsRequest> {
*/
export class RestoreSnapshotRequest extends Message<RestoreSnapshotRequest> {
/**
* @generated from field: string repo_id = 1;
*/
repoId = "";
/**
* @generated from field: string plan_id = 2;
* @generated from field: string plan_id = 1;
*/
planId = "";
/**
* @generated from field: string snapshot_id = 3;
* @generated from field: string snapshot_id = 2;
*/
snapshotId = "";
/**
* @generated from field: string path = 4;
* @generated from field: string path = 3;
*/
path = "";
/**
* @generated from field: string target = 5;
* @generated from field: string target = 4;
*/
target = "";
@@ -198,11 +193,10 @@ export class RestoreSnapshotRequest extends Message<RestoreSnapshotRequest> {
static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "v1.RestoreSnapshotRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "repo_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "plan_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 3, name: "snapshot_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 4, name: "path", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 5, name: "target", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 1, name: "plan_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "snapshot_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 3, name: "path", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 4, name: "target", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): RestoreSnapshotRequest {
+57 -55
View File
@@ -3,6 +3,7 @@ import {
Operation,
OperationEvent,
OperationEventType,
OperationForget,
OperationStatus,
} from "../../gen/ts/v1/operations_pb";
import {
@@ -31,6 +32,7 @@ import {
displayTypeToString,
getOperations,
getTypeForDisplay,
shouldHideOperation,
shouldHideStatus,
subscribeToOperations,
unsubscribeFromOperations,
@@ -131,7 +133,7 @@ export const OperationList = ({
return (
<Card size="small" style={{ margin: "5px" }}>
{ops.map((op) => {
if (shouldHideStatus(op.status!)) {
if (shouldHideOperation(op)) {
return null;
}
return <OperationRow alertApi={alertApi!} key={op.id} operation={op} showPlan={showPlan || false} />
@@ -244,57 +246,7 @@ export const OperationRow = ({
if (forgetOp.forget?.length === 0) {
return null;
}
const policy = forgetOp.policy! || {};
const policyDesc = [];
if (policy.keepLastN) {
policyDesc.push(`Keep Last ${policy.keepLastN} Snapshots`);
}
if (policy.keepHourly) {
policyDesc.push(`Keep Hourly for ${policy.keepHourly} Hours`);
}
if (policy.keepDaily) {
policyDesc.push(`Keep Daily for ${policy.keepDaily} Days`);
}
if (policy.keepWeekly) {
policyDesc.push(`Keep Weekly for ${policy.keepWeekly} Weeks`);
}
if (policy.keepMonthly) {
policyDesc.push(`Keep Monthly for ${policy.keepMonthly} Months`);
}
if (policy.keepYearly) {
policyDesc.push(`Keep Yearly for ${policy.keepYearly} Years`);
}
body = (
<>
<p></p>
<Collapse
size="small"
destroyInactivePanel
items={[
{
key: 1,
label: "Removed " + forgetOp.forget?.length + " Snapshots",
children: <>
Removed snapshots:
<pre>{forgetOp.forget?.map((f) => (
<div key={f.id}>
{"removed snapshot " + normalizeSnapshotId(f.id!) + " taken at " + formatTime(Number(f.unixTimeMs))} <br />
</div>
))}</pre>
Policy:
<ul>
{policyDesc.map((desc, idx) => (
<li key={idx}>{desc}</li>
))}
</ul>
</>,
},
]}
/>
</>
);
body = <ForgetOperationDetails forgetOp={forgetOp} />
} else if (operation.op.case === "operationPrune") {
const prune = operation.op.value;
body = (
@@ -407,9 +359,6 @@ const BackupOperationStatus = ({
<>
<Progress percent={progress} status="active" />
<br />
{st.currentFile && st.currentFile.length > 0 ? (
<pre>Current file: {st.currentFile.join("\n")}</pre>
) : null}
<Row gutter={16}>
<Col span={12}>
<Typography.Text strong>Bytes Done/Total</Typography.Text>
@@ -422,6 +371,9 @@ const BackupOperationStatus = ({
{Number(st.filesDone)}/{Number(st.totalFiles)}
</Col>
</Row>
{st.currentFile && st.currentFile.length > 0 ? (
<pre>Current file: {st.currentFile.join("\n")}</pre>
) : null}
</>
);
} else if (status.entry.case === "summary") {
@@ -473,3 +425,53 @@ const BackupOperationStatus = ({
return <>No fields set. This shouldn't happen</>;
}
};
const ForgetOperationDetails = ({ forgetOp }: { forgetOp: OperationForget }) => {
const policy = forgetOp.policy! || {};
const policyDesc = [];
if (policy.keepLastN) {
policyDesc.push(`Keep Last ${policy.keepLastN} Snapshots`);
}
if (policy.keepHourly) {
policyDesc.push(`Keep Hourly for ${policy.keepHourly} Hours`);
}
if (policy.keepDaily) {
policyDesc.push(`Keep Daily for ${policy.keepDaily} Days`);
}
if (policy.keepWeekly) {
policyDesc.push(`Keep Weekly for ${policy.keepWeekly} Weeks`);
}
if (policy.keepMonthly) {
policyDesc.push(`Keep Monthly for ${policy.keepMonthly} Months`);
}
if (policy.keepYearly) {
policyDesc.push(`Keep Yearly for ${policy.keepYearly} Years`);
}
return (
<Collapse
size="small"
destroyInactivePanel
items={[
{
key: 1,
label: "Removed " + forgetOp.forget?.length + " Snapshots",
children: <>
Removed snapshots:
<pre>{forgetOp.forget?.map((f) => (
<div key={f.id}>
{"removed snapshot " + normalizeSnapshotId(f.id!) + " taken at " + formatTime(Number(f.unixTimeMs))} <br />
</div>
))}</pre>
Policy:
<ul>
{policyDesc.map((desc, idx) => (
<li key={idx}>{desc}</li>
))}
</ul>
</>,
},
]}
/>
);
}
-34
View File
@@ -112,7 +112,6 @@ export const OperationTree = ({
return (
<Row>
<Col span={12}>
<h3>Browse Backups</h3>
<Tree<OpTreeNode>
treeData={treeData}
showIcon
@@ -210,39 +209,6 @@ const buildTreePlan = (operations: BackupInfo[]): OpTreeNode[] => {
return entries;
};
const buildTreeYear = (keyPrefix: string, operations: BackupInfo[]): OpTreeNode[] => {
const grouped = _.groupBy(operations, (op) => {
return localISOTime(op.displayTime).substring(0, 4);
});
const entries: OpTreeNode[] = _.map(grouped, (value, key) => {
return {
key: keyPrefix + key,
title: "" + key,
children: buildTreeDay(keyPrefix, value),
};
});
entries.sort(sortByKey);
return entries;
};
const buildTreeMonth = (keyPrefix: string, operations: BackupInfo[]): OpTreeNode[] => {
const grouped = _.groupBy(operations, (op) => {
return localISOTime(op.displayTime).substring(0, 7);
});
const entries: OpTreeNode[] = _.map(grouped, (value, key) => {
return {
key: keyPrefix + key,
title: value[0].displayTime.toLocaleString("default", {
month: "long",
}),
children: buildTreeDay(keyPrefix, value),
};
});
entries.sort(sortByKey);
return entries;
};
const buildTreeDay = (keyPrefix: string, operations: BackupInfo[]): OpTreeNode[] => {
const grouped = _.groupBy(operations, (op) => {
return localISOTime(op.displayTime).substring(0, 10);
+1 -7
View File
@@ -199,7 +199,6 @@ const FileNode = ({ entry }: { entry: LsEntry }) => {
<RestoreModal
path={entry.path!}
planId={planId}
repoId={repoId}
snapshotId={snapshotId}
/>
);
@@ -228,12 +227,10 @@ const FileNode = ({ entry }: { entry: LsEntry }) => {
const RestoreModal = ({
planId,
repoId,
snapshotId,
path,
}: {
planId?: string; // optional: purely to link restore operations to the right plan.
repoId: string;
snapshotId: string;
path: string;
}) => {
@@ -260,7 +257,6 @@ const RestoreModal = ({
const values = await validateForm(form);
await backrestService.restore({
planId,
repoId,
snapshotId,
path,
target: values.target,
@@ -281,9 +277,7 @@ const RestoreModal = ({
"Restore " +
path +
" from snapshot " +
normalizeSnapshotId(snapshotId) +
" in " +
repoId
normalizeSnapshotId(snapshotId)
}
width="40vw"
footer={[
+10 -1
View File
@@ -102,6 +102,7 @@ export enum DisplayType {
FORGET,
PRUNE,
RESTORE,
STATS,
}
export interface BackupInfo {
@@ -152,7 +153,7 @@ export class BackupInfoCollector {
// use the latest status that is not cancelled.
let statusIdx = operations.length - 1;
let status = OperationStatus.STATUS_SYSTEM_CANCELLED;
while (statusIdx !== -1 && shouldHideStatus(status)) {
while (statusIdx !== -1 && (shouldHideStatus(status) || status === OperationStatus.STATUS_PENDING)) {
status = operations[statusIdx].status!;
statusIdx--;
}
@@ -263,6 +264,10 @@ export class BackupInfoCollector {
}
}
export const shouldHideOperation = (operation: Operation) => {
return operation.op.case === "operationStats" || shouldHideStatus(operation.status);
}
export const shouldHideStatus = (status: OperationStatus) => {
return status === OperationStatus.STATUS_SYSTEM_CANCELLED;
};
@@ -279,6 +284,8 @@ export const getTypeForDisplay = (op: Operation) => {
return DisplayType.PRUNE;
case "operationRestore":
return DisplayType.RESTORE;
case "operationStats":
return DisplayType.STATS;
default:
return DisplayType.UNKNOWN;
}
@@ -296,6 +303,8 @@ export const displayTypeToString = (type: DisplayType) => {
return "Prune";
case DisplayType.RESTORE:
return "Restore";
case DisplayType.STATS:
return "Stats";
default:
return "Unknown";
}
+81 -29
View File
@@ -1,6 +1,6 @@
import React from "react";
import React, { useEffect, useState } from "react";
import { Repo } from "../../gen/ts/v1/config_pb";
import { Flex, Tabs, Typography } from "antd";
import { Col, Empty, Flex, Row, Tabs, Typography } from "antd";
import { useRecoilValue } from "recoil";
import { configState } from "../state/config";
import { useAlertApi } from "../components/Alerts";
@@ -8,9 +8,30 @@ import { OperationList } from "../components/OperationList";
import { OperationTree } from "../components/OperationTree";
import { MAX_OPERATION_HISTORY } from "../constants";
import { GetOperationsRequest } from "../../gen/ts/v1/service_pb";
import { getOperations } from "../state/oplog";
import { RepoStats } from "../../gen/ts/v1/restic_pb";
import { formatBytes } from "../lib/formatting";
export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => {
const alertsApi = useAlertApi()!;
const [stats, setStats] = useState<RepoStats | null>(null);
useEffect(() => {
setStats(null);
getOperations(new GetOperationsRequest({ repoId: repo.id!, lastN: BigInt(10) })).then((operations) => {
for (const op of operations) {
if (op.op.case === "operationStats") {
const stats = op.op.value.stats;
if (stats) {
setStats(stats);
}
}
}
}).catch((e) => {
console.error(e);
});
}, [repo.id]);
// Gracefully handle deletions by checking if the plan is still in the config.
const config = useRecoilValue(configState);
@@ -20,6 +41,62 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => {
}
repo = repoInConfig;
if (!stats) {
return <Empty description="No stats available. Run a backup." />;
}
const items = [
{
key: "1",
label: "Stats",
children: (
<>
<h3>Repo Stats</h3>
<Row>
<Col style={{ paddingRight: "20px" }}>
<p><strong>Total Size: </strong></p>
<p><strong>Total Size Uncompressed: </strong></p>
<p><strong>Blob Count: </strong></p>
<p><strong>Snapshot Count: </strong></p>
<p><strong>Compression Ratio: </strong></p>
</Col>
<Col>
<p>{formatBytes(Number(stats.totalSize))}</p>
<p>{formatBytes(Number(stats.totalUncompressedSize))}</p>
<p>{Number(stats.totalBlobCount)} blobs</p>
<p>{Number(stats.snapshotCount)} snapshots</p>
<p>{Math.round(stats.compressionRatio * 1000) / 1000}</p>
</Col>
</Row>
</>
),
},
{
key: "2",
label: "Tree View",
children: (
<>
<h3>Browse Backups</h3>
<OperationTree
req={new GetOperationsRequest({ repoId: repo.id!, lastN: BigInt(MAX_OPERATION_HISTORY) })}
/>
</>
),
},
{
key: "3",
label: "Operation List",
children: (
<>
<h3>Backup Action History</h3>
<OperationList
req={new GetOperationsRequest({ repoId: repo.id!, lastN: BigInt(MAX_OPERATION_HISTORY) })}
showPlan={true}
/>
</>
),
},
]
return (
<>
<Flex gap="small" align="center" wrap="wrap">
@@ -28,33 +105,8 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => {
</Typography.Title>
</Flex>
<Tabs
defaultActiveKey="1"
items={[
{
key: "1",
label: "Tree View",
children: (
<>
<OperationTree
req={new GetOperationsRequest({ repoId: repo.id!, lastN: BigInt(MAX_OPERATION_HISTORY) })}
/>
</>
),
},
{
key: "2",
label: "Operation List",
children: (
<>
<h2>Backup Action History</h2>
<OperationList
req={new GetOperationsRequest({ repoId: repo.id!, lastN: BigInt(MAX_OPERATION_HISTORY) })}
showPlan={true}
/>
</>
),
},
]}
defaultActiveKey={items[0].key}
items={items}
/>
</>
);