mirror of
https://github.com/garethgeorge/backrest.git
synced 2026-08-24 09:56:29 +00:00
feat: display non-fatal errors in backup operations (e.g. unreadable files) in UI (#100)
This commit is contained in:
+85
-72
@@ -467,7 +467,8 @@ type OperationBackup struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
LastStatus *BackupProgressEntry `protobuf:"bytes,3,opt,name=last_status,json=lastStatus,proto3" json:"last_status,omitempty"`
|
||||
LastStatus *BackupProgressEntry `protobuf:"bytes,3,opt,name=last_status,json=lastStatus,proto3" json:"last_status,omitempty"`
|
||||
Errors []*BackupProgressError `protobuf:"bytes,4,rep,name=errors,proto3" json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
func (x *OperationBackup) Reset() {
|
||||
@@ -509,6 +510,13 @@ func (x *OperationBackup) GetLastStatus() *BackupProgressEntry {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *OperationBackup) GetErrors() []*BackupProgressError {
|
||||
if x != nil {
|
||||
return x.Errors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// OperationIndexSnapshot tracks that a snapshot was detected by backrest.
|
||||
type OperationIndexSnapshot struct {
|
||||
state protoimpl.MessageState
|
||||
@@ -907,67 +915,70 @@ var file_v1_operations_proto_rawDesc = []byte{
|
||||
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,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7c,
|
||||
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, 0x22,
|
||||
0x4b, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x48,
|
||||
0x6f, 0x6f, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75,
|
||||
0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
|
||||
0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4c, 0x6f, 0x67, 0x72, 0x65, 0x66, 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,
|
||||
0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2f, 0x0a, 0x06, 0x65,
|
||||
0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x45,
|
||||
0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 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,
|
||||
0x22, 0x4b, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e,
|
||||
0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x70,
|
||||
0x75, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4c, 0x6f, 0x67, 0x72, 0x65, 0x66, 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 (
|
||||
@@ -998,10 +1009,11 @@ var file_v1_operations_proto_goTypes = []interface{}{
|
||||
(*OperationStats)(nil), // 10: v1.OperationStats
|
||||
(*OperationRunHook)(nil), // 11: v1.OperationRunHook
|
||||
(*BackupProgressEntry)(nil), // 12: v1.BackupProgressEntry
|
||||
(*ResticSnapshot)(nil), // 13: v1.ResticSnapshot
|
||||
(*RetentionPolicy)(nil), // 14: v1.RetentionPolicy
|
||||
(*RestoreProgressEntry)(nil), // 15: v1.RestoreProgressEntry
|
||||
(*RepoStats)(nil), // 16: v1.RepoStats
|
||||
(*BackupProgressError)(nil), // 13: v1.BackupProgressError
|
||||
(*ResticSnapshot)(nil), // 14: v1.ResticSnapshot
|
||||
(*RetentionPolicy)(nil), // 15: v1.RetentionPolicy
|
||||
(*RestoreProgressEntry)(nil), // 16: v1.RestoreProgressEntry
|
||||
(*RepoStats)(nil), // 17: v1.RepoStats
|
||||
}
|
||||
var file_v1_operations_proto_depIdxs = []int32{
|
||||
3, // 0: v1.OperationList.operations:type_name -> v1.Operation
|
||||
@@ -1016,16 +1028,17 @@ var file_v1_operations_proto_depIdxs = []int32{
|
||||
0, // 9: v1.OperationEvent.type:type_name -> v1.OperationEventType
|
||||
3, // 10: v1.OperationEvent.operation:type_name -> v1.Operation
|
||||
12, // 11: v1.OperationBackup.last_status:type_name -> v1.BackupProgressEntry
|
||||
13, // 12: v1.OperationIndexSnapshot.snapshot:type_name -> v1.ResticSnapshot
|
||||
13, // 13: v1.OperationForget.forget:type_name -> v1.ResticSnapshot
|
||||
14, // 14: v1.OperationForget.policy:type_name -> v1.RetentionPolicy
|
||||
15, // 15: v1.OperationRestore.status:type_name -> v1.RestoreProgressEntry
|
||||
16, // 16: v1.OperationStats.stats:type_name -> v1.RepoStats
|
||||
17, // [17:17] is the sub-list for method output_type
|
||||
17, // [17:17] is the sub-list for method input_type
|
||||
17, // [17:17] is the sub-list for extension type_name
|
||||
17, // [17:17] is the sub-list for extension extendee
|
||||
0, // [0:17] is the sub-list for field type_name
|
||||
13, // 12: v1.OperationBackup.errors:type_name -> v1.BackupProgressError
|
||||
14, // 13: v1.OperationIndexSnapshot.snapshot:type_name -> v1.ResticSnapshot
|
||||
14, // 14: v1.OperationForget.forget:type_name -> v1.ResticSnapshot
|
||||
15, // 15: v1.OperationForget.policy:type_name -> v1.RetentionPolicy
|
||||
16, // 16: v1.OperationRestore.status:type_name -> v1.RestoreProgressEntry
|
||||
17, // 17: v1.OperationStats.stats:type_name -> v1.RepoStats
|
||||
18, // [18:18] is the sub-list for method output_type
|
||||
18, // [18:18] is the sub-list for method input_type
|
||||
18, // [18:18] is the sub-list for extension type_name
|
||||
18, // [18:18] is the sub-list for extension extendee
|
||||
0, // [0:18] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_v1_operations_proto_init() }
|
||||
|
||||
+122
-47
@@ -260,6 +260,7 @@ type BackupProgressStatusEntry struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// See https://restic.readthedocs.io/en/stable/075_scripting.html#id1
|
||||
PercentDone float64 `protobuf:"fixed64,1,opt,name=percent_done,json=percentDone,proto3" json:"percent_done,omitempty"` // 0.0 - 1.0
|
||||
TotalFiles int64 `protobuf:"varint,2,opt,name=total_files,json=totalFiles,proto3" json:"total_files,omitempty"`
|
||||
TotalBytes int64 `protobuf:"varint,3,opt,name=total_bytes,json=totalBytes,proto3" json:"total_bytes,omitempty"`
|
||||
@@ -348,6 +349,7 @@ type BackupProgressSummary struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// See https://restic.readthedocs.io/en/stable/075_scripting.html#summary
|
||||
FilesNew int64 `protobuf:"varint,1,opt,name=files_new,json=filesNew,proto3" json:"files_new,omitempty"`
|
||||
FilesChanged int64 `protobuf:"varint,2,opt,name=files_changed,json=filesChanged,proto3" json:"files_changed,omitempty"`
|
||||
FilesUnmodified int64 `protobuf:"varint,3,opt,name=files_unmodified,json=filesUnmodified,proto3" json:"files_unmodified,omitempty"`
|
||||
@@ -486,6 +488,62 @@ func (x *BackupProgressSummary) GetSnapshotId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type BackupProgressError struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// See https://restic.readthedocs.io/en/stable/075_scripting.html#error
|
||||
Item string `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
|
||||
During string `protobuf:"bytes,2,opt,name=during,proto3" json:"during,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BackupProgressError) Reset() {
|
||||
*x = BackupProgressError{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *BackupProgressError) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BackupProgressError) ProtoMessage() {}
|
||||
|
||||
func (x *BackupProgressError) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[5]
|
||||
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 BackupProgressError.ProtoReflect.Descriptor instead.
|
||||
func (*BackupProgressError) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *BackupProgressError) GetItem() string {
|
||||
if x != nil {
|
||||
return x.Item
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BackupProgressError) GetDuring() string {
|
||||
if x != nil {
|
||||
return x.During
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// RestoreProgressEvent represents a single entry in the restore progress stream.
|
||||
type RestoreProgressEntry struct {
|
||||
state protoimpl.MessageState
|
||||
@@ -504,7 +562,7 @@ type RestoreProgressEntry struct {
|
||||
func (x *RestoreProgressEntry) Reset() {
|
||||
*x = RestoreProgressEntry{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[5]
|
||||
mi := &file_v1_restic_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -517,7 +575,7 @@ func (x *RestoreProgressEntry) String() string {
|
||||
func (*RestoreProgressEntry) ProtoMessage() {}
|
||||
|
||||
func (x *RestoreProgressEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[5]
|
||||
mi := &file_v1_restic_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -530,7 +588,7 @@ func (x *RestoreProgressEntry) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RestoreProgressEntry.ProtoReflect.Descriptor instead.
|
||||
func (*RestoreProgressEntry) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{5}
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *RestoreProgressEntry) GetMessageType() string {
|
||||
@@ -597,7 +655,7 @@ type RepoStats struct {
|
||||
func (x *RepoStats) Reset() {
|
||||
*x = RepoStats{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[6]
|
||||
mi := &file_v1_restic_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -610,7 +668,7 @@ func (x *RepoStats) String() string {
|
||||
func (*RepoStats) ProtoMessage() {}
|
||||
|
||||
func (x *RepoStats) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[6]
|
||||
mi := &file_v1_restic_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -623,7 +681,7 @@ func (x *RepoStats) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RepoStats.ProtoReflect.Descriptor instead.
|
||||
func (*RepoStats) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{6}
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *RepoStats) GetTotalSize() int64 {
|
||||
@@ -738,42 +796,46 @@ var file_v1_restic_proto_rawDesc = []byte{
|
||||
0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x1f, 0x0a, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0d,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x64,
|
||||
0x22, 0x95, 0x02, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x67,
|
||||
0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x27, 0x0a, 0x0f,
|
||||
0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x45, 0x6c,
|
||||
0x61, 0x70, 0x73, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62,
|
||||
0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f,
|
||||
0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d,
|
||||
0x62, 0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x1f, 0x0a,
|
||||
0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x25,
|
||||
0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74,
|
||||
0x5f, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x70, 0x65, 0x72,
|
||||
0x63, 0x65, 0x6e, 0x74, 0x44, 0x6f, 0x6e, 0x65, 0x22, 0xe0, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x70,
|
||||
0x6f, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f,
|
||||
0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x75,
|
||||
0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x6e, 0x63,
|
||||
0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2b, 0x0a,
|
||||
0x11, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65,
|
||||
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f,
|
||||
0x74, 0x61, 0x6c, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x6c, 0x6f, 0x62, 0x43,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,
|
||||
0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x73, 0x6e,
|
||||
0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 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,
|
||||
0x22, 0x41, 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65,
|
||||
0x73, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x64,
|
||||
0x75, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x75, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x22, 0x95, 0x02, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50,
|
||||
0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x0c,
|
||||
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12,
|
||||
0x27, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x65, 0x6c, 0x61, 0x70, 0x73,
|
||||
0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64,
|
||||
0x73, 0x45, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74,
|
||||
0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x79, 0x74,
|
||||
0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x0d, 0x62, 0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64,
|
||||
0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65,
|
||||
0x73, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x73,
|
||||
0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x65, 0x72, 0x63,
|
||||
0x65, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x6e, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b,
|
||||
0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x44, 0x6f, 0x6e, 0x65, 0x22, 0xe0, 0x01, 0x0a, 0x09,
|
||||
0x52, 0x65, 0x70, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74,
|
||||
0x61, 0x6c, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74,
|
||||
0x6f, 0x74, 0x61, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x5f, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c,
|
||||
0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65,
|
||||
0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x63, 0x6f, 0x6d,
|
||||
0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x28, 0x0a,
|
||||
0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x6c,
|
||||
0x6f, 0x62, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x6e, 0x61, 0x70, 0x73,
|
||||
0x68, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 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 (
|
||||
@@ -788,15 +850,16 @@ func file_v1_restic_proto_rawDescGZIP() []byte {
|
||||
return file_v1_restic_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_v1_restic_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_v1_restic_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||
var file_v1_restic_proto_goTypes = []interface{}{
|
||||
(*ResticSnapshot)(nil), // 0: v1.ResticSnapshot
|
||||
(*ResticSnapshotList)(nil), // 1: v1.ResticSnapshotList
|
||||
(*BackupProgressEntry)(nil), // 2: v1.BackupProgressEntry
|
||||
(*BackupProgressStatusEntry)(nil), // 3: v1.BackupProgressStatusEntry
|
||||
(*BackupProgressSummary)(nil), // 4: v1.BackupProgressSummary
|
||||
(*RestoreProgressEntry)(nil), // 5: v1.RestoreProgressEntry
|
||||
(*RepoStats)(nil), // 6: v1.RepoStats
|
||||
(*BackupProgressError)(nil), // 5: v1.BackupProgressError
|
||||
(*RestoreProgressEntry)(nil), // 6: v1.RestoreProgressEntry
|
||||
(*RepoStats)(nil), // 7: v1.RepoStats
|
||||
}
|
||||
var file_v1_restic_proto_depIdxs = []int32{
|
||||
0, // 0: v1.ResticSnapshotList.snapshots:type_name -> v1.ResticSnapshot
|
||||
@@ -876,7 +939,7 @@ func file_v1_restic_proto_init() {
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RestoreProgressEntry); i {
|
||||
switch v := v.(*BackupProgressError); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -888,6 +951,18 @@ func file_v1_restic_proto_init() {
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RestoreProgressEntry); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RepoStats); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -910,7 +985,7 @@ func file_v1_restic_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_v1_restic_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 7,
|
||||
NumMessages: 8,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -15,6 +15,8 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var maxBackupErrorHistoryLength = 20 // arbitrary limit on the number of file read errors recorded in a backup operation to prevent it from growing too large.
|
||||
|
||||
// BackupTask is a scheduled backup operation.
|
||||
type BackupTask struct {
|
||||
name string
|
||||
@@ -119,16 +121,32 @@ func backupHelper(ctx context.Context, t Task, orchestrator *Orchestrator, plan
|
||||
}
|
||||
lastSent = time.Now()
|
||||
|
||||
// prevents flickering output when a status entry omits the CurrentFiles property. Largely cosmetic.
|
||||
if len(entry.CurrentFiles) == 0 {
|
||||
entry.CurrentFiles = lastFiles
|
||||
} else {
|
||||
lastFiles = entry.CurrentFiles
|
||||
}
|
||||
if entry.MessageType == "status" {
|
||||
// prevents flickering output when a status entry omits the CurrentFiles property. Largely cosmetic.
|
||||
if len(entry.CurrentFiles) == 0 {
|
||||
entry.CurrentFiles = lastFiles
|
||||
} else {
|
||||
lastFiles = entry.CurrentFiles
|
||||
}
|
||||
|
||||
backupOp.OperationBackup.LastStatus = protoutil.BackupProgressEntryToProto(entry)
|
||||
if err := orchestrator.OpLog.Update(op); err != nil {
|
||||
zap.S().Errorf("failed to update oplog with progress for backup: %v", err)
|
||||
backupOp.OperationBackup.LastStatus = protoutil.BackupProgressEntryToProto(entry)
|
||||
if err := orchestrator.OpLog.Update(op); err != nil {
|
||||
zap.S().Errorf("failed to update oplog with progress for backup: %v", err)
|
||||
}
|
||||
} else if entry.MessageType == "error" {
|
||||
zap.S().Warnf("backup error: %v", entry.Error)
|
||||
backupError, err := protoutil.BackupProgressEntryToBackupError(entry)
|
||||
if err != nil {
|
||||
zap.S().Errorf("failed to convert backup progress entry to backup error: %v", err)
|
||||
return
|
||||
}
|
||||
if len(backupOp.OperationBackup.Errors) > maxBackupErrorHistoryLength {
|
||||
zap.S().Warnf("too many errors, not adding more to backup entry.")
|
||||
return
|
||||
}
|
||||
backupOp.OperationBackup.Errors = append(backupOp.OperationBackup.Errors, backupError)
|
||||
} else if entry.MessageType != "summary" {
|
||||
zap.S().Warnf("unexpected message type %q in backup progress entry", entry.MessageType)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package protoutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
v1 "github.com/garethgeorge/backrest/gen/go/v1"
|
||||
"github.com/garethgeorge/backrest/pkg/restic"
|
||||
)
|
||||
@@ -73,6 +75,18 @@ func BackupProgressEntryToProto(b *restic.BackupProgressEntry) *v1.BackupProgres
|
||||
}
|
||||
}
|
||||
|
||||
// BackupProgressEntryToBackupError converts a BackupProgressEntry to a BackupError if it's type is "error"
|
||||
func BackupProgressEntryToBackupError(b *restic.BackupProgressEntry) (*v1.BackupProgressError, error) {
|
||||
if b.MessageType != "error" {
|
||||
return nil, errors.New("BackupProgressEntry is not of type error")
|
||||
}
|
||||
|
||||
return &v1.BackupProgressError{
|
||||
Item: b.Item,
|
||||
During: b.During,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func RetentionPolicyFromProto(p *v1.RetentionPolicy) *restic.RetentionPolicy {
|
||||
return &restic.RetentionPolicy{
|
||||
KeepLastN: int(p.KeepLastN),
|
||||
|
||||
@@ -49,7 +49,12 @@ func (s *Snapshot) Validate() error {
|
||||
|
||||
type BackupProgressEntry struct {
|
||||
// Common fields
|
||||
MessageType string `json:"message_type"` // "summary" or "status"
|
||||
MessageType string `json:"message_type"` // "summary" or "status" or "error"
|
||||
|
||||
// Error fields
|
||||
Error any `json:"error"`
|
||||
During string `json:"during"`
|
||||
Item string `json:"item"`
|
||||
|
||||
// Summary fields
|
||||
FilesNew int `json:"files_new"`
|
||||
|
||||
@@ -3,6 +3,7 @@ package restic
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"slices"
|
||||
@@ -43,6 +44,8 @@ func TestResticBackup(t *testing.T) {
|
||||
|
||||
testData := helpers.CreateTestData(t)
|
||||
testData2 := helpers.CreateTestData(t)
|
||||
testDataUnreadable := t.TempDir()
|
||||
helpers.CreateUnreadable(t, testDataUnreadable+"/unreadable")
|
||||
|
||||
var tests = []struct {
|
||||
name string
|
||||
@@ -75,6 +78,11 @@ func TestResticBackup(t *testing.T) {
|
||||
opts: []BackupOption{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "with unreadable file",
|
||||
opts: []BackupOption{WithBackupPaths(testData), WithBackupPaths(testDataUnreadable)},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
@@ -107,6 +115,46 @@ func TestResticBackup(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestResticPartialBackup(t *testing.T) {
|
||||
t.Parallel()
|
||||
repo := t.TempDir()
|
||||
|
||||
// create a new repo with cache disabled for testing
|
||||
r := NewRepo(helpers.ResticBinary(t), &v1.Repo{
|
||||
Id: "test",
|
||||
Uri: repo,
|
||||
Password: "test",
|
||||
}, WithFlags("--no-cache"))
|
||||
if err := r.Init(context.Background()); err != nil {
|
||||
t.Fatalf("failed to init repo: %v", err)
|
||||
}
|
||||
|
||||
testDataUnreadable := t.TempDir()
|
||||
helpers.CreateUnreadable(t, testDataUnreadable+"/unreadable")
|
||||
|
||||
var entries []*BackupProgressEntry
|
||||
|
||||
summary, err := r.Backup(context.Background(), func(entry *BackupProgressEntry) {
|
||||
entries = append(entries, entry)
|
||||
}, WithBackupPaths(testDataUnreadable))
|
||||
if !errors.Is(err, ErrPartialBackup) {
|
||||
t.Fatalf("wanted error to be partial backup, got: %v", err)
|
||||
}
|
||||
if summary == nil {
|
||||
t.Fatalf("wanted summary, got: nil")
|
||||
}
|
||||
|
||||
if summary.TotalFilesProcessed != 0 {
|
||||
t.Errorf("wanted 0 files, got: %d", summary.TotalFilesProcessed)
|
||||
}
|
||||
|
||||
if !slices.ContainsFunc(entries, func(e *BackupProgressEntry) bool {
|
||||
return e.MessageType == "error" && e.Item == testDataUnreadable+"/unreadable"
|
||||
}) {
|
||||
t.Errorf("wanted entries to contain an error event for the unreadable file, got: %v", entries)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResticBackupLots(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Skip("this test takes a long time to run")
|
||||
|
||||
@@ -66,6 +66,7 @@ enum OperationStatus {
|
||||
|
||||
message OperationBackup {
|
||||
BackupProgressEntry last_status = 3;
|
||||
repeated BackupProgressError errors = 4;
|
||||
}
|
||||
|
||||
// OperationIndexSnapshot tracks that a snapshot was detected by backrest.
|
||||
|
||||
@@ -31,6 +31,7 @@ message BackupProgressEntry {
|
||||
|
||||
// BackupProgressStatusEntry represents a single status entry in the backup progress stream.
|
||||
message BackupProgressStatusEntry {
|
||||
// See https://restic.readthedocs.io/en/stable/075_scripting.html#id1
|
||||
double percent_done = 1; // 0.0 - 1.0
|
||||
int64 total_files = 2;
|
||||
int64 total_bytes = 3;
|
||||
@@ -41,6 +42,7 @@ message BackupProgressStatusEntry {
|
||||
|
||||
// BackupProgressSummary represents a the summary event emitted at the end of a backup stream.
|
||||
message BackupProgressSummary {
|
||||
// See https://restic.readthedocs.io/en/stable/075_scripting.html#summary
|
||||
int64 files_new = 1;
|
||||
int64 files_changed = 2;
|
||||
int64 files_unmodified = 3;
|
||||
@@ -56,6 +58,13 @@ message BackupProgressSummary {
|
||||
string snapshot_id = 13;
|
||||
}
|
||||
|
||||
message BackupProgressError {
|
||||
// See https://restic.readthedocs.io/en/stable/075_scripting.html#error
|
||||
string item = 1;
|
||||
string during = 2;
|
||||
string message = 3;
|
||||
}
|
||||
|
||||
// RestoreProgressEvent represents a single entry in the restore progress stream.
|
||||
message RestoreProgressEntry {
|
||||
string message_type = 1; // "summary" or "status"
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
func CreateTestData(t *testing.T) string {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
err := os.WriteFile(path.Join(dir, fmt.Sprintf("file%2d", i)), []byte(fmt.Sprintf("test data %d", i)), 0644)
|
||||
if err != nil {
|
||||
@@ -18,4 +18,14 @@ func CreateTestData(t *testing.T) string {
|
||||
}
|
||||
}
|
||||
return dir
|
||||
}
|
||||
}
|
||||
|
||||
func CreateUnreadable(t *testing.T, path string) {
|
||||
t.Helper()
|
||||
|
||||
// Create a file that can be written but can't be read by the current user
|
||||
err := os.WriteFile(path, []byte("test data"), 0200)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create unreadable file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
|
||||
import { Message, proto3, protoInt64 } from "@bufbuild/protobuf";
|
||||
import { BackupProgressEntry, RepoStats, ResticSnapshot, RestoreProgressEntry } from "./restic_pb.js";
|
||||
import { BackupProgressEntry, BackupProgressError, RepoStats, ResticSnapshot, RestoreProgressEntry } from "./restic_pb.js";
|
||||
import { RetentionPolicy } from "./config_pb.js";
|
||||
|
||||
/**
|
||||
@@ -352,6 +352,11 @@ export class OperationBackup extends Message<OperationBackup> {
|
||||
*/
|
||||
lastStatus?: BackupProgressEntry;
|
||||
|
||||
/**
|
||||
* @generated from field: repeated v1.BackupProgressError errors = 4;
|
||||
*/
|
||||
errors: BackupProgressError[] = [];
|
||||
|
||||
constructor(data?: PartialMessage<OperationBackup>) {
|
||||
super();
|
||||
proto3.util.initPartial(data, this);
|
||||
@@ -361,6 +366,7 @@ export class OperationBackup extends Message<OperationBackup> {
|
||||
static readonly typeName = "v1.OperationBackup";
|
||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||
{ no: 3, name: "last_status", kind: "message", T: BackupProgressEntry },
|
||||
{ no: 4, name: "errors", kind: "message", T: BackupProgressError, repeated: true },
|
||||
]);
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): OperationBackup {
|
||||
|
||||
@@ -189,6 +189,8 @@ export class BackupProgressEntry extends Message<BackupProgressEntry> {
|
||||
*/
|
||||
export class BackupProgressStatusEntry extends Message<BackupProgressStatusEntry> {
|
||||
/**
|
||||
* See https://restic.readthedocs.io/en/stable/075_scripting.html#id1
|
||||
*
|
||||
* 0.0 - 1.0
|
||||
*
|
||||
* @generated from field: double percent_done = 1;
|
||||
@@ -260,6 +262,8 @@ export class BackupProgressStatusEntry extends Message<BackupProgressStatusEntry
|
||||
*/
|
||||
export class BackupProgressSummary extends Message<BackupProgressSummary> {
|
||||
/**
|
||||
* See https://restic.readthedocs.io/en/stable/075_scripting.html#summary
|
||||
*
|
||||
* @generated from field: int64 files_new = 1;
|
||||
*/
|
||||
filesNew = protoInt64.zero;
|
||||
@@ -364,6 +368,51 @@ export class BackupProgressSummary extends Message<BackupProgressSummary> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message v1.BackupProgressError
|
||||
*/
|
||||
export class BackupProgressError extends Message<BackupProgressError> {
|
||||
/**
|
||||
* See https://restic.readthedocs.io/en/stable/075_scripting.html#error
|
||||
*
|
||||
* @generated from field: string item = 1;
|
||||
*/
|
||||
item = "";
|
||||
|
||||
/**
|
||||
* @generated from field: string during = 2;
|
||||
*/
|
||||
during = "";
|
||||
|
||||
constructor(data?: PartialMessage<BackupProgressError>) {
|
||||
super();
|
||||
proto3.util.initPartial(data, this);
|
||||
}
|
||||
|
||||
static readonly runtime: typeof proto3 = proto3;
|
||||
static readonly typeName = "v1.BackupProgressError";
|
||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||
{ no: 1, name: "item", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "during", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
]);
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): BackupProgressError {
|
||||
return new BackupProgressError().fromBinary(bytes, options);
|
||||
}
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): BackupProgressError {
|
||||
return new BackupProgressError().fromJson(jsonValue, options);
|
||||
}
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): BackupProgressError {
|
||||
return new BackupProgressError().fromJsonString(jsonString, options);
|
||||
}
|
||||
|
||||
static equals(a: BackupProgressError | PlainMessage<BackupProgressError> | undefined, b: BackupProgressError | PlainMessage<BackupProgressError> | undefined): boolean {
|
||||
return proto3.util.equals(BackupProgressError, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RestoreProgressEvent represents a single entry in the restore progress stream.
|
||||
*
|
||||
|
||||
@@ -210,19 +210,29 @@ export const OperationRow = ({
|
||||
|
||||
if (operation.op.case === "operationBackup") {
|
||||
const backupOp = operation.op.value;
|
||||
const items: { key: number, label: string, children: React.ReactNode }[] = [
|
||||
{
|
||||
key: 1,
|
||||
label: "Backup Details",
|
||||
children: <BackupOperationStatus status={backupOp.lastStatus} />,
|
||||
},
|
||||
];
|
||||
|
||||
if (backupOp.errors.length > 0) {
|
||||
items.splice(0, 0, {
|
||||
key: 2,
|
||||
label: "Item Errors",
|
||||
children: <pre>{backupOp.errors.map(e => "Error on item: " + e.item).join("\n")}</pre>,
|
||||
});
|
||||
}
|
||||
|
||||
body = (
|
||||
<>
|
||||
<Collapse
|
||||
size="small"
|
||||
destroyInactivePanel
|
||||
defaultActiveKey={[1]}
|
||||
items={[
|
||||
{
|
||||
key: 1,
|
||||
label: "Backup Details",
|
||||
children: <BackupOperationStatus status={backupOp.lastStatus} />,
|
||||
},
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user