From aad45ec9f9fb0053082d58cbf7f70519829902b8 Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Sun, 26 May 2024 23:14:42 -0700 Subject: [PATCH 01/14] proto changes for restic check operation --- gen/go/v1/config.pb.go | 235 +++++++++-------- gen/go/v1/operations.pb.go | 319 ++++++++++++++--------- internal/orchestrator/tasks/taskcheck.go | 166 ++++++++++++ proto/v1/operations.proto | 9 + webui/gen/ts/v1/config_pb.ts | 13 +- webui/gen/ts/v1/operations_pb.ts | 54 ++++ 6 files changed, 569 insertions(+), 227 deletions(-) create mode 100644 internal/orchestrator/tasks/taskcheck.go diff --git a/gen/go/v1/config.pb.go b/gen/go/v1/config.pb.go index 6e0f255e..5f6d3b33 100644 --- a/gen/go/v1/config.pb.go +++ b/gen/go/v1/config.pb.go @@ -813,6 +813,7 @@ type CheckPolicy struct { Schedule *Schedule `protobuf:"bytes,1,opt,name=schedule,proto3" json:"schedule,omitempty"` // Types that are assignable to ReadPolicy: // + // *CheckPolicy_Disabled // *CheckPolicy_ReadPercent ReadPolicy isCheckPolicy_ReadPolicy `protobuf_oneof:"read_policy"` } @@ -863,6 +864,13 @@ func (m *CheckPolicy) GetReadPolicy() isCheckPolicy_ReadPolicy { return nil } +func (x *CheckPolicy) GetDisabled() bool { + if x, ok := x.GetReadPolicy().(*CheckPolicy_Disabled); ok { + return x.Disabled + } + return false +} + func (x *CheckPolicy) GetReadPercent() int32 { if x, ok := x.GetReadPolicy().(*CheckPolicy_ReadPercent); ok { return x.ReadPercent @@ -874,10 +882,16 @@ type isCheckPolicy_ReadPolicy interface { isCheckPolicy_ReadPolicy() } +type CheckPolicy_Disabled struct { + Disabled bool `protobuf:"varint,100,opt,name=disabled,proto3,oneof"` // disable the check. +} + type CheckPolicy_ReadPercent struct { - ReadPercent int32 `protobuf:"varint,11,opt,name=read_percent,json=readPercent,proto3,oneof"` // check a percentage of snapshots. + ReadPercent int32 `protobuf:"varint,101,opt,name=read_percent,json=readPercent,proto3,oneof"` // check a percentage of snapshots. } +func (*CheckPolicy_Disabled) isCheckPolicy_ReadPolicy() {} + func (*CheckPolicy_ReadPercent) isCheckPolicy_ReadPolicy() {} type Schedule struct { @@ -1870,116 +1884,118 @@ var file_v1_config_proto_rawDesc = []byte{ 0x61, 0x78, 0x55, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x55, 0x6e, - 0x75, 0x73, 0x65, 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, 0x6b, 0x0a, 0x0b, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x08, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x08, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, - 0x63, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0b, 0x72, 0x65, - 0x61, 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x72, 0x65, 0x61, - 0x64, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0xa8, 0x01, 0x0a, 0x08, 0x53, 0x63, 0x68, + 0x75, 0x73, 0x65, 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, 0x89, 0x01, 0x0a, 0x0b, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x08, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x10, 0x6d, 0x61, 0x78, - 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x44, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x6e, 0x63, 0x79, 0x44, 0x61, 0x79, 0x73, 0x12, 0x2e, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x46, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x05, 0x48, 0x00, 0x52, 0x11, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, - 0x75, 0x6c, 0x65, 0x22, 0xec, 0x09, 0x0a, 0x04, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x32, 0x0a, 0x0a, - 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, - 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x2b, 0x0a, 0x08, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x4f, 0x6e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x07, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x39, 0x0a, - 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, - 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, - 0x6f, 0x6b, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x65, 0x62, 0x68, - 0x6f, 0x6f, 0x6b, 0x12, 0x39, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x69, - 0x73, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, - 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, - 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x36, - 0x0a, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x67, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x18, - 0x67, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, - 0x47, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x47, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x33, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x18, 0x68, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, - 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0b, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x3c, 0x0a, 0x0f, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x18, 0x69, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x53, - 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x48, 0x00, 0x52, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x1a, 0x23, 0x0a, 0x07, 0x43, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x1a, 0xa1, - 0x01, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x65, - 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x2f, 0x0a, 0x06, 0x6d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x76, 0x31, - 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1a, 0x0a, 0x08, - 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, - 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, - 0x10, 0x02, 0x1a, 0x46, 0x0a, 0x07, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x1f, 0x0a, - 0x0b, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x1a, - 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x7c, 0x0a, 0x06, 0x47, 0x6f, - 0x74, 0x69, 0x66, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, - 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, - 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x18, 0x65, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x69, 0x74, 0x6c, 0x65, - 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x44, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, - 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, - 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x49, - 0x0a, 0x08, 0x53, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x68, - 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x73, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, + 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x63, + 0x65, 0x6e, 0x74, 0x18, 0x65, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0b, 0x72, 0x65, 0x61, + 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64, + 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0xa8, 0x01, 0x0a, 0x08, 0x53, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x46, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x44, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x48, 0x00, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x79, 0x44, 0x61, 0x79, 0x73, 0x12, 0x2e, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x05, 0x48, 0x00, 0x52, 0x11, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x22, 0xec, 0x09, 0x0a, 0x04, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x32, 0x0a, 0x0a, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x2b, 0x0a, 0x08, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x4f, 0x6e, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x07, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x39, 0x0a, 0x0e, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x64, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x65, 0x62, 0x68, 0x6f, + 0x6f, 0x6b, 0x12, 0x39, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x69, 0x73, + 0x63, 0x6f, 0x72, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, + 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, 0x0d, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x36, 0x0a, + 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x67, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x18, 0x67, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x47, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x47, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x33, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x18, 0x68, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31, + 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0b, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x3c, 0x0a, 0x0f, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x18, 0x69, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x53, 0x68, + 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x48, 0x00, 0x52, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x1a, 0x23, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x1a, 0xa1, 0x01, + 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x2f, 0x0a, 0x06, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, + 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, + 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, + 0x02, 0x1a, 0x46, 0x0a, 0x07, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x1f, 0x0a, 0x0b, + 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x09, 0x43, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x44, 0x49, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x17, - 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4e, 0x59, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x44, 0x49, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x53, 0x54, - 0x41, 0x52, 0x54, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x45, 0x4e, 0x44, 0x10, - 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, - 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, - 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, - 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x22, - 0x47, 0x0a, 0x07, 0x4f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x4e, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, - 0x13, 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x41, 0x4e, 0x43, - 0x45, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x02, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0x42, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x51, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x62, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x0a, 0x0a, - 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 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, + 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x7c, 0x0a, 0x06, 0x47, 0x6f, 0x74, + 0x69, 0x66, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x18, 0x65, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x44, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, 0x6b, + 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, + 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x49, 0x0a, + 0x08, 0x53, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x68, 0x6f, + 0x75, 0x74, 0x72, 0x72, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x73, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x17, 0x0a, + 0x13, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4e, 0x59, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x53, 0x54, 0x41, + 0x52, 0x54, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x45, 0x4e, 0x44, 0x10, 0x03, + 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, + 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x1e, + 0x0a, 0x1a, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, + 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x22, 0x47, + 0x0a, 0x07, 0x4f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x13, + 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, + 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x02, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x42, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, + 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x51, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x62, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x0a, 0x0a, 0x08, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 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 ( @@ -2292,6 +2308,7 @@ func file_v1_config_proto_init() { (*RetentionPolicy_PolicyKeepAll)(nil), } file_v1_config_proto_msgTypes[6].OneofWrappers = []interface{}{ + (*CheckPolicy_Disabled)(nil), (*CheckPolicy_ReadPercent)(nil), } file_v1_config_proto_msgTypes[7].OneofWrappers = []interface{}{ diff --git a/gen/go/v1/operations.pb.go b/gen/go/v1/operations.pb.go index 166341e6..047fe637 100644 --- a/gen/go/v1/operations.pb.go +++ b/gen/go/v1/operations.pb.go @@ -216,6 +216,7 @@ type Operation struct { // *Operation_OperationRestore // *Operation_OperationStats // *Operation_OperationRunHook + // *Operation_OperationCheck Op isOperation_Op `protobuf_oneof:"op"` } @@ -384,6 +385,13 @@ func (x *Operation) GetOperationRunHook() *OperationRunHook { return nil } +func (x *Operation) GetOperationCheck() *OperationCheck { + if x, ok := x.GetOp().(*Operation_OperationCheck); ok { + return x.OperationCheck + } + return nil +} + type isOperation_Op interface { isOperation_Op() } @@ -416,6 +424,10 @@ type Operation_OperationRunHook struct { OperationRunHook *OperationRunHook `protobuf:"bytes,106,opt,name=operation_run_hook,json=operationRunHook,proto3,oneof"` } +type Operation_OperationCheck struct { + OperationCheck *OperationCheck `protobuf:"bytes,107,opt,name=operation_check,json=operationCheck,proto3,oneof"` +} + func (*Operation_OperationBackup) isOperation_Op() {} func (*Operation_OperationIndexSnapshot) isOperation_Op() {} @@ -430,6 +442,8 @@ func (*Operation_OperationStats) isOperation_Op() {} func (*Operation_OperationRunHook) isOperation_Op() {} +func (*Operation_OperationCheck) isOperation_Op() {} + // OperationEvent is used in the wireformat to stream operation changes to clients type OperationEvent struct { state protoimpl.MessageState @@ -709,6 +723,55 @@ func (x *OperationPrune) GetOutput() string { return "" } +// OperationCheck tracks a check operation. +type OperationCheck struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Output string `protobuf:"bytes,1,opt,name=output,proto3" json:"output,omitempty"` // output of the check operation. +} + +func (x *OperationCheck) Reset() { + *x = OperationCheck{} + if protoimpl.UnsafeEnabled { + mi := &file_v1_operations_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OperationCheck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OperationCheck) ProtoMessage() {} + +func (x *OperationCheck) ProtoReflect() protoreflect.Message { + mi := &file_v1_operations_proto_msgTypes[7] + 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 OperationCheck.ProtoReflect.Descriptor instead. +func (*OperationCheck) Descriptor() ([]byte, []int) { + return file_v1_operations_proto_rawDescGZIP(), []int{7} +} + +func (x *OperationCheck) GetOutput() string { + if x != nil { + return x.Output + } + return "" +} + +// OperationRestore tracks a restore operation. type OperationRestore struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -722,7 +785,7 @@ type OperationRestore struct { func (x *OperationRestore) Reset() { *x = OperationRestore{} if protoimpl.UnsafeEnabled { - mi := &file_v1_operations_proto_msgTypes[7] + mi := &file_v1_operations_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -735,7 +798,7 @@ func (x *OperationRestore) String() string { func (*OperationRestore) ProtoMessage() {} func (x *OperationRestore) ProtoReflect() protoreflect.Message { - mi := &file_v1_operations_proto_msgTypes[7] + mi := &file_v1_operations_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -748,7 +811,7 @@ func (x *OperationRestore) ProtoReflect() protoreflect.Message { // Deprecated: Use OperationRestore.ProtoReflect.Descriptor instead. func (*OperationRestore) Descriptor() ([]byte, []int) { - return file_v1_operations_proto_rawDescGZIP(), []int{7} + return file_v1_operations_proto_rawDescGZIP(), []int{8} } func (x *OperationRestore) GetPath() string { @@ -772,6 +835,7 @@ func (x *OperationRestore) GetStatus() *RestoreProgressEntry { return nil } +// OperationStats tracks a stats operation. type OperationStats struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -783,7 +847,7 @@ type OperationStats struct { func (x *OperationStats) Reset() { *x = OperationStats{} if protoimpl.UnsafeEnabled { - mi := &file_v1_operations_proto_msgTypes[8] + mi := &file_v1_operations_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -796,7 +860,7 @@ func (x *OperationStats) String() string { func (*OperationStats) ProtoMessage() {} func (x *OperationStats) ProtoReflect() protoreflect.Message { - mi := &file_v1_operations_proto_msgTypes[8] + mi := &file_v1_operations_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -809,7 +873,7 @@ func (x *OperationStats) ProtoReflect() protoreflect.Message { // Deprecated: Use OperationStats.ProtoReflect.Descriptor instead. func (*OperationStats) Descriptor() ([]byte, []int) { - return file_v1_operations_proto_rawDescGZIP(), []int{8} + return file_v1_operations_proto_rawDescGZIP(), []int{9} } func (x *OperationStats) GetStats() *RepoStats { @@ -819,6 +883,7 @@ func (x *OperationStats) GetStats() *RepoStats { return nil } +// OperationRunHook tracks a hook that was run. type OperationRunHook struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -832,7 +897,7 @@ type OperationRunHook struct { func (x *OperationRunHook) Reset() { *x = OperationRunHook{} if protoimpl.UnsafeEnabled { - mi := &file_v1_operations_proto_msgTypes[9] + mi := &file_v1_operations_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -845,7 +910,7 @@ func (x *OperationRunHook) String() string { func (*OperationRunHook) ProtoMessage() {} func (x *OperationRunHook) ProtoReflect() protoreflect.Message { - mi := &file_v1_operations_proto_msgTypes[9] + mi := &file_v1_operations_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -858,7 +923,7 @@ func (x *OperationRunHook) ProtoReflect() protoreflect.Message { // Deprecated: Use OperationRunHook.ProtoReflect.Descriptor instead. func (*OperationRunHook) Descriptor() ([]byte, []int) { - return file_v1_operations_proto_rawDescGZIP(), []int{9} + return file_v1_operations_proto_rawDescGZIP(), []int{10} } func (x *OperationRunHook) GetName() string { @@ -892,7 +957,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, 0xd7, 0x06, 0x0a, 0x09, + 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x96, 0x07, 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, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, @@ -945,80 +1010,87 @@ var file_v1_operations_proto_rawDesc = []byte{ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x6a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x48, 0x6f, 0x6f, 0x6b, 0x48, 0x00, 0x52, 0x10, 0x6f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x48, 0x6f, 0x6f, 0x6b, 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, 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, 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, 0x7d, 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, 0x12, - 0x30, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 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, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6e, 0x48, 0x6f, 0x6f, 0x6b, 0x12, + 0x3d, 0x0a, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x18, 0x6b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0e, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 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, + 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, 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, 0x28, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x65, 0x63, 0x6b, 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, 0x7d, 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, 0x12, 0x30, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x76, 0x31, + 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 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 ( @@ -1034,7 +1106,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, 10) +var file_v1_operations_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_v1_operations_proto_goTypes = []interface{}{ (OperationEventType)(0), // 0: v1.OperationEventType (OperationStatus)(0), // 1: v1.OperationStatus @@ -1045,16 +1117,17 @@ var file_v1_operations_proto_goTypes = []interface{}{ (*OperationIndexSnapshot)(nil), // 6: v1.OperationIndexSnapshot (*OperationForget)(nil), // 7: v1.OperationForget (*OperationPrune)(nil), // 8: v1.OperationPrune - (*OperationRestore)(nil), // 9: v1.OperationRestore - (*OperationStats)(nil), // 10: v1.OperationStats - (*OperationRunHook)(nil), // 11: v1.OperationRunHook - (*BackupProgressEntry)(nil), // 12: v1.BackupProgressEntry - (*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 - (Hook_Condition)(0), // 18: v1.Hook.Condition + (*OperationCheck)(nil), // 9: v1.OperationCheck + (*OperationRestore)(nil), // 10: v1.OperationRestore + (*OperationStats)(nil), // 11: v1.OperationStats + (*OperationRunHook)(nil), // 12: v1.OperationRunHook + (*BackupProgressEntry)(nil), // 13: v1.BackupProgressEntry + (*BackupProgressError)(nil), // 14: v1.BackupProgressError + (*ResticSnapshot)(nil), // 15: v1.ResticSnapshot + (*RetentionPolicy)(nil), // 16: v1.RetentionPolicy + (*RestoreProgressEntry)(nil), // 17: v1.RestoreProgressEntry + (*RepoStats)(nil), // 18: v1.RepoStats + (Hook_Condition)(0), // 19: v1.Hook.Condition } var file_v1_operations_proto_depIdxs = []int32{ 3, // 0: v1.OperationList.operations:type_name -> v1.Operation @@ -1063,24 +1136,25 @@ var file_v1_operations_proto_depIdxs = []int32{ 6, // 3: v1.Operation.operation_index_snapshot:type_name -> v1.OperationIndexSnapshot 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 - 10, // 7: v1.Operation.operation_stats:type_name -> v1.OperationStats - 11, // 8: v1.Operation.operation_run_hook:type_name -> v1.OperationRunHook - 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.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: v1.OperationRunHook.condition:type_name -> v1.Hook.Condition - 19, // [19:19] is the sub-list for method output_type - 19, // [19:19] is the sub-list for method input_type - 19, // [19:19] is the sub-list for extension type_name - 19, // [19:19] is the sub-list for extension extendee - 0, // [0:19] is the sub-list for field type_name + 10, // 6: v1.Operation.operation_restore:type_name -> v1.OperationRestore + 11, // 7: v1.Operation.operation_stats:type_name -> v1.OperationStats + 12, // 8: v1.Operation.operation_run_hook:type_name -> v1.OperationRunHook + 9, // 9: v1.Operation.operation_check:type_name -> v1.OperationCheck + 0, // 10: v1.OperationEvent.type:type_name -> v1.OperationEventType + 3, // 11: v1.OperationEvent.operation:type_name -> v1.Operation + 13, // 12: v1.OperationBackup.last_status:type_name -> v1.BackupProgressEntry + 14, // 13: v1.OperationBackup.errors:type_name -> v1.BackupProgressError + 15, // 14: v1.OperationIndexSnapshot.snapshot:type_name -> v1.ResticSnapshot + 15, // 15: v1.OperationForget.forget:type_name -> v1.ResticSnapshot + 16, // 16: v1.OperationForget.policy:type_name -> v1.RetentionPolicy + 17, // 17: v1.OperationRestore.status:type_name -> v1.RestoreProgressEntry + 18, // 18: v1.OperationStats.stats:type_name -> v1.RepoStats + 19, // 19: v1.OperationRunHook.condition:type_name -> v1.Hook.Condition + 20, // [20:20] is the sub-list for method output_type + 20, // [20:20] is the sub-list for method input_type + 20, // [20:20] is the sub-list for extension type_name + 20, // [20:20] is the sub-list for extension extendee + 0, // [0:20] is the sub-list for field type_name } func init() { file_v1_operations_proto_init() } @@ -1176,7 +1250,7 @@ func file_v1_operations_proto_init() { } } file_v1_operations_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OperationRestore); i { + switch v := v.(*OperationCheck); i { case 0: return &v.state case 1: @@ -1188,7 +1262,7 @@ func file_v1_operations_proto_init() { } } file_v1_operations_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OperationStats); i { + switch v := v.(*OperationRestore); i { case 0: return &v.state case 1: @@ -1200,6 +1274,18 @@ func file_v1_operations_proto_init() { } } file_v1_operations_proto_msgTypes[9].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[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OperationRunHook); i { case 0: return &v.state @@ -1220,6 +1306,7 @@ func file_v1_operations_proto_init() { (*Operation_OperationRestore)(nil), (*Operation_OperationStats)(nil), (*Operation_OperationRunHook)(nil), + (*Operation_OperationCheck)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1227,7 +1314,7 @@ func file_v1_operations_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_v1_operations_proto_rawDesc, NumEnums: 2, - NumMessages: 10, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/orchestrator/tasks/taskcheck.go b/internal/orchestrator/tasks/taskcheck.go new file mode 100644 index 00000000..2648769a --- /dev/null +++ b/internal/orchestrator/tasks/taskcheck.go @@ -0,0 +1,166 @@ +package tasks + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + v1 "github.com/garethgeorge/backrest/gen/go/v1" + "github.com/garethgeorge/backrest/internal/hook" + "github.com/garethgeorge/backrest/internal/ioutil" + "github.com/garethgeorge/backrest/internal/oplog" + "github.com/garethgeorge/backrest/internal/oplog/indexutil" + "github.com/garethgeorge/backrest/internal/protoutil" + "go.uber.org/zap" +) + +type CheckTask struct { + BaseTask + force bool + didRun bool +} + +func NewCheckTask(repoID, planID string, force bool) Task { + return &CheckTask{ + BaseTask: BaseTask{ + TaskName: fmt.Sprintf("prune repo %q", repoID), + TaskRepoID: repoID, + TaskPlanID: planID, + }, + force: force, + } +} + +func (t *CheckTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, error) { + if t.force { + if t.didRun { + return NeverScheduledTask, nil + } + t.didRun = true + return ScheduledTask{ + Task: t, + RunAt: now, + Op: &v1.Operation{ + Op: &v1.Operation_OperationPrune{}, + }, + }, nil + } + + repo, err := runner.GetRepo(t.RepoID()) + if err != nil { + return ScheduledTask{}, fmt.Errorf("get repo %v: %w", t.RepoID(), err) + } + + if repo.PrunePolicy.GetSchedule() == nil { + return NeverScheduledTask, nil + } + + var lastRan time.Time + if err := runner.OpLog().ForEach(oplog.Query{RepoId: t.RepoID()}, indexutil.Reversed(indexutil.CollectAll()), func(op *v1.Operation) error { + if _, ok := op.Op.(*v1.Operation_OperationPrune); ok { + lastRan = time.Unix(0, op.UnixTimeEndMs*int64(time.Millisecond)) + return oplog.ErrStopIteration + } + return nil + }); err != nil { + return NeverScheduledTask, fmt.Errorf("finding last backup run time: %w", err) + } + + zap.L().Debug("last prune time", zap.Time("time", lastRan), zap.String("repo", t.RepoID())) + + runAt, err := protoutil.ResolveSchedule(repo.PrunePolicy.GetSchedule(), lastRan) + if errors.Is(err, protoutil.ErrScheduleDisabled) { + return NeverScheduledTask, nil + } else if err != nil { + return NeverScheduledTask, fmt.Errorf("resolve schedule: %w", err) + } + + return ScheduledTask{ + Task: t, + RunAt: runAt, + Op: &v1.Operation{ + Op: &v1.Operation_OperationCheck{}, + }, + }, nil +} + +func (t *CheckTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner) error { + op := st.Op + + repo, err := runner.GetRepoOrchestrator(t.RepoID()) + if err != nil { + return fmt.Errorf("couldn't get repo %q: %w", t.RepoID(), err) + } + + err = repo.UnlockIfAutoEnabled(ctx) + if err != nil { + return fmt.Errorf("auto unlock repo %q: %w", t.RepoID(), err) + } + + opPrune := &v1.Operation_OperationPrune{ + OperationPrune: &v1.OperationPrune{}, + } + op.Op = opPrune + + ctx, cancel := context.WithCancel(ctx) + interval := time.NewTicker(1 * time.Second) + defer interval.Stop() + buf := ioutil.HeadWriter{Limit: 8 * 1024} + bufWriter := ioutil.SynchronizedWriter{W: &buf} + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + for { + select { + case <-interval.C: + bufWriter.Mu.Lock() + output := string(buf.Bytes()) + bufWriter.Mu.Unlock() + if len(output) > 8*1024 { // only provide live status upto the first 8K of output. + output = output[:len(output)-8*1024] + } + + if opPrune.OperationPrune.Output != string(output) { + opPrune.OperationPrune.Output = string(output) + + if err := runner.OpLog().Update(op); err != nil { + zap.L().Error("update prune operation with status output", zap.Error(err)) + } + } + case <-ctx.Done(): + return + } + } + }() + + if err := repo.Prune(ctx, &bufWriter); err != nil { + cancel() + + runner.ExecuteHooks([]v1.Hook_Condition{ + v1.Hook_CONDITION_ANY_ERROR, + }, hook.HookVars{ + Error: err.Error(), + }) + + return fmt.Errorf("prune: %w", err) + } + cancel() + wg.Wait() + + output := buf.String() + if len(output) > 8*1024 { // only save the first 4K of output. + output = output[:len(output)-8*1024] + } + + opPrune.OperationPrune.Output = output + + // Run a stats task after a successful prune + if err := runner.ScheduleTask(NewStatsTask(t.RepoID(), PlanForSystemTasks, false), TaskPriorityStats); err != nil { + zap.L().Error("schedule stats task", zap.Error(err)) + } + + return nil +} diff --git a/proto/v1/operations.proto b/proto/v1/operations.proto index 5a55a2fb..f99f7f18 100644 --- a/proto/v1/operations.proto +++ b/proto/v1/operations.proto @@ -39,6 +39,7 @@ message Operation { OperationRestore operation_restore = 104; OperationStats operation_stats = 105; OperationRunHook operation_run_hook = 106; + OperationCheck operation_check = 107; } } @@ -90,16 +91,24 @@ message OperationPrune { string output = 1; // output of the prune. } +// OperationCheck tracks a check operation. +message OperationCheck { + string output = 1; // output of the check operation. +} + +// OperationRestore tracks a restore operation. 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. } +// OperationStats tracks a stats operation. message OperationStats { RepoStats stats = 1; } +// OperationRunHook tracks a hook that was run. message OperationRunHook { string name = 1; // description of the hook that was run. typically repo/hook_idx or plan/hook_idx. string output_logref = 2; // logref of the hook's output. DEPRECATED. diff --git a/webui/gen/ts/v1/config_pb.ts b/webui/gen/ts/v1/config_pb.ts index 8818665a..9d551568 100644 --- a/webui/gen/ts/v1/config_pb.ts +++ b/webui/gen/ts/v1/config_pb.ts @@ -649,10 +649,18 @@ export class CheckPolicy extends Message { * @generated from oneof v1.CheckPolicy.read_policy */ readPolicy: { + /** + * disable the check. + * + * @generated from field: bool disabled = 100; + */ + value: boolean; + case: "disabled"; + } | { /** * check a percentage of snapshots. * - * @generated from field: int32 read_percent = 11; + * @generated from field: int32 read_percent = 101; */ value: number; case: "readPercent"; @@ -667,7 +675,8 @@ export class CheckPolicy extends Message { static readonly typeName = "v1.CheckPolicy"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "schedule", kind: "message", T: Schedule }, - { no: 11, name: "read_percent", kind: "scalar", T: 5 /* ScalarType.INT32 */, oneof: "read_policy" }, + { no: 100, name: "disabled", kind: "scalar", T: 8 /* ScalarType.BOOL */, oneof: "read_policy" }, + { no: 101, name: "read_percent", kind: "scalar", T: 5 /* ScalarType.INT32 */, oneof: "read_policy" }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): CheckPolicy { diff --git a/webui/gen/ts/v1/operations_pb.ts b/webui/gen/ts/v1/operations_pb.ts index a0a49dd1..9547fb65 100644 --- a/webui/gen/ts/v1/operations_pb.ts +++ b/webui/gen/ts/v1/operations_pb.ts @@ -271,6 +271,12 @@ export class Operation extends Message { */ value: OperationRunHook; case: "operationRunHook"; + } | { + /** + * @generated from field: v1.OperationCheck operation_check = 107; + */ + value: OperationCheck; + case: "operationCheck"; } | { case: undefined; value?: undefined } = { case: undefined }; constructor(data?: PartialMessage) { @@ -299,6 +305,7 @@ export class Operation extends Message { { no: 104, name: "operation_restore", kind: "message", T: OperationRestore, oneof: "op" }, { no: 105, name: "operation_stats", kind: "message", T: OperationStats, oneof: "op" }, { no: 106, name: "operation_run_hook", kind: "message", T: OperationRunHook, oneof: "op" }, + { no: 107, name: "operation_check", kind: "message", T: OperationCheck, oneof: "op" }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): Operation { @@ -550,6 +557,49 @@ export class OperationPrune extends Message { } /** + * OperationCheck tracks a check operation. + * + * @generated from message v1.OperationCheck + */ +export class OperationCheck extends Message { + /** + * output of the check operation. + * + * @generated from field: string output = 1; + */ + output = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "v1.OperationCheck"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "output", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): OperationCheck { + return new OperationCheck().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): OperationCheck { + return new OperationCheck().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): OperationCheck { + return new OperationCheck().fromJsonString(jsonString, options); + } + + static equals(a: OperationCheck | PlainMessage | undefined, b: OperationCheck | PlainMessage | undefined): boolean { + return proto3.util.equals(OperationCheck, a, b); + } +} + +/** + * OperationRestore tracks a restore operation. + * * @generated from message v1.OperationRestore */ export class OperationRestore extends Message { @@ -605,6 +655,8 @@ export class OperationRestore extends Message { } /** + * OperationStats tracks a stats operation. + * * @generated from message v1.OperationStats */ export class OperationStats extends Message { @@ -642,6 +694,8 @@ export class OperationStats extends Message { } /** + * OperationRunHook tracks a hook that was run. + * * @generated from message v1.OperationRunHook */ export class OperationRunHook extends Message { From 77ae1acb7d200b121d0efdf0a7bd6ffdc5024721 Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Sun, 26 May 2024 23:53:49 -0700 Subject: [PATCH 02/14] implementing check operation --- cmd/backrestmon/backrestmon.go | 9 ++- internal/ioutil/ioutil.go | 10 +-- internal/orchestrator/repo/repo.go | 19 ++++++ internal/orchestrator/tasks/taskcheck.go | 24 +++---- internal/orchestrator/tasks/taskprune.go | 19 ++---- pkg/restic/error.go | 35 ++++++++--- pkg/restic/logging.go | 18 ------ pkg/restic/restic.go | 79 +++++++++++++++++------- pkg/restic/restic_test.go | 53 ++++++++++++++++ proto/v1/config.proto | 3 +- 10 files changed, 179 insertions(+), 90 deletions(-) diff --git a/cmd/backrestmon/backrestmon.go b/cmd/backrestmon/backrestmon.go index 8400f5b1..2387e5c8 100644 --- a/cmd/backrestmon/backrestmon.go +++ b/cmd/backrestmon/backrestmon.go @@ -45,13 +45,12 @@ func main() { cmd.Env = os.Environ() cmd.Env = append(cmd.Env, "ENV=production") - pro, pwo := io.Pipe() - pre, pwe := io.Pipe() - cmd.Stdout = pwo - cmd.Stderr = pwe + pr, pw := io.Pipe() + cmd.Stdout = pw + cmd.Stderr = pw go func() { - io.Copy(l, io.MultiReader(pro, pre)) + io.Copy(l, pr) }() if err := cmd.Start(); err != nil { diff --git a/internal/ioutil/ioutil.go b/internal/ioutil/ioutil.go index 59302ae4..b58a6fee 100644 --- a/internal/ioutil/ioutil.go +++ b/internal/ioutil/ioutil.go @@ -33,14 +33,11 @@ func (w *HeadWriter) Write(p []byte) (n int, err error) { } func (w *HeadWriter) Bytes() []byte { - w.mu.Lock() - defer w.mu.Unlock() return slices.Clone(w.Buf) } // tailWriter keeps the last 'Limit' bytes in memory. type TailWriter struct { - mu sync.Mutex Buf []byte Limit int } @@ -48,8 +45,6 @@ type TailWriter struct { var _ io.Writer = &TailWriter{} func (w *TailWriter) Write(p []byte) (n int, err error) { - w.mu.Lock() - defer w.mu.Unlock() w.Buf = append(w.Buf, p...) if len(w.Buf) > w.Limit { w.Buf = w.Buf[len(w.Buf)-w.Limit:] @@ -58,11 +53,12 @@ func (w *TailWriter) Write(p []byte) (n int, err error) { } func (w *TailWriter) Bytes() []byte { - w.mu.Lock() - defer w.mu.Unlock() return slices.Clone(w.Buf) } +// OutputCapturer keeps the first 'Limit' bytes and the last 'Limit' bytes in memory. +// If the total number of bytes written exceeds 'Limit', the middle is truncated. +// The writer is thread-safe. type OutputCapturer struct { mu sync.Mutex HeadWriter diff --git a/internal/orchestrator/repo/repo.go b/internal/orchestrator/repo/repo.go index 96922e34..8cc4a457 100644 --- a/internal/orchestrator/repo/repo.go +++ b/internal/orchestrator/repo/repo.go @@ -263,6 +263,25 @@ func (r *RepoOrchestrator) Prune(ctx context.Context, output io.Writer) error { return nil } +func (r *RepoOrchestrator) Check(ctx context.Context, output io.Writer) error { + r.mu.Lock() + defer r.mu.Unlock() + ctx, flush := forwardResticLogs(ctx) + defer flush() + + var opts []restic.GenericOption + if r.repoConfig.CheckOptions != nil { + opts = append(opts, restic.WithFlags(r.repoConfig.CheckOptions...)) + } + + r.l.Debug("checking repo") + err := r.repo.Check(ctx, output) + if err != nil { + return fmt.Errorf("check repo %v: %w", r.repoConfig.Id, err) + } + return nil +} + func (r *RepoOrchestrator) Restore(ctx context.Context, snapshotId string, path string, target string, progressCallback func(event *v1.RestoreProgressEntry)) (*v1.RestoreProgressEntry, error) { r.mu.Lock() defer r.mu.Unlock() diff --git a/internal/orchestrator/tasks/taskcheck.go b/internal/orchestrator/tasks/taskcheck.go index 2648769a..1659540f 100644 --- a/internal/orchestrator/tasks/taskcheck.go +++ b/internal/orchestrator/tasks/taskcheck.go @@ -99,15 +99,15 @@ func (t *CheckTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner return fmt.Errorf("auto unlock repo %q: %w", t.RepoID(), err) } - opPrune := &v1.Operation_OperationPrune{ - OperationPrune: &v1.OperationPrune{}, + opCheck := &v1.Operation_OperationCheck{ + OperationCheck: &v1.OperationCheck{}, } - op.Op = opPrune + op.Op = opCheck ctx, cancel := context.WithCancel(ctx) interval := time.NewTicker(1 * time.Second) defer interval.Stop() - buf := ioutil.HeadWriter{Limit: 8 * 1024} + buf := ioutil.HeadWriter{Limit: 16 * 1024} bufWriter := ioutil.SynchronizedWriter{W: &buf} var wg sync.WaitGroup wg.Add(1) @@ -119,12 +119,9 @@ func (t *CheckTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner bufWriter.Mu.Lock() output := string(buf.Bytes()) bufWriter.Mu.Unlock() - if len(output) > 8*1024 { // only provide live status upto the first 8K of output. - output = output[:len(output)-8*1024] - } - if opPrune.OperationPrune.Output != string(output) { - opPrune.OperationPrune.Output = string(output) + if opCheck.OperationCheck.Output != string(output) { + opCheck.OperationCheck.Output = string(output) if err := runner.OpLog().Update(op); err != nil { zap.L().Error("update prune operation with status output", zap.Error(err)) @@ -136,7 +133,7 @@ func (t *CheckTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner } }() - if err := repo.Prune(ctx, &bufWriter); err != nil { + if err := repo.Check(ctx, &bufWriter); err != nil { cancel() runner.ExecuteHooks([]v1.Hook_Condition{ @@ -150,12 +147,7 @@ func (t *CheckTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner cancel() wg.Wait() - output := buf.String() - if len(output) > 8*1024 { // only save the first 4K of output. - output = output[:len(output)-8*1024] - } - - opPrune.OperationPrune.Output = output + opCheck.OperationCheck.Output = string(buf.Bytes()) // Run a stats task after a successful prune if err := runner.ScheduleTask(NewStatsTask(t.RepoID(), PlanForSystemTasks, false), TaskPriorityStats); err != nil { diff --git a/internal/orchestrator/tasks/taskprune.go b/internal/orchestrator/tasks/taskprune.go index ac821874..0fe2a7fe 100644 --- a/internal/orchestrator/tasks/taskprune.go +++ b/internal/orchestrator/tasks/taskprune.go @@ -1,7 +1,6 @@ package tasks import ( - "bytes" "context" "errors" "fmt" @@ -108,7 +107,7 @@ func (t *PruneTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner ctx, cancel := context.WithCancel(ctx) interval := time.NewTicker(1 * time.Second) defer interval.Stop() - var buf bytes.Buffer + buf := ioutil.HeadWriter{Limit: 16 * 1024} bufWriter := ioutil.SynchronizedWriter{W: &buf} var wg sync.WaitGroup wg.Add(1) @@ -118,14 +117,11 @@ func (t *PruneTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner select { case <-interval.C: bufWriter.Mu.Lock() - output := buf.String() + output := string(buf.Bytes()) bufWriter.Mu.Unlock() - if len(output) > 8*1024 { // only provide live status upto the first 8K of output. - output = output[:len(output)-8*1024] - } - if opPrune.OperationPrune.Output != output { - opPrune.OperationPrune.Output = buf.String() + if opPrune.OperationPrune.Output != string(output) { + opPrune.OperationPrune.Output = string(output) if err := runner.OpLog().Update(op); err != nil { zap.L().Error("update prune operation with status output", zap.Error(err)) @@ -151,12 +147,7 @@ func (t *PruneTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner cancel() wg.Wait() - output := buf.String() - if len(output) > 8*1024 { // only save the first 4K of output. - output = output[:len(output)-8*1024] - } - - opPrune.OperationPrune.Output = output + opPrune.OperationPrune.Output = string(buf.Bytes()) // Run a stats task after a successful prune if err := runner.ScheduleTask(NewStatsTask(t.RepoID(), PlanForSystemTasks, false), TaskPriorityStats); err != nil { diff --git a/pkg/restic/error.go b/pkg/restic/error.go index c69f9ad1..b2866e25 100644 --- a/pkg/restic/error.go +++ b/pkg/restic/error.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os/exec" + "strings" ) const outputBufferLimit = 1000 @@ -40,13 +41,33 @@ func newCmdError(ctx context.Context, cmd *exec.Cmd, err error) *CmdError { return cerr } -func newCmdErrorPreformatted(ctx context.Context, cmd *exec.Cmd, err error) *CmdError { - cerr := &CmdError{ - Command: cmd.String(), - Err: err, +type ErrorWithOutput struct { + Err error + Output string +} + +func (e *ErrorWithOutput) Error() string { + return fmt.Sprintf("%v\nOutput:\n%s", e.Err, e.Output) +} + +func (e *ErrorWithOutput) Unwrap() error { + return e.Err +} + +func (e *ErrorWithOutput) Is(target error) bool { + _, ok := target.(*ErrorWithOutput) + return ok +} + +// newErrorWithOutput creates a new error with the given output. +func newErrorWithOutput(err error, output string) *ErrorWithOutput { + firstNewLine := strings.Index(output, "\n") + if firstNewLine > 0 { + output = output[:firstNewLine] } - if logger := LoggerFromContext(ctx); logger != nil { - logger.Write([]byte(cerr.Error())) + + return &ErrorWithOutput{ + Err: err, + Output: output, } - return cerr } diff --git a/pkg/restic/logging.go b/pkg/restic/logging.go index 329d89ba..d74f5dd3 100644 --- a/pkg/restic/logging.go +++ b/pkg/restic/logging.go @@ -3,7 +3,6 @@ package restic import ( "context" "io" - "os/exec" ) var loggerKey = struct{}{} @@ -16,20 +15,3 @@ func LoggerFromContext(ctx context.Context) io.Writer { writer, _ := ctx.Value(loggerKey).(io.Writer) return writer } - -func addLoggingToCommand(ctx context.Context, cmd *exec.Cmd) { - logger := LoggerFromContext(ctx) - if logger == nil { - return - } - if cmd.Stdout != nil { - cmd.Stdout = io.MultiWriter(cmd.Stdout, logger) - } else { - cmd.Stdout = logger - } - if cmd.Stderr != nil { - cmd.Stderr = io.MultiWriter(cmd.Stderr, logger) - } else { - cmd.Stderr = logger - } -} diff --git a/pkg/restic/restic.go b/pkg/restic/restic.go index 744bc841..5be40c6e 100644 --- a/pkg/restic/restic.go +++ b/pkg/restic/restic.go @@ -23,12 +23,16 @@ var ErrPartialBackup = errors.New("incomplete backup") var ErrBackupFailed = errors.New("backup failed") type Repo struct { - cmd string - uri string - initialized bool + cmd string + uri string extraArgs []string extraEnv []string + + exists error + checkExists sync.Once + initialized error // nil or errAlreadyInitialized if initialized, error if initialization failed. + shouldInitialize sync.Once } // NewRepo instantiates a new repository. @@ -41,11 +45,10 @@ func NewRepo(resticBin string, uri string, opts ...GenericOption) *Repo { opt.extraEnv = append(opt.extraEnv, "RESTIC_REPOSITORY="+uri) return &Repo{ - cmd: resticBin, // TODO: configurable binary path - uri: uri, - initialized: false, - extraArgs: opt.extraArgs, - extraEnv: opt.extraEnv, + cmd: resticBin, // TODO: configurable binary path + uri: uri, + extraArgs: opt.extraArgs, + extraEnv: opt.extraEnv, } } @@ -59,7 +62,12 @@ func (r *Repo) commandWithContext(ctx context.Context, args []string, opts ...Ge cmd.Env = append(cmd.Env, r.extraEnv...) cmd.Env = append(cmd.Env, opt.extraEnv...) - addLoggingToCommand(ctx, cmd) + logger := LoggerFromContext(ctx) + if logger != nil { + sw := &ioutil.SynchronizedWriter{W: logger} + cmd.Stderr = sw + cmd.Stdout = sw + } if logger := LoggerFromContext(ctx); logger != nil { fmt.Fprintf(logger, "\ncommand: %v %v\n", r.cmd, strings.Join(args, " ")) @@ -85,25 +93,40 @@ func (r *Repo) pipeCmdOutputToWriter(cmd *exec.Cmd, handlers ...io.Writer) { cmd.Stderr = mw } +// Exists checks if the repository exists. +// Returns true if exists, false if it does not exist OR an access error occurred. +func (r *Repo) Exists(ctx context.Context, opts ...GenericOption) error { + r.checkExists.Do(func() { + cmd := r.commandWithContext(ctx, []string{"cat", "config"}, opts...) + if err := cmd.Run(); err != nil { + r.exists = newCmdError(ctx, cmd, err) + } + r.exists = nil + }) + return r.exists +} + // init initializes the repo, the command will be cancelled with the context. func (r *Repo) init(ctx context.Context, opts ...GenericOption) error { - if r.initialized { + if r.Exists(ctx, opts...) == nil { return nil } - cmd := r.commandWithContext(ctx, []string{"init", "--json"}, opts...) - output := bytes.NewBuffer(nil) - r.pipeCmdOutputToWriter(cmd, output) + r.shouldInitialize.Do(func() { + cmd := r.commandWithContext(ctx, []string{"init", "--json"}, opts...) + output := bytes.NewBuffer(nil) + r.pipeCmdOutputToWriter(cmd, output) - if err := cmd.Run(); err != nil { - if strings.Contains(output.String(), "config file already exists") || strings.Contains(output.String(), "already initialized") { - return errAlreadyInitialized + if err := cmd.Run(); err != nil { + if strings.Contains(output.String(), "config file already exists") || strings.Contains(output.String(), "already initialized") { + r.initialized = errAlreadyInitialized + } else { + r.initialized = newCmdError(ctx, cmd, fmt.Errorf("%w: %v", err, output.String())) + } } - return newCmdError(ctx, cmd, fmt.Errorf("%w: %v", err, output.String())) - } + }) - r.initialized = true - return nil + return r.initialized } func (r *Repo) Init(ctx context.Context, opts ...GenericOption) error { @@ -160,7 +183,7 @@ func (r *Repo) Backup(ctx context.Context, paths []string, progressCallback func } } } - return summary, newCmdErrorPreformatted(ctx, cmd, errors.Join(cmdErr, readErr)) + return summary, newCmdError(ctx, cmd, errors.Join(cmdErr, readErr)) } return summary, nil } @@ -235,6 +258,18 @@ func (r *Repo) Prune(ctx context.Context, pruneOutput io.Writer, opts ...Generic return nil } +func (r *Repo) Check(ctx context.Context, checkOutput io.Writer, opts ...GenericOption) error { + args := []string{"check"} + cmd := r.commandWithContext(ctx, args, opts...) + if checkOutput != nil { + r.pipeCmdOutputToWriter(cmd, checkOutput) + } + if err := cmd.Run(); err != nil { + return newCmdError(ctx, cmd, err) + } + return nil +} + func (r *Repo) Restore(ctx context.Context, snapshot string, callback func(*RestoreProgressEntry), opts ...GenericOption) (*RestoreProgressEntry, error) { opts = append(slices.Clone(opts), WithEnv("RESTIC_PROGRESS_FPS=2")) cmd := r.commandWithContext(ctx, []string{"restore", "--json", snapshot}, opts...) @@ -271,7 +306,7 @@ func (r *Repo) Restore(ctx context.Context, snapshot string, callback func(*Rest } } - return summary, newCmdErrorPreformatted(ctx, cmd, errors.Join(cmdErr, readErr)) + return summary, newCmdError(ctx, cmd, errors.Join(cmdErr, readErr)) } return summary, nil } diff --git a/pkg/restic/restic_test.go b/pkg/restic/restic_test.go index a3cabb52..917b52be 100644 --- a/pkg/restic/restic_test.go +++ b/pkg/restic/restic_test.go @@ -467,6 +467,59 @@ func TestResticStats(t *testing.T) { } } +func TestResticCheck(t *testing.T) { + t.Parallel() + + repo := t.TempDir() + r := NewRepo(helpers.ResticBinary(t), repo, WithFlags("--no-cache"), WithEnv("RESTIC_PASSWORD=test")) + if err := r.Init(context.Background()); err != nil { + t.Fatalf("failed to init repo: %v", err) + } + + testData := helpers.CreateTestData(t) + + _, err := r.Backup(context.Background(), []string{testData}, nil) + if err != nil { + t.Fatalf("failed to backup and create new snapshot: %v", err) + } + + // check repo + output := bytes.NewBuffer(nil) + if err := r.Check(context.Background(), output, WithFlags("--read-data")); err != nil { + t.Fatalf("failed to check repo: %v", err) + } + + wantStr := "no errors were found" + if !bytes.Contains(output.Bytes(), []byte(wantStr)) { + t.Errorf("wanted output to contain 'no errors were found', got: %s", output.String()) + } + + // corrupt the repo + filepath.WalkDir(repo, func(path string, d os.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() || !strings.HasSuffix(path, "snapshot") { + return nil + } + if err := os.WriteFile(path, []byte("corrupted"), 0644); err != nil { + return err + } + return nil + }) + + // check repo + output.Reset() + if err := r.Check(context.Background(), output); err == nil { + t.Errorf("wanted error, got: nil") + } + + wantStr = "error: repository contains errors" + if !bytes.Contains(output.Bytes(), []byte(wantStr)) { + t.Errorf("wanted output to contain 'repository contains errors', got: %s", output.String()) + } +} + func toRepoPath(path string) string { if runtime.GOOS != "windows" { return path diff --git a/proto/v1/config.proto b/proto/v1/config.proto index 0d5cad2c..5c62f9ba 100644 --- a/proto/v1/config.proto +++ b/proto/v1/config.proto @@ -94,7 +94,8 @@ message CheckPolicy { Schedule schedule = 1 [json_name="schedule"]; oneof read_policy { - int32 read_percent = 11 [json_name="readPercent"]; // check a percentage of snapshots. + bool disabled = 100 [json_name="disabled"]; // disable the check. + int32 read_percent = 101 [json_name="readPercent"]; // check a percentage of snapshots. } } From ca9a30a973744cd9d4443ca87aa2ef5ec6bd3554 Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 00:56:12 -0700 Subject: [PATCH 03/14] implement check and UI changes --- gen/go/v1/config.pb.go | 262 +++++----- gen/go/v1/service.pb.go | 629 ++++++++++++++---------- gen/go/v1/service_grpc.pb.go | 149 +----- gen/go/v1/v1connect/service.connect.go | 137 +----- internal/api/backresthandler.go | 60 +-- internal/ioutil/ioutil.go | 4 + internal/orchestrator/repo/repo.go | 11 +- internal/orchestrator/repo/repo_test.go | 57 +++ internal/orchestrator/tasks/task.go | 7 +- pkg/restic/restic.go | 10 +- pkg/restic/restic_test.go | 25 - proto/v1/config.proto | 6 +- proto/v1/service.proto | 26 +- webui/gen/ts/v1/config_pb.ts | 20 +- webui/gen/ts/v1/service_connect.ts | 45 +- webui/gen/ts/v1/service_pb.ts | 87 ++++ webui/src/components/OperationList.tsx | 12 +- webui/src/components/OperationRow.tsx | 18 + webui/src/state/oplog.ts | 5 + webui/src/views/PlanView.tsx | 14 +- webui/src/views/RepoView.tsx | 47 +- 21 files changed, 864 insertions(+), 767 deletions(-) diff --git a/gen/go/v1/config.pb.go b/gen/go/v1/config.pb.go index 5f6d3b33..bc620be1 100644 --- a/gen/go/v1/config.pb.go +++ b/gen/go/v1/config.pb.go @@ -811,11 +811,11 @@ type CheckPolicy struct { unknownFields protoimpl.UnknownFields Schedule *Schedule `protobuf:"bytes,1,opt,name=schedule,proto3" json:"schedule,omitempty"` - // Types that are assignable to ReadPolicy: + // Types that are assignable to Mode: // - // *CheckPolicy_Disabled - // *CheckPolicy_ReadPercent - ReadPolicy isCheckPolicy_ReadPolicy `protobuf_oneof:"read_policy"` + // *CheckPolicy_StructureOnly + // *CheckPolicy_ReadDataSubsetPercent + Mode isCheckPolicy_Mode `protobuf_oneof:"mode"` } func (x *CheckPolicy) Reset() { @@ -857,42 +857,42 @@ func (x *CheckPolicy) GetSchedule() *Schedule { return nil } -func (m *CheckPolicy) GetReadPolicy() isCheckPolicy_ReadPolicy { +func (m *CheckPolicy) GetMode() isCheckPolicy_Mode { if m != nil { - return m.ReadPolicy + return m.Mode } return nil } -func (x *CheckPolicy) GetDisabled() bool { - if x, ok := x.GetReadPolicy().(*CheckPolicy_Disabled); ok { - return x.Disabled +func (x *CheckPolicy) GetStructureOnly() bool { + if x, ok := x.GetMode().(*CheckPolicy_StructureOnly); ok { + return x.StructureOnly } return false } -func (x *CheckPolicy) GetReadPercent() int32 { - if x, ok := x.GetReadPolicy().(*CheckPolicy_ReadPercent); ok { - return x.ReadPercent +func (x *CheckPolicy) GetReadDataSubsetPercent() int32 { + if x, ok := x.GetMode().(*CheckPolicy_ReadDataSubsetPercent); ok { + return x.ReadDataSubsetPercent } return 0 } -type isCheckPolicy_ReadPolicy interface { - isCheckPolicy_ReadPolicy() +type isCheckPolicy_Mode interface { + isCheckPolicy_Mode() } -type CheckPolicy_Disabled struct { - Disabled bool `protobuf:"varint,100,opt,name=disabled,proto3,oneof"` // disable the check. +type CheckPolicy_StructureOnly struct { + StructureOnly bool `protobuf:"varint,100,opt,name=structure_only,json=structureOnly,proto3,oneof"` // only check the structure of the repo. No pack data is read. } -type CheckPolicy_ReadPercent struct { - ReadPercent int32 `protobuf:"varint,101,opt,name=read_percent,json=readPercent,proto3,oneof"` // check a percentage of snapshots. +type CheckPolicy_ReadDataSubsetPercent struct { + ReadDataSubsetPercent int32 `protobuf:"varint,101,opt,name=read_data_subset_percent,json=readDataSubsetPercent,proto3,oneof"` // check a percentage of pack data. } -func (*CheckPolicy_Disabled) isCheckPolicy_ReadPolicy() {} +func (*CheckPolicy_StructureOnly) isCheckPolicy_Mode() {} -func (*CheckPolicy_ReadPercent) isCheckPolicy_ReadPolicy() {} +func (*CheckPolicy_ReadDataSubsetPercent) isCheckPolicy_Mode() {} type Schedule struct { state protoimpl.MessageState @@ -1884,118 +1884,120 @@ var file_v1_config_proto_rawDesc = []byte{ 0x61, 0x78, 0x55, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x55, 0x6e, - 0x75, 0x73, 0x65, 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, 0x89, 0x01, 0x0a, 0x0b, + 0x75, 0x73, 0x65, 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, 0xa3, 0x01, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x08, 0x73, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x63, - 0x65, 0x6e, 0x74, 0x18, 0x65, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0b, 0x72, 0x65, 0x61, - 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64, - 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0xa8, 0x01, 0x0a, 0x08, 0x53, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x00, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x46, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x44, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x48, 0x00, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x79, 0x44, 0x61, 0x79, 0x73, 0x12, 0x2e, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x05, 0x48, 0x00, 0x52, 0x11, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, - 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x22, 0xec, 0x09, 0x0a, 0x04, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x32, 0x0a, 0x0a, 0x63, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, - 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x2b, 0x0a, 0x08, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x4f, 0x6e, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x52, 0x07, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x39, 0x0a, 0x0e, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x64, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, - 0x6b, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x65, 0x62, 0x68, 0x6f, - 0x6f, 0x6b, 0x12, 0x39, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x72, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, - 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, 0x0d, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x36, 0x0a, - 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x67, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x18, 0x67, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x47, - 0x6f, 0x74, 0x69, 0x66, 0x79, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x47, - 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x33, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x18, 0x68, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31, - 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0b, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x3c, 0x0a, 0x0f, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x18, 0x69, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x53, 0x68, - 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x48, 0x00, 0x52, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x53, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x1a, 0x23, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x1a, 0xa1, 0x01, - 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x65, 0x62, - 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x2f, 0x0a, 0x06, 0x6d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, - 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x74, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, - 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, - 0x02, 0x1a, 0x46, 0x0a, 0x07, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x1f, 0x0a, 0x0b, - 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, - 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x7c, 0x0a, 0x06, 0x47, 0x6f, 0x74, - 0x69, 0x66, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, - 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, - 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x74, 0x65, 0x18, 0x65, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x54, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x44, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, 0x6b, - 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, - 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x49, 0x0a, - 0x08, 0x53, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x68, 0x6f, - 0x75, 0x74, 0x72, 0x72, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x73, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, - 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x17, 0x0a, - 0x13, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4e, 0x59, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x53, 0x54, 0x41, - 0x52, 0x54, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x45, 0x4e, 0x44, 0x10, 0x03, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x27, 0x0a, 0x0e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, + 0x72, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, + 0x0d, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x39, + 0x0a, 0x18, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x75, 0x62, 0x73, + 0x65, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x65, 0x20, 0x01, 0x28, 0x05, + 0x48, 0x00, 0x52, 0x15, 0x72, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x75, 0x62, 0x73, + 0x65, 0x74, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x6d, 0x6f, 0x64, + 0x65, 0x22, 0xa8, 0x01, 0x0a, 0x08, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x1c, + 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x04, + 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x63, 0x72, + 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x79, 0x44, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x10, + 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x44, 0x61, 0x79, 0x73, + 0x12, 0x2e, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, + 0x48, 0x6f, 0x75, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x11, 0x6d, + 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, + 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x22, 0xec, 0x09, 0x0a, + 0x04, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x32, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x48, + 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x0a, 0x08, 0x6f, 0x6e, 0x5f, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x76, 0x31, + 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x4f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x07, 0x6f, + 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x39, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x12, 0x39, 0x0a, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, + 0x6f, 0x6f, 0x6b, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x48, 0x00, 0x52, 0x0d, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x39, 0x0a, 0x0e, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x66, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x67, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x18, 0x67, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x47, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x48, + 0x00, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, + 0x33, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x18, + 0x68, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, + 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x3c, 0x0a, 0x0f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, + 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x18, 0x69, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x53, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, + 0x48, 0x00, 0x52, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x6f, 0x75, 0x74, 0x72, + 0x72, 0x72, 0x1a, 0x23, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x1a, 0xa1, 0x01, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, + 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x2f, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x57, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x06, 0x6d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x22, 0x28, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, + 0x01, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x02, 0x1a, 0x46, 0x0a, 0x07, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x1a, 0x7c, 0x0a, 0x06, 0x47, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x19, 0x0a, + 0x08, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x62, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, + 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x65, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x1a, 0x44, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x65, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x1a, 0x49, 0x0a, 0x08, 0x53, 0x68, 0x6f, 0x75, 0x74, + 0x72, 0x72, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x5f, + 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x68, 0x6f, 0x75, 0x74, + 0x72, 0x72, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x44, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4e, 0x59, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, - 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x1e, - 0x0a, 0x1a, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, - 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x22, 0x47, - 0x0a, 0x07, 0x4f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x13, - 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, - 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x02, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0x42, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x51, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x62, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x70, 0x61, - 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x0a, 0x0a, 0x08, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 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, + 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x02, 0x12, 0x1a, + 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, + 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x45, 0x4e, 0x44, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, + 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4e, 0x44, + 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x57, + 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x22, 0x47, 0x0a, 0x07, 0x4f, 0x6e, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, + 0x0e, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, + 0x02, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x42, 0x0a, 0x04, 0x41, + 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, + 0x1e, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, + 0x51, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x62, 0x63, 0x72, 0x79, 0x70, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x42, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 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 ( @@ -2308,8 +2310,8 @@ func file_v1_config_proto_init() { (*RetentionPolicy_PolicyKeepAll)(nil), } file_v1_config_proto_msgTypes[6].OneofWrappers = []interface{}{ - (*CheckPolicy_Disabled)(nil), - (*CheckPolicy_ReadPercent)(nil), + (*CheckPolicy_StructureOnly)(nil), + (*CheckPolicy_ReadDataSubsetPercent)(nil), } file_v1_config_proto_msgTypes[7].OneofWrappers = []interface{}{ (*Schedule_Disabled)(nil), diff --git a/gen/go/v1/service.pb.go b/gen/go/v1/service.pb.go index 1afe6278..8a02217e 100644 --- a/gen/go/v1/service.pb.go +++ b/gen/go/v1/service.pb.go @@ -23,6 +23,64 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type DoRepoTaskRequest_Task int32 + +const ( + DoRepoTaskRequest_TASK_NONE DoRepoTaskRequest_Task = 0 + DoRepoTaskRequest_TASK_INDEX_SNAPSHOTS DoRepoTaskRequest_Task = 1 + DoRepoTaskRequest_TASK_PRUNE DoRepoTaskRequest_Task = 2 + DoRepoTaskRequest_TASK_CHECK DoRepoTaskRequest_Task = 3 + DoRepoTaskRequest_TASK_STATS DoRepoTaskRequest_Task = 4 + DoRepoTaskRequest_TASK_UNLOCK DoRepoTaskRequest_Task = 5 +) + +// Enum value maps for DoRepoTaskRequest_Task. +var ( + DoRepoTaskRequest_Task_name = map[int32]string{ + 0: "TASK_NONE", + 1: "TASK_INDEX_SNAPSHOTS", + 2: "TASK_PRUNE", + 3: "TASK_CHECK", + 4: "TASK_STATS", + 5: "TASK_UNLOCK", + } + DoRepoTaskRequest_Task_value = map[string]int32{ + "TASK_NONE": 0, + "TASK_INDEX_SNAPSHOTS": 1, + "TASK_PRUNE": 2, + "TASK_CHECK": 3, + "TASK_STATS": 4, + "TASK_UNLOCK": 5, + } +) + +func (x DoRepoTaskRequest_Task) Enum() *DoRepoTaskRequest_Task { + p := new(DoRepoTaskRequest_Task) + *p = x + return p +} + +func (x DoRepoTaskRequest_Task) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DoRepoTaskRequest_Task) Descriptor() protoreflect.EnumDescriptor { + return file_v1_service_proto_enumTypes[0].Descriptor() +} + +func (DoRepoTaskRequest_Task) Type() protoreflect.EnumType { + return &file_v1_service_proto_enumTypes[0] +} + +func (x DoRepoTaskRequest_Task) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DoRepoTaskRequest_Task.Descriptor instead. +func (DoRepoTaskRequest_Task) EnumDescriptor() ([]byte, []int) { + return file_v1_service_proto_rawDescGZIP(), []int{1, 0} +} + // OpSelector is a message that can be used to select operations e.g. by query. type OpSelector struct { state protoimpl.MessageState @@ -103,6 +161,61 @@ func (x *OpSelector) GetFlowId() int64 { return 0 } +type DoRepoTaskRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RepoId string `protobuf:"bytes,1,opt,name=repo_id,json=repoId,proto3" json:"repo_id,omitempty"` + Task DoRepoTaskRequest_Task `protobuf:"varint,2,opt,name=task,proto3,enum=v1.DoRepoTaskRequest_Task" json:"task,omitempty"` +} + +func (x *DoRepoTaskRequest) Reset() { + *x = DoRepoTaskRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_v1_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DoRepoTaskRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DoRepoTaskRequest) ProtoMessage() {} + +func (x *DoRepoTaskRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_service_proto_msgTypes[1] + 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 DoRepoTaskRequest.ProtoReflect.Descriptor instead. +func (*DoRepoTaskRequest) Descriptor() ([]byte, []int) { + return file_v1_service_proto_rawDescGZIP(), []int{1} +} + +func (x *DoRepoTaskRequest) GetRepoId() string { + if x != nil { + return x.RepoId + } + return "" +} + +func (x *DoRepoTaskRequest) GetTask() DoRepoTaskRequest_Task { + if x != nil { + return x.Task + } + return DoRepoTaskRequest_TASK_NONE +} + type ClearHistoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -115,7 +228,7 @@ type ClearHistoryRequest struct { func (x *ClearHistoryRequest) Reset() { *x = ClearHistoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[1] + mi := &file_v1_service_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -128,7 +241,7 @@ func (x *ClearHistoryRequest) String() string { func (*ClearHistoryRequest) ProtoMessage() {} func (x *ClearHistoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[1] + mi := &file_v1_service_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -141,7 +254,7 @@ func (x *ClearHistoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearHistoryRequest.ProtoReflect.Descriptor instead. func (*ClearHistoryRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{1} + return file_v1_service_proto_rawDescGZIP(), []int{2} } func (x *ClearHistoryRequest) GetSelector() *OpSelector { @@ -171,7 +284,7 @@ type ForgetRequest struct { func (x *ForgetRequest) Reset() { *x = ForgetRequest{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[2] + mi := &file_v1_service_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -184,7 +297,7 @@ func (x *ForgetRequest) String() string { func (*ForgetRequest) ProtoMessage() {} func (x *ForgetRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[2] + mi := &file_v1_service_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -197,7 +310,7 @@ func (x *ForgetRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ForgetRequest.ProtoReflect.Descriptor instead. func (*ForgetRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{2} + return file_v1_service_proto_rawDescGZIP(), []int{3} } func (x *ForgetRequest) GetRepoId() string { @@ -233,7 +346,7 @@ type ListSnapshotsRequest struct { func (x *ListSnapshotsRequest) Reset() { *x = ListSnapshotsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[3] + mi := &file_v1_service_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -246,7 +359,7 @@ func (x *ListSnapshotsRequest) String() string { func (*ListSnapshotsRequest) ProtoMessage() {} func (x *ListSnapshotsRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[3] + mi := &file_v1_service_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -259,7 +372,7 @@ func (x *ListSnapshotsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSnapshotsRequest.ProtoReflect.Descriptor instead. func (*ListSnapshotsRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{3} + return file_v1_service_proto_rawDescGZIP(), []int{4} } func (x *ListSnapshotsRequest) GetRepoId() string { @@ -288,7 +401,7 @@ type GetOperationsRequest struct { func (x *GetOperationsRequest) Reset() { *x = GetOperationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[4] + mi := &file_v1_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -301,7 +414,7 @@ func (x *GetOperationsRequest) String() string { func (*GetOperationsRequest) ProtoMessage() {} func (x *GetOperationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[4] + mi := &file_v1_service_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -314,7 +427,7 @@ func (x *GetOperationsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetOperationsRequest.ProtoReflect.Descriptor instead. func (*GetOperationsRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{4} + return file_v1_service_proto_rawDescGZIP(), []int{5} } func (x *GetOperationsRequest) GetSelector() *OpSelector { @@ -346,7 +459,7 @@ type RestoreSnapshotRequest struct { func (x *RestoreSnapshotRequest) Reset() { *x = RestoreSnapshotRequest{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[5] + mi := &file_v1_service_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -359,7 +472,7 @@ func (x *RestoreSnapshotRequest) String() string { func (*RestoreSnapshotRequest) ProtoMessage() {} func (x *RestoreSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[5] + mi := &file_v1_service_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -372,7 +485,7 @@ func (x *RestoreSnapshotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreSnapshotRequest.ProtoReflect.Descriptor instead. func (*RestoreSnapshotRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{5} + return file_v1_service_proto_rawDescGZIP(), []int{6} } func (x *RestoreSnapshotRequest) GetPlanId() string { @@ -423,7 +536,7 @@ type ListSnapshotFilesRequest struct { func (x *ListSnapshotFilesRequest) Reset() { *x = ListSnapshotFilesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[6] + mi := &file_v1_service_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -436,7 +549,7 @@ func (x *ListSnapshotFilesRequest) String() string { func (*ListSnapshotFilesRequest) ProtoMessage() {} func (x *ListSnapshotFilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[6] + mi := &file_v1_service_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -449,7 +562,7 @@ func (x *ListSnapshotFilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSnapshotFilesRequest.ProtoReflect.Descriptor instead. func (*ListSnapshotFilesRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{6} + return file_v1_service_proto_rawDescGZIP(), []int{7} } func (x *ListSnapshotFilesRequest) GetRepoId() string { @@ -485,7 +598,7 @@ type ListSnapshotFilesResponse struct { func (x *ListSnapshotFilesResponse) Reset() { *x = ListSnapshotFilesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[7] + mi := &file_v1_service_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -498,7 +611,7 @@ func (x *ListSnapshotFilesResponse) String() string { func (*ListSnapshotFilesResponse) ProtoMessage() {} func (x *ListSnapshotFilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[7] + mi := &file_v1_service_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -511,7 +624,7 @@ func (x *ListSnapshotFilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSnapshotFilesResponse.ProtoReflect.Descriptor instead. func (*ListSnapshotFilesResponse) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{7} + return file_v1_service_proto_rawDescGZIP(), []int{8} } func (x *ListSnapshotFilesResponse) GetPath() string { @@ -539,7 +652,7 @@ type LogDataRequest struct { func (x *LogDataRequest) Reset() { *x = LogDataRequest{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[8] + mi := &file_v1_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -552,7 +665,7 @@ func (x *LogDataRequest) String() string { func (*LogDataRequest) ProtoMessage() {} func (x *LogDataRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[8] + mi := &file_v1_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -565,7 +678,7 @@ func (x *LogDataRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LogDataRequest.ProtoReflect.Descriptor instead. func (*LogDataRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{8} + return file_v1_service_proto_rawDescGZIP(), []int{9} } func (x *LogDataRequest) GetRef() string { @@ -595,7 +708,7 @@ type LsEntry struct { func (x *LsEntry) Reset() { *x = LsEntry{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[9] + mi := &file_v1_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -608,7 +721,7 @@ func (x *LsEntry) String() string { func (*LsEntry) ProtoMessage() {} func (x *LsEntry) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[9] + mi := &file_v1_service_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -621,7 +734,7 @@ func (x *LsEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use LsEntry.ProtoReflect.Descriptor instead. func (*LsEntry) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{9} + return file_v1_service_proto_rawDescGZIP(), []int{10} } func (x *LsEntry) GetName() string { @@ -706,7 +819,7 @@ type RunCommandRequest struct { func (x *RunCommandRequest) Reset() { *x = RunCommandRequest{} if protoimpl.UnsafeEnabled { - mi := &file_v1_service_proto_msgTypes[10] + mi := &file_v1_service_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -719,7 +832,7 @@ func (x *RunCommandRequest) String() string { func (*RunCommandRequest) ProtoMessage() {} func (x *RunCommandRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[10] + mi := &file_v1_service_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -732,7 +845,7 @@ func (x *RunCommandRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RunCommandRequest.ProtoReflect.Descriptor instead. func (*RunCommandRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{10} + return file_v1_service_proto_rawDescGZIP(), []int{11} } func (x *RunCommandRequest) GetRepoId() string { @@ -770,149 +883,152 @@ var file_v1_service_proto_rawDesc = []byte{ 0x0a, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x22, 0x62, 0x0a, 0x13, 0x43, 0x6c, 0x65, 0x61, - 0x72, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x2a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, - 0x6e, 0x6c, 0x79, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0a, 0x6f, 0x6e, 0x6c, 0x79, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x62, 0x0a, 0x0d, - 0x46, 0x6f, 0x72, 0x67, 0x65, 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, - 0x22, 0x48, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, - 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, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x22, 0x59, 0x0a, 0x14, 0x47, 0x65, - 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x15, - 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x02, 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, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x70, - 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x05, 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, 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, 0x22, 0x0a, 0x0e, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x72, 0x65, 0x66, 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, 0x22, 0x46, 0x0a, 0x11, 0x52, - 0x75, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 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, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x32, 0x9e, 0x09, 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, 0x3e, 0x0a, 0x0e, - 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 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, 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, + 0x52, 0x06, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x22, 0xce, 0x01, 0x0a, 0x11, 0x44, 0x6f, 0x52, + 0x65, 0x70, 0x6f, 0x54, 0x61, 0x73, 0x6b, 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, 0x2e, 0x0a, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x52, 0x65, 0x70, + 0x6f, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x61, 0x73, + 0x6b, 0x52, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x22, 0x70, 0x0a, 0x04, 0x54, 0x61, 0x73, 0x6b, 0x12, + 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x53, 0x4b, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x18, + 0x0a, 0x14, 0x54, 0x41, 0x53, 0x4b, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, 0x53, 0x4e, 0x41, + 0x50, 0x53, 0x48, 0x4f, 0x54, 0x53, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x41, 0x53, 0x4b, + 0x5f, 0x50, 0x52, 0x55, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x41, 0x53, 0x4b, + 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x41, 0x53, 0x4b, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x41, 0x53, 0x4b, + 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x05, 0x22, 0x62, 0x0a, 0x13, 0x43, 0x6c, 0x65, + 0x61, 0x72, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, + 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0a, 0x6f, 0x6e, 0x6c, 0x79, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x62, 0x0a, + 0x0d, 0x46, 0x6f, 0x72, 0x67, 0x65, 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, 0x22, 0x48, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, + 0x74, 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, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x22, 0x59, 0x0a, 0x14, 0x47, + 0x65, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, + 0x15, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x02, 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, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, + 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x05, 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, 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, 0x22, 0x0a, 0x0e, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x72, 0x65, 0x66, 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, 0x22, 0x46, 0x0a, 0x11, + 0x52, 0x75, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 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, 0x18, 0x0a, 0x07, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x32, 0xf7, 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, 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, 0x3d, 0x0a, 0x0a, 0x44, 0x6f, 0x52, 0x65, 0x70, 0x6f, 0x54, + 0x61, 0x73, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x52, 0x65, 0x70, 0x6f, 0x54, + 0x61, 0x73, 0x6b, 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, 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, 0x35, 0x0a, 0x06, 0x46, - 0x6f, 0x72, 0x67, 0x65, 0x74, 0x12, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x67, 0x65, - 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, 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, + 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x12, 0x11, + 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x67, 0x65, 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, 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, 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, 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, 0x32, 0x0a, 0x07, 0x47, 0x65, 0x74, - 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, - 0x0a, 0x52, 0x75, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x15, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x75, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x79, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x12, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x0e, 0x47, 0x65, 0x74, - 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x52, 0x4c, 0x12, 0x11, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x12, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, - 0x75, 0x65, 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, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0a, 0x52, 0x75, 0x6e, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x15, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x00, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, + 0x61, 0x64, 0x55, 0x52, 0x4c, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, + 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 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, } var ( @@ -927,79 +1043,77 @@ func file_v1_service_proto_rawDescGZIP() []byte { return file_v1_service_proto_rawDescData } -var file_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_v1_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_v1_service_proto_goTypes = []interface{}{ - (*OpSelector)(nil), // 0: v1.OpSelector - (*ClearHistoryRequest)(nil), // 1: v1.ClearHistoryRequest - (*ForgetRequest)(nil), // 2: v1.ForgetRequest - (*ListSnapshotsRequest)(nil), // 3: v1.ListSnapshotsRequest - (*GetOperationsRequest)(nil), // 4: v1.GetOperationsRequest - (*RestoreSnapshotRequest)(nil), // 5: v1.RestoreSnapshotRequest - (*ListSnapshotFilesRequest)(nil), // 6: v1.ListSnapshotFilesRequest - (*ListSnapshotFilesResponse)(nil), // 7: v1.ListSnapshotFilesResponse - (*LogDataRequest)(nil), // 8: v1.LogDataRequest - (*LsEntry)(nil), // 9: v1.LsEntry - (*RunCommandRequest)(nil), // 10: v1.RunCommandRequest - (*emptypb.Empty)(nil), // 11: google.protobuf.Empty - (*Config)(nil), // 12: v1.Config - (*Repo)(nil), // 13: v1.Repo - (*types.StringValue)(nil), // 14: types.StringValue - (*types.Int64Value)(nil), // 15: types.Int64Value - (*OperationEvent)(nil), // 16: v1.OperationEvent - (*OperationList)(nil), // 17: v1.OperationList - (*ResticSnapshotList)(nil), // 18: v1.ResticSnapshotList - (*types.BytesValue)(nil), // 19: types.BytesValue - (*types.StringList)(nil), // 20: types.StringList + (DoRepoTaskRequest_Task)(0), // 0: v1.DoRepoTaskRequest.Task + (*OpSelector)(nil), // 1: v1.OpSelector + (*DoRepoTaskRequest)(nil), // 2: v1.DoRepoTaskRequest + (*ClearHistoryRequest)(nil), // 3: v1.ClearHistoryRequest + (*ForgetRequest)(nil), // 4: v1.ForgetRequest + (*ListSnapshotsRequest)(nil), // 5: v1.ListSnapshotsRequest + (*GetOperationsRequest)(nil), // 6: v1.GetOperationsRequest + (*RestoreSnapshotRequest)(nil), // 7: v1.RestoreSnapshotRequest + (*ListSnapshotFilesRequest)(nil), // 8: v1.ListSnapshotFilesRequest + (*ListSnapshotFilesResponse)(nil), // 9: v1.ListSnapshotFilesResponse + (*LogDataRequest)(nil), // 10: v1.LogDataRequest + (*LsEntry)(nil), // 11: v1.LsEntry + (*RunCommandRequest)(nil), // 12: v1.RunCommandRequest + (*emptypb.Empty)(nil), // 13: google.protobuf.Empty + (*Config)(nil), // 14: v1.Config + (*Repo)(nil), // 15: v1.Repo + (*types.StringValue)(nil), // 16: types.StringValue + (*types.Int64Value)(nil), // 17: types.Int64Value + (*OperationEvent)(nil), // 18: v1.OperationEvent + (*OperationList)(nil), // 19: v1.OperationList + (*ResticSnapshotList)(nil), // 20: v1.ResticSnapshotList + (*types.BytesValue)(nil), // 21: types.BytesValue + (*types.StringList)(nil), // 22: types.StringList } var file_v1_service_proto_depIdxs = []int32{ - 0, // 0: v1.ClearHistoryRequest.selector:type_name -> v1.OpSelector - 0, // 1: v1.GetOperationsRequest.selector:type_name -> v1.OpSelector - 9, // 2: v1.ListSnapshotFilesResponse.entries:type_name -> v1.LsEntry - 11, // 3: v1.Backrest.GetConfig:input_type -> google.protobuf.Empty - 12, // 4: v1.Backrest.SetConfig:input_type -> v1.Config - 13, // 5: v1.Backrest.AddRepo:input_type -> v1.Repo - 11, // 6: v1.Backrest.GetOperationEvents:input_type -> google.protobuf.Empty - 4, // 7: v1.Backrest.GetOperations:input_type -> v1.GetOperationsRequest - 3, // 8: v1.Backrest.ListSnapshots:input_type -> v1.ListSnapshotsRequest - 6, // 9: v1.Backrest.ListSnapshotFiles:input_type -> v1.ListSnapshotFilesRequest - 14, // 10: v1.Backrest.IndexSnapshots:input_type -> types.StringValue - 14, // 11: v1.Backrest.Backup:input_type -> types.StringValue - 14, // 12: v1.Backrest.Prune:input_type -> types.StringValue - 2, // 13: v1.Backrest.Forget:input_type -> v1.ForgetRequest - 5, // 14: v1.Backrest.Restore:input_type -> v1.RestoreSnapshotRequest - 14, // 15: v1.Backrest.Unlock:input_type -> types.StringValue - 14, // 16: v1.Backrest.Stats:input_type -> types.StringValue - 15, // 17: v1.Backrest.Cancel:input_type -> types.Int64Value - 8, // 18: v1.Backrest.GetLogs:input_type -> v1.LogDataRequest - 10, // 19: v1.Backrest.RunCommand:input_type -> v1.RunCommandRequest - 15, // 20: v1.Backrest.GetDownloadURL:input_type -> types.Int64Value - 1, // 21: v1.Backrest.ClearHistory:input_type -> v1.ClearHistoryRequest - 14, // 22: v1.Backrest.PathAutocomplete:input_type -> types.StringValue - 12, // 23: v1.Backrest.GetConfig:output_type -> v1.Config - 12, // 24: v1.Backrest.SetConfig:output_type -> v1.Config - 12, // 25: v1.Backrest.AddRepo:output_type -> v1.Config - 16, // 26: v1.Backrest.GetOperationEvents:output_type -> v1.OperationEvent - 17, // 27: v1.Backrest.GetOperations:output_type -> v1.OperationList - 18, // 28: v1.Backrest.ListSnapshots:output_type -> v1.ResticSnapshotList - 7, // 29: v1.Backrest.ListSnapshotFiles:output_type -> v1.ListSnapshotFilesResponse - 11, // 30: v1.Backrest.IndexSnapshots:output_type -> google.protobuf.Empty - 11, // 31: v1.Backrest.Backup:output_type -> google.protobuf.Empty - 11, // 32: v1.Backrest.Prune:output_type -> google.protobuf.Empty - 11, // 33: v1.Backrest.Forget:output_type -> google.protobuf.Empty - 11, // 34: v1.Backrest.Restore:output_type -> google.protobuf.Empty - 11, // 35: v1.Backrest.Unlock:output_type -> google.protobuf.Empty - 11, // 36: v1.Backrest.Stats:output_type -> google.protobuf.Empty - 11, // 37: v1.Backrest.Cancel:output_type -> google.protobuf.Empty - 19, // 38: v1.Backrest.GetLogs:output_type -> types.BytesValue - 19, // 39: v1.Backrest.RunCommand:output_type -> types.BytesValue - 14, // 40: v1.Backrest.GetDownloadURL:output_type -> types.StringValue - 11, // 41: v1.Backrest.ClearHistory:output_type -> google.protobuf.Empty - 20, // 42: v1.Backrest.PathAutocomplete:output_type -> types.StringList - 23, // [23:43] is the sub-list for method output_type - 3, // [3:23] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 0, // 0: v1.DoRepoTaskRequest.task:type_name -> v1.DoRepoTaskRequest.Task + 1, // 1: v1.ClearHistoryRequest.selector:type_name -> v1.OpSelector + 1, // 2: v1.GetOperationsRequest.selector:type_name -> v1.OpSelector + 11, // 3: v1.ListSnapshotFilesResponse.entries:type_name -> v1.LsEntry + 13, // 4: v1.Backrest.GetConfig:input_type -> google.protobuf.Empty + 14, // 5: v1.Backrest.SetConfig:input_type -> v1.Config + 15, // 6: v1.Backrest.AddRepo:input_type -> v1.Repo + 13, // 7: v1.Backrest.GetOperationEvents:input_type -> google.protobuf.Empty + 6, // 8: v1.Backrest.GetOperations:input_type -> v1.GetOperationsRequest + 5, // 9: v1.Backrest.ListSnapshots:input_type -> v1.ListSnapshotsRequest + 8, // 10: v1.Backrest.ListSnapshotFiles:input_type -> v1.ListSnapshotFilesRequest + 16, // 11: v1.Backrest.Backup:input_type -> types.StringValue + 2, // 12: v1.Backrest.DoRepoTask:input_type -> v1.DoRepoTaskRequest + 4, // 13: v1.Backrest.Forget:input_type -> v1.ForgetRequest + 7, // 14: v1.Backrest.Restore:input_type -> v1.RestoreSnapshotRequest + 17, // 15: v1.Backrest.Cancel:input_type -> types.Int64Value + 10, // 16: v1.Backrest.GetLogs:input_type -> v1.LogDataRequest + 12, // 17: v1.Backrest.RunCommand:input_type -> v1.RunCommandRequest + 17, // 18: v1.Backrest.GetDownloadURL:input_type -> types.Int64Value + 3, // 19: v1.Backrest.ClearHistory:input_type -> v1.ClearHistoryRequest + 16, // 20: v1.Backrest.PathAutocomplete:input_type -> types.StringValue + 14, // 21: v1.Backrest.GetConfig:output_type -> v1.Config + 14, // 22: v1.Backrest.SetConfig:output_type -> v1.Config + 14, // 23: v1.Backrest.AddRepo:output_type -> v1.Config + 18, // 24: v1.Backrest.GetOperationEvents:output_type -> v1.OperationEvent + 19, // 25: v1.Backrest.GetOperations:output_type -> v1.OperationList + 20, // 26: v1.Backrest.ListSnapshots:output_type -> v1.ResticSnapshotList + 9, // 27: v1.Backrest.ListSnapshotFiles:output_type -> v1.ListSnapshotFilesResponse + 13, // 28: v1.Backrest.Backup:output_type -> google.protobuf.Empty + 13, // 29: v1.Backrest.DoRepoTask:output_type -> google.protobuf.Empty + 13, // 30: v1.Backrest.Forget:output_type -> google.protobuf.Empty + 13, // 31: v1.Backrest.Restore:output_type -> google.protobuf.Empty + 13, // 32: v1.Backrest.Cancel:output_type -> google.protobuf.Empty + 21, // 33: v1.Backrest.GetLogs:output_type -> types.BytesValue + 21, // 34: v1.Backrest.RunCommand:output_type -> types.BytesValue + 16, // 35: v1.Backrest.GetDownloadURL:output_type -> types.StringValue + 13, // 36: v1.Backrest.ClearHistory:output_type -> google.protobuf.Empty + 22, // 37: v1.Backrest.PathAutocomplete:output_type -> types.StringList + 21, // [21:38] is the sub-list for method output_type + 4, // [4:21] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_v1_service_proto_init() } @@ -1024,7 +1138,7 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClearHistoryRequest); i { + switch v := v.(*DoRepoTaskRequest); i { case 0: return &v.state case 1: @@ -1036,7 +1150,7 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ForgetRequest); i { + switch v := v.(*ClearHistoryRequest); i { case 0: return &v.state case 1: @@ -1048,7 +1162,7 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListSnapshotsRequest); i { + switch v := v.(*ForgetRequest); i { case 0: return &v.state case 1: @@ -1060,7 +1174,7 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetOperationsRequest); i { + switch v := v.(*ListSnapshotsRequest); i { case 0: return &v.state case 1: @@ -1072,7 +1186,7 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RestoreSnapshotRequest); i { + switch v := v.(*GetOperationsRequest); i { case 0: return &v.state case 1: @@ -1084,7 +1198,7 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListSnapshotFilesRequest); i { + switch v := v.(*RestoreSnapshotRequest); i { case 0: return &v.state case 1: @@ -1096,7 +1210,7 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListSnapshotFilesResponse); i { + switch v := v.(*ListSnapshotFilesRequest); i { case 0: return &v.state case 1: @@ -1108,7 +1222,7 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LogDataRequest); i { + switch v := v.(*ListSnapshotFilesResponse); i { case 0: return &v.state case 1: @@ -1120,7 +1234,7 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LsEntry); i { + switch v := v.(*LogDataRequest); i { case 0: return &v.state case 1: @@ -1132,6 +1246,18 @@ func file_v1_service_proto_init() { } } file_v1_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LsEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_v1_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RunCommandRequest); i { case 0: return &v.state @@ -1149,13 +1275,14 @@ func file_v1_service_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_v1_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 11, + NumEnums: 1, + NumMessages: 12, NumExtensions: 0, NumServices: 1, }, GoTypes: file_v1_service_proto_goTypes, DependencyIndexes: file_v1_service_proto_depIdxs, + EnumInfos: file_v1_service_proto_enumTypes, MessageInfos: file_v1_service_proto_msgTypes, }.Build() File_v1_service_proto = out.File diff --git a/gen/go/v1/service_grpc.pb.go b/gen/go/v1/service_grpc.pb.go index 675c4d32..2132a9ef 100644 --- a/gen/go/v1/service_grpc.pb.go +++ b/gen/go/v1/service_grpc.pb.go @@ -28,13 +28,10 @@ const ( Backrest_GetOperations_FullMethodName = "/v1.Backrest/GetOperations" Backrest_ListSnapshots_FullMethodName = "/v1.Backrest/ListSnapshots" Backrest_ListSnapshotFiles_FullMethodName = "/v1.Backrest/ListSnapshotFiles" - Backrest_IndexSnapshots_FullMethodName = "/v1.Backrest/IndexSnapshots" Backrest_Backup_FullMethodName = "/v1.Backrest/Backup" - Backrest_Prune_FullMethodName = "/v1.Backrest/Prune" + Backrest_DoRepoTask_FullMethodName = "/v1.Backrest/DoRepoTask" 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_GetLogs_FullMethodName = "/v1.Backrest/GetLogs" Backrest_RunCommand_FullMethodName = "/v1.Backrest/RunCommand" @@ -54,20 +51,14 @@ type BackrestClient interface { GetOperations(ctx context.Context, in *GetOperationsRequest, opts ...grpc.CallOption) (*OperationList, error) ListSnapshots(ctx context.Context, in *ListSnapshotsRequest, opts ...grpc.CallOption) (*ResticSnapshotList, error) ListSnapshotFiles(ctx context.Context, in *ListSnapshotFilesRequest, opts ...grpc.CallOption) (*ListSnapshotFilesResponse, error) - // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. - IndexSnapshots(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. Backup(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) - // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. - Prune(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. + DoRepoTask(ctx context.Context, in *DoRepoTaskRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. Forget(ctx context.Context, in *ForgetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) // Restore schedules a restore operation. 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) // GetLogs returns the keyed large data for the given operation. @@ -176,15 +167,6 @@ func (c *backrestClient) ListSnapshotFiles(ctx context.Context, in *ListSnapshot return out, nil } -func (c *backrestClient) IndexSnapshots(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Backrest_IndexSnapshots_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *backrestClient) Backup(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, Backrest_Backup_FullMethodName, in, out, opts...) @@ -194,9 +176,9 @@ func (c *backrestClient) Backup(ctx context.Context, in *types.StringValue, opts return out, nil } -func (c *backrestClient) Prune(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *backrestClient) DoRepoTask(ctx context.Context, in *DoRepoTaskRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Backrest_Prune_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Backrest_DoRepoTask_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -221,24 +203,6 @@ func (c *backrestClient) Restore(ctx context.Context, in *RestoreSnapshotRequest return out, nil } -func (c *backrestClient) Unlock(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Backrest_Unlock_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - 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...) @@ -327,20 +291,14 @@ type BackrestServer interface { GetOperations(context.Context, *GetOperationsRequest) (*OperationList, error) ListSnapshots(context.Context, *ListSnapshotsRequest) (*ResticSnapshotList, error) ListSnapshotFiles(context.Context, *ListSnapshotFilesRequest) (*ListSnapshotFilesResponse, error) - // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. - IndexSnapshots(context.Context, *types.StringValue) (*emptypb.Empty, error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. Backup(context.Context, *types.StringValue) (*emptypb.Empty, error) - // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. - Prune(context.Context, *types.StringValue) (*emptypb.Empty, error) + // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. + DoRepoTask(context.Context, *DoRepoTaskRequest) (*emptypb.Empty, error) // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. Forget(context.Context, *ForgetRequest) (*emptypb.Empty, error) // Restore schedules a restore operation. 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) // GetLogs returns the keyed large data for the given operation. @@ -381,14 +339,11 @@ func (UnimplementedBackrestServer) ListSnapshots(context.Context, *ListSnapshots func (UnimplementedBackrestServer) ListSnapshotFiles(context.Context, *ListSnapshotFilesRequest) (*ListSnapshotFilesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListSnapshotFiles not implemented") } -func (UnimplementedBackrestServer) IndexSnapshots(context.Context, *types.StringValue) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method IndexSnapshots not implemented") -} func (UnimplementedBackrestServer) Backup(context.Context, *types.StringValue) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method Backup not implemented") } -func (UnimplementedBackrestServer) Prune(context.Context, *types.StringValue) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Prune not implemented") +func (UnimplementedBackrestServer) DoRepoTask(context.Context, *DoRepoTaskRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DoRepoTask not implemented") } func (UnimplementedBackrestServer) Forget(context.Context, *ForgetRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method Forget not implemented") @@ -396,12 +351,6 @@ func (UnimplementedBackrestServer) Forget(context.Context, *ForgetRequest) (*emp func (UnimplementedBackrestServer) Restore(context.Context, *RestoreSnapshotRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method Restore not implemented") } -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") } @@ -562,24 +511,6 @@ func _Backrest_ListSnapshotFiles_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } -func _Backrest_IndexSnapshots_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).IndexSnapshots(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Backrest_IndexSnapshots_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BackrestServer).IndexSnapshots(ctx, req.(*types.StringValue)) - } - return interceptor(ctx, in, info, handler) -} - func _Backrest_Backup_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 { @@ -598,20 +529,20 @@ func _Backrest_Backup_Handler(srv interface{}, ctx context.Context, dec func(int return interceptor(ctx, in, info, handler) } -func _Backrest_Prune_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(types.StringValue) +func _Backrest_DoRepoTask_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DoRepoTaskRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(BackrestServer).Prune(ctx, in) + return srv.(BackrestServer).DoRepoTask(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Backrest_Prune_FullMethodName, + FullMethod: Backrest_DoRepoTask_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BackrestServer).Prune(ctx, req.(*types.StringValue)) + return srv.(BackrestServer).DoRepoTask(ctx, req.(*DoRepoTaskRequest)) } return interceptor(ctx, in, info, handler) } @@ -652,42 +583,6 @@ func _Backrest_Restore_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } -func _Backrest_Unlock_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).Unlock(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Backrest_Unlock_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BackrestServer).Unlock(ctx, req.(*types.StringValue)) - } - 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 { @@ -830,17 +725,13 @@ var Backrest_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListSnapshotFiles", Handler: _Backrest_ListSnapshotFiles_Handler, }, - { - MethodName: "IndexSnapshots", - Handler: _Backrest_IndexSnapshots_Handler, - }, { MethodName: "Backup", Handler: _Backrest_Backup_Handler, }, { - MethodName: "Prune", - Handler: _Backrest_Prune_Handler, + MethodName: "DoRepoTask", + Handler: _Backrest_DoRepoTask_Handler, }, { MethodName: "Forget", @@ -850,14 +741,6 @@ var Backrest_ServiceDesc = grpc.ServiceDesc{ MethodName: "Restore", Handler: _Backrest_Restore_Handler, }, - { - MethodName: "Unlock", - Handler: _Backrest_Unlock_Handler, - }, - { - MethodName: "Stats", - Handler: _Backrest_Stats_Handler, - }, { MethodName: "Cancel", Handler: _Backrest_Cancel_Handler, diff --git a/gen/go/v1/v1connect/service.connect.go b/gen/go/v1/v1connect/service.connect.go index 3742c9a9..703d92cb 100644 --- a/gen/go/v1/v1connect/service.connect.go +++ b/gen/go/v1/v1connect/service.connect.go @@ -51,20 +51,14 @@ const ( // BackrestListSnapshotFilesProcedure is the fully-qualified name of the Backrest's // ListSnapshotFiles RPC. BackrestListSnapshotFilesProcedure = "/v1.Backrest/ListSnapshotFiles" - // BackrestIndexSnapshotsProcedure is the fully-qualified name of the Backrest's IndexSnapshots RPC. - BackrestIndexSnapshotsProcedure = "/v1.Backrest/IndexSnapshots" // BackrestBackupProcedure is the fully-qualified name of the Backrest's Backup RPC. BackrestBackupProcedure = "/v1.Backrest/Backup" - // BackrestPruneProcedure is the fully-qualified name of the Backrest's Prune RPC. - BackrestPruneProcedure = "/v1.Backrest/Prune" + // BackrestDoRepoTaskProcedure is the fully-qualified name of the Backrest's DoRepoTask RPC. + BackrestDoRepoTaskProcedure = "/v1.Backrest/DoRepoTask" // BackrestForgetProcedure is the fully-qualified name of the Backrest's Forget RPC. BackrestForgetProcedure = "/v1.Backrest/Forget" // BackrestRestoreProcedure is the fully-qualified name of the Backrest's Restore RPC. 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" // BackrestGetLogsProcedure is the fully-qualified name of the Backrest's GetLogs RPC. @@ -90,13 +84,10 @@ var ( backrestGetOperationsMethodDescriptor = backrestServiceDescriptor.Methods().ByName("GetOperations") backrestListSnapshotsMethodDescriptor = backrestServiceDescriptor.Methods().ByName("ListSnapshots") backrestListSnapshotFilesMethodDescriptor = backrestServiceDescriptor.Methods().ByName("ListSnapshotFiles") - backrestIndexSnapshotsMethodDescriptor = backrestServiceDescriptor.Methods().ByName("IndexSnapshots") backrestBackupMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Backup") - backrestPruneMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Prune") + backrestDoRepoTaskMethodDescriptor = backrestServiceDescriptor.Methods().ByName("DoRepoTask") 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") backrestGetLogsMethodDescriptor = backrestServiceDescriptor.Methods().ByName("GetLogs") backrestRunCommandMethodDescriptor = backrestServiceDescriptor.Methods().ByName("RunCommand") @@ -114,20 +105,14 @@ type BackrestClient interface { GetOperations(context.Context, *connect.Request[v1.GetOperationsRequest]) (*connect.Response[v1.OperationList], error) ListSnapshots(context.Context, *connect.Request[v1.ListSnapshotsRequest]) (*connect.Response[v1.ResticSnapshotList], error) ListSnapshotFiles(context.Context, *connect.Request[v1.ListSnapshotFilesRequest]) (*connect.Response[v1.ListSnapshotFilesResponse], error) - // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. - IndexSnapshots(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. Backup(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) - // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. - Prune(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) + // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. + DoRepoTask(context.Context, *connect.Request[v1.DoRepoTaskRequest]) (*connect.Response[emptypb.Empty], error) // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. Forget(context.Context, *connect.Request[v1.ForgetRequest]) (*connect.Response[emptypb.Empty], error) // Restore schedules a restore operation. 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) // GetLogs returns the keyed large data for the given operation. @@ -194,22 +179,16 @@ func NewBackrestClient(httpClient connect.HTTPClient, baseURL string, opts ...co connect.WithSchema(backrestListSnapshotFilesMethodDescriptor), connect.WithClientOptions(opts...), ), - indexSnapshots: connect.NewClient[types.StringValue, emptypb.Empty]( - httpClient, - baseURL+BackrestIndexSnapshotsProcedure, - connect.WithSchema(backrestIndexSnapshotsMethodDescriptor), - connect.WithClientOptions(opts...), - ), backup: connect.NewClient[types.StringValue, emptypb.Empty]( httpClient, baseURL+BackrestBackupProcedure, connect.WithSchema(backrestBackupMethodDescriptor), connect.WithClientOptions(opts...), ), - prune: connect.NewClient[types.StringValue, emptypb.Empty]( + doRepoTask: connect.NewClient[v1.DoRepoTaskRequest, emptypb.Empty]( httpClient, - baseURL+BackrestPruneProcedure, - connect.WithSchema(backrestPruneMethodDescriptor), + baseURL+BackrestDoRepoTaskProcedure, + connect.WithSchema(backrestDoRepoTaskMethodDescriptor), connect.WithClientOptions(opts...), ), forget: connect.NewClient[v1.ForgetRequest, emptypb.Empty]( @@ -224,18 +203,6 @@ func NewBackrestClient(httpClient connect.HTTPClient, baseURL string, opts ...co connect.WithSchema(backrestRestoreMethodDescriptor), connect.WithClientOptions(opts...), ), - unlock: connect.NewClient[types.StringValue, emptypb.Empty]( - httpClient, - baseURL+BackrestUnlockProcedure, - 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, @@ -284,13 +251,10 @@ type backrestClient struct { getOperations *connect.Client[v1.GetOperationsRequest, v1.OperationList] listSnapshots *connect.Client[v1.ListSnapshotsRequest, v1.ResticSnapshotList] listSnapshotFiles *connect.Client[v1.ListSnapshotFilesRequest, v1.ListSnapshotFilesResponse] - indexSnapshots *connect.Client[types.StringValue, emptypb.Empty] backup *connect.Client[types.StringValue, emptypb.Empty] - prune *connect.Client[types.StringValue, emptypb.Empty] + doRepoTask *connect.Client[v1.DoRepoTaskRequest, emptypb.Empty] forget *connect.Client[v1.ForgetRequest, 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] getLogs *connect.Client[v1.LogDataRequest, types.BytesValue] runCommand *connect.Client[v1.RunCommandRequest, types.BytesValue] @@ -334,19 +298,14 @@ func (c *backrestClient) ListSnapshotFiles(ctx context.Context, req *connect.Req return c.listSnapshotFiles.CallUnary(ctx, req) } -// IndexSnapshots calls v1.Backrest.IndexSnapshots. -func (c *backrestClient) IndexSnapshots(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { - return c.indexSnapshots.CallUnary(ctx, req) -} - // Backup calls v1.Backrest.Backup. func (c *backrestClient) Backup(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { return c.backup.CallUnary(ctx, req) } -// Prune calls v1.Backrest.Prune. -func (c *backrestClient) Prune(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { - return c.prune.CallUnary(ctx, req) +// DoRepoTask calls v1.Backrest.DoRepoTask. +func (c *backrestClient) DoRepoTask(ctx context.Context, req *connect.Request[v1.DoRepoTaskRequest]) (*connect.Response[emptypb.Empty], error) { + return c.doRepoTask.CallUnary(ctx, req) } // Forget calls v1.Backrest.Forget. @@ -359,16 +318,6 @@ func (c *backrestClient) Restore(ctx context.Context, req *connect.Request[v1.Re return c.restore.CallUnary(ctx, req) } -// Unlock calls v1.Backrest.Unlock. -func (c *backrestClient) Unlock(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { - 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) @@ -408,20 +357,14 @@ type BackrestHandler interface { GetOperations(context.Context, *connect.Request[v1.GetOperationsRequest]) (*connect.Response[v1.OperationList], error) ListSnapshots(context.Context, *connect.Request[v1.ListSnapshotsRequest]) (*connect.Response[v1.ResticSnapshotList], error) ListSnapshotFiles(context.Context, *connect.Request[v1.ListSnapshotFilesRequest]) (*connect.Response[v1.ListSnapshotFilesResponse], error) - // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. - IndexSnapshots(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. Backup(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) - // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. - Prune(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) + // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. + DoRepoTask(context.Context, *connect.Request[v1.DoRepoTaskRequest]) (*connect.Response[emptypb.Empty], error) // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. Forget(context.Context, *connect.Request[v1.ForgetRequest]) (*connect.Response[emptypb.Empty], error) // Restore schedules a restore operation. 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) // GetLogs returns the keyed large data for the given operation. @@ -484,22 +427,16 @@ func NewBackrestHandler(svc BackrestHandler, opts ...connect.HandlerOption) (str connect.WithSchema(backrestListSnapshotFilesMethodDescriptor), connect.WithHandlerOptions(opts...), ) - backrestIndexSnapshotsHandler := connect.NewUnaryHandler( - BackrestIndexSnapshotsProcedure, - svc.IndexSnapshots, - connect.WithSchema(backrestIndexSnapshotsMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) backrestBackupHandler := connect.NewUnaryHandler( BackrestBackupProcedure, svc.Backup, connect.WithSchema(backrestBackupMethodDescriptor), connect.WithHandlerOptions(opts...), ) - backrestPruneHandler := connect.NewUnaryHandler( - BackrestPruneProcedure, - svc.Prune, - connect.WithSchema(backrestPruneMethodDescriptor), + backrestDoRepoTaskHandler := connect.NewUnaryHandler( + BackrestDoRepoTaskProcedure, + svc.DoRepoTask, + connect.WithSchema(backrestDoRepoTaskMethodDescriptor), connect.WithHandlerOptions(opts...), ) backrestForgetHandler := connect.NewUnaryHandler( @@ -514,18 +451,6 @@ func NewBackrestHandler(svc BackrestHandler, opts ...connect.HandlerOption) (str connect.WithSchema(backrestRestoreMethodDescriptor), connect.WithHandlerOptions(opts...), ) - backrestUnlockHandler := connect.NewUnaryHandler( - BackrestUnlockProcedure, - svc.Unlock, - connect.WithSchema(backrestUnlockMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - backrestStatsHandler := connect.NewUnaryHandler( - BackrestStatsProcedure, - svc.Stats, - connect.WithSchema(backrestStatsMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) backrestCancelHandler := connect.NewUnaryHandler( BackrestCancelProcedure, svc.Cancel, @@ -578,20 +503,14 @@ func NewBackrestHandler(svc BackrestHandler, opts ...connect.HandlerOption) (str backrestListSnapshotsHandler.ServeHTTP(w, r) case BackrestListSnapshotFilesProcedure: backrestListSnapshotFilesHandler.ServeHTTP(w, r) - case BackrestIndexSnapshotsProcedure: - backrestIndexSnapshotsHandler.ServeHTTP(w, r) case BackrestBackupProcedure: backrestBackupHandler.ServeHTTP(w, r) - case BackrestPruneProcedure: - backrestPruneHandler.ServeHTTP(w, r) + case BackrestDoRepoTaskProcedure: + backrestDoRepoTaskHandler.ServeHTTP(w, r) case BackrestForgetProcedure: backrestForgetHandler.ServeHTTP(w, r) case BackrestRestoreProcedure: backrestRestoreHandler.ServeHTTP(w, r) - case BackrestUnlockProcedure: - backrestUnlockHandler.ServeHTTP(w, r) - case BackrestStatsProcedure: - backrestStatsHandler.ServeHTTP(w, r) case BackrestCancelProcedure: backrestCancelHandler.ServeHTTP(w, r) case BackrestGetLogsProcedure: @@ -641,16 +560,12 @@ func (UnimplementedBackrestHandler) ListSnapshotFiles(context.Context, *connect. return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.ListSnapshotFiles is not implemented")) } -func (UnimplementedBackrestHandler) IndexSnapshots(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.IndexSnapshots is not implemented")) -} - func (UnimplementedBackrestHandler) Backup(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.Backup is not implemented")) } -func (UnimplementedBackrestHandler) Prune(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.Prune is not implemented")) +func (UnimplementedBackrestHandler) DoRepoTask(context.Context, *connect.Request[v1.DoRepoTaskRequest]) (*connect.Response[emptypb.Empty], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.DoRepoTask is not implemented")) } func (UnimplementedBackrestHandler) Forget(context.Context, *connect.Request[v1.ForgetRequest]) (*connect.Response[emptypb.Empty], error) { @@ -661,14 +576,6 @@ func (UnimplementedBackrestHandler) Restore(context.Context, *connect.Request[v1 return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.Restore is not implemented")) } -func (UnimplementedBackrestHandler) Unlock(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { - 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")) } diff --git a/internal/api/backresthandler.go b/internal/api/backresthandler.go index 6b11e47c..3b9f7e9c 100644 --- a/internal/api/backresthandler.go +++ b/internal/api/backresthandler.go @@ -331,13 +331,41 @@ func (s *BackrestHandler) Forget(ctx context.Context, req *connect.Request[v1.Fo return connect.NewResponse(&emptypb.Empty{}), nil } -func (s *BackrestHandler) Prune(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { +func (s BackrestHandler) DoRepoTask(ctx context.Context, req *connect.Request[v1.DoRepoTaskRequest]) (*connect.Response[emptypb.Empty], error) { + var task tasks.Task + priority := tasks.TaskPriorityInteractive + switch req.Msg.Task { + case v1.DoRepoTaskRequest_TASK_CHECK: + task = tasks.NewCheckTask(req.Msg.RepoId, tasks.PlanForSystemTasks, true) + case v1.DoRepoTaskRequest_TASK_PRUNE: + task = tasks.NewPruneTask(req.Msg.RepoId, tasks.PlanForSystemTasks, true) + priority |= tasks.TaskPriorityPrune + case v1.DoRepoTaskRequest_TASK_STATS: + task = tasks.NewStatsTask(req.Msg.RepoId, tasks.PlanForSystemTasks, true) + priority |= tasks.TaskPriorityStats + case v1.DoRepoTaskRequest_TASK_INDEX_SNAPSHOTS: + task = tasks.NewOneoffIndexSnapshotsTask(req.Msg.RepoId, time.Now()) + priority |= tasks.TaskPriorityIndexSnapshots + case v1.DoRepoTaskRequest_TASK_UNLOCK: + repo, err := s.orchestrator.GetRepoOrchestrator(req.Msg.RepoId) + if err != nil { + return nil, fmt.Errorf("failed to get repo %q: %w", req.Msg.RepoId, err) + } + if err := repo.Unlock(ctx); err != nil { + return nil, fmt.Errorf("failed to unlock repo %q: %w", req.Msg.RepoId, err) + } + default: + return nil, fmt.Errorf("unknown task %v", req.Msg.Task.String()) + } + var err error wait := make(chan struct{}) - s.orchestrator.ScheduleTask(tasks.NewPruneTask(req.Msg.Value, tasks.PlanForSystemTasks, true), tasks.TaskPriorityInteractive+tasks.TaskPriorityPrune, func(e error) { + if err := s.orchestrator.ScheduleTask(task, priority, func(e error) { err = e close(wait) - }) + }); err != nil { + return nil, err + } <-wait if err != nil { return nil, err @@ -370,32 +398,6 @@ func (s *BackrestHandler) Restore(ctx context.Context, req *connect.Request[v1.R return connect.NewResponse(&emptypb.Empty{}), nil } -func (s *BackrestHandler) Unlock(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { - repo, err := s.orchestrator.GetRepoOrchestrator(req.Msg.Value) - if err != nil { - return nil, fmt.Errorf("failed to get repo %q: %w", req.Msg.Value, err) - } - - if err := repo.Unlock(context.Background()); err != nil { - return nil, fmt.Errorf("failed to unlock repo %q: %w", req.Msg.Value, err) - } - - return connect.NewResponse(&emptypb.Empty{}), nil -} - -func (s *BackrestHandler) Stats(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { - var err error - wait := make(chan struct{}) - if err := s.orchestrator.ScheduleTask(tasks.NewStatsTask(req.Msg.Value, tasks.PlanForSystemTasks, true), tasks.TaskPriorityInteractive+tasks.TaskPriorityStats, func(e error) { - err = e - close(wait) - }); err != nil { - return nil, err - } - <-wait - return connect.NewResponse(&emptypb.Empty{}), err -} - func (s *BackrestHandler) RunCommand(ctx context.Context, req *connect.Request[v1.RunCommandRequest], resp *connect.ServerStream[types.BytesValue]) error { repo, err := s.orchestrator.GetRepoOrchestrator(req.Msg.RepoId) if err != nil { diff --git a/internal/ioutil/ioutil.go b/internal/ioutil/ioutil.go index b58a6fee..d06e31bd 100644 --- a/internal/ioutil/ioutil.go +++ b/internal/ioutil/ioutil.go @@ -107,6 +107,10 @@ func (w *OutputCapturer) Bytes() []byte { return buf.Bytes() } +func (w *OutputCapturer) String() string { + return string(w.Bytes()) +} + type SynchronizedWriter struct { Mu sync.Mutex W io.Writer diff --git a/internal/orchestrator/repo/repo.go b/internal/orchestrator/repo/repo.go index 8cc4a457..df17636d 100644 --- a/internal/orchestrator/repo/repo.go +++ b/internal/orchestrator/repo/repo.go @@ -270,12 +270,17 @@ func (r *RepoOrchestrator) Check(ctx context.Context, output io.Writer) error { defer flush() var opts []restic.GenericOption - if r.repoConfig.CheckOptions != nil { - opts = append(opts, restic.WithFlags(r.repoConfig.CheckOptions...)) + if r.repoConfig.CheckPolicy != nil { + switch m := r.repoConfig.CheckPolicy.Mode.(type) { + case *v1.CheckPolicy_ReadDataSubsetPercent: + opts = append(opts, restic.WithFlags(fmt.Sprintf("--read-data-subset=%v%%", m.ReadDataSubsetPercent))) + case *v1.CheckPolicy_StructureOnly: + default: + } } r.l.Debug("checking repo") - err := r.repo.Check(ctx, output) + err := r.repo.Check(ctx, output, opts...) if err != nil { return fmt.Errorf("check repo %v: %w", r.repoConfig.Id, err) } diff --git a/internal/orchestrator/repo/repo_test.go b/internal/orchestrator/repo/repo_test.go index a3a759fa..744d349b 100644 --- a/internal/orchestrator/repo/repo_test.go +++ b/internal/orchestrator/repo/repo_test.go @@ -1,6 +1,7 @@ package repo import ( + "bytes" "context" "os" "slices" @@ -189,3 +190,59 @@ func TestEnvVarPropagation(t *testing.T) { t.Fatal("expected snapshot id") } } + +func TestCheck(t *testing.T) { + t.Parallel() + + tcs := []struct { + name string + repo *v1.Repo + }{ + { + name: "check structure", + repo: &v1.Repo{ + Id: "test", + Uri: t.TempDir(), + Password: "test", + CheckPolicy: &v1.CheckPolicy{ + Mode: nil, + }, + }, + }, + { + name: "read data percent", + repo: &v1.Repo{ + Id: "test", + Uri: t.TempDir(), + Password: "test", + CheckPolicy: &v1.CheckPolicy{ + Mode: &v1.CheckPolicy_ReadDataSubsetPercent{ + ReadDataSubsetPercent: 50, + }, + }, + }, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + orchestrator, err := NewRepoOrchestrator(configForTest, tc.repo, helpers.ResticBinary(t)) + if err != nil { + t.Fatalf("failed to create repo orchestrator: %v", err) + } + + buf := bytes.NewBuffer(nil) + + err = orchestrator.Init(context.Background()) + if err != nil { + t.Fatalf("init error: %v", err) + } + + err = orchestrator.Check(context.Background(), buf) + if err != nil { + t.Errorf("check error: %v", err) + } + t.Logf("check output: %s", buf.String()) + }) + } +} diff --git a/internal/orchestrator/tasks/task.go b/internal/orchestrator/tasks/task.go index 64937c35..3388d658 100644 --- a/internal/orchestrator/tasks/task.go +++ b/internal/orchestrator/tasks/task.go @@ -17,12 +17,13 @@ const ( PlanForUnassociatedOperations = "_unassociated_" PlanForSystemTasks = "_system_" // plan for system tasks e.g. garbage collection, prune, stats, etc. - TaskPriorityStats = -1 - TaskPriorityDefault = 0 - TaskPriorityInteractive = 1 << 1 + TaskPriorityStats = 0 + TaskPriorityDefault = 1 << 1 // default priority TaskPriorityForget = 1 << 2 TaskPriorityIndexSnapshots = 1 << 3 TaskPriorityPrune = 1 << 4 + TaskPriorityCheck = 1 << 4 + TaskPriorityInteractive = 1 << 6 // highest priority ) // TaskRunner is an interface for running tasks. It is used by tasks to create operations and write logs. diff --git a/pkg/restic/restic.go b/pkg/restic/restic.go index 5be40c6e..59f25e78 100644 --- a/pkg/restic/restic.go +++ b/pkg/restic/restic.go @@ -97,11 +97,14 @@ func (r *Repo) pipeCmdOutputToWriter(cmd *exec.Cmd, handlers ...io.Writer) { // Returns true if exists, false if it does not exist OR an access error occurred. func (r *Repo) Exists(ctx context.Context, opts ...GenericOption) error { r.checkExists.Do(func() { + output := bytes.NewBuffer(nil) cmd := r.commandWithContext(ctx, []string{"cat", "config"}, opts...) + r.pipeCmdOutputToWriter(cmd, output) if err := cmd.Run(); err != nil { - r.exists = newCmdError(ctx, cmd, err) + r.exists = newCmdError(ctx, cmd, newErrorWithOutput(err, output.String())) + } else { + r.exists = nil } - r.exists = nil }) return r.exists } @@ -183,7 +186,7 @@ func (r *Repo) Backup(ctx context.Context, paths []string, progressCallback func } } } - return summary, newCmdError(ctx, cmd, errors.Join(cmdErr, readErr)) + return summary, newCmdError(ctx, cmd, newErrorWithOutput(errors.Join(cmdErr, readErr), outputForErr.String())) } return summary, nil } @@ -261,6 +264,7 @@ func (r *Repo) Prune(ctx context.Context, pruneOutput io.Writer, opts ...Generic func (r *Repo) Check(ctx context.Context, checkOutput io.Writer, opts ...GenericOption) error { args := []string{"check"} cmd := r.commandWithContext(ctx, args, opts...) + cmd.Stdin = bytes.NewBuffer(nil) if checkOutput != nil { r.pipeCmdOutputToWriter(cmd, checkOutput) } diff --git a/pkg/restic/restic_test.go b/pkg/restic/restic_test.go index 917b52be..2ee5e9e1 100644 --- a/pkg/restic/restic_test.go +++ b/pkg/restic/restic_test.go @@ -493,31 +493,6 @@ func TestResticCheck(t *testing.T) { if !bytes.Contains(output.Bytes(), []byte(wantStr)) { t.Errorf("wanted output to contain 'no errors were found', got: %s", output.String()) } - - // corrupt the repo - filepath.WalkDir(repo, func(path string, d os.DirEntry, err error) error { - if err != nil { - return err - } - if d.IsDir() || !strings.HasSuffix(path, "snapshot") { - return nil - } - if err := os.WriteFile(path, []byte("corrupted"), 0644); err != nil { - return err - } - return nil - }) - - // check repo - output.Reset() - if err := r.Check(context.Background(), output); err == nil { - t.Errorf("wanted error, got: nil") - } - - wantStr = "error: repository contains errors" - if !bytes.Contains(output.Bytes(), []byte(wantStr)) { - t.Errorf("wanted output to contain 'repository contains errors', got: %s", output.String()) - } } func toRepoPath(path string) string { diff --git a/proto/v1/config.proto b/proto/v1/config.proto index 5c62f9ba..f9744671 100644 --- a/proto/v1/config.proto +++ b/proto/v1/config.proto @@ -93,9 +93,9 @@ message PrunePolicy { message CheckPolicy { Schedule schedule = 1 [json_name="schedule"]; - oneof read_policy { - bool disabled = 100 [json_name="disabled"]; // disable the check. - int32 read_percent = 101 [json_name="readPercent"]; // check a percentage of snapshots. + oneof mode { + bool structure_only = 100 [json_name="structureOnly"]; // only check the structure of the repo. No pack data is read. + int32 read_data_subset_percent = 101 [json_name="readDataSubsetPercent"]; // check a percentage of pack data. } } diff --git a/proto/v1/service.proto b/proto/v1/service.proto index 27066baa..7a3ff2e5 100644 --- a/proto/v1/service.proto +++ b/proto/v1/service.proto @@ -26,14 +26,11 @@ service Backrest { rpc ListSnapshotFiles(ListSnapshotFilesRequest) returns (ListSnapshotFilesResponse) {} - // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. - rpc IndexSnapshots(types.StringValue) returns (google.protobuf.Empty) {} - // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. rpc Backup(types.StringValue) returns (google.protobuf.Empty) {} - // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. - rpc Prune(types.StringValue) returns (google.protobuf.Empty) {} + // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. + rpc DoRepoTask(DoRepoTaskRequest) returns (google.protobuf.Empty) {} // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. rpc Forget(ForgetRequest) returns (google.protobuf.Empty) {} @@ -41,12 +38,6 @@ service Backrest { // Restore schedules a restore operation. rpc Restore(RestoreSnapshotRequest) returns (google.protobuf.Empty) {} - // 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) {} @@ -75,6 +66,19 @@ message OpSelector { int64 flow_id = 5; } +message DoRepoTaskRequest { + string repo_id = 1; + enum Task { + TASK_NONE = 0; + TASK_INDEX_SNAPSHOTS = 1; + TASK_PRUNE = 2; + TASK_CHECK = 3; + TASK_STATS = 4; + TASK_UNLOCK = 5; + } + Task task = 2; +} + message ClearHistoryRequest { OpSelector selector = 1; bool only_failed = 2; diff --git a/webui/gen/ts/v1/config_pb.ts b/webui/gen/ts/v1/config_pb.ts index 9d551568..1e7ead03 100644 --- a/webui/gen/ts/v1/config_pb.ts +++ b/webui/gen/ts/v1/config_pb.ts @@ -646,24 +646,24 @@ export class CheckPolicy extends Message { schedule?: Schedule; /** - * @generated from oneof v1.CheckPolicy.read_policy + * @generated from oneof v1.CheckPolicy.mode */ - readPolicy: { + mode: { /** - * disable the check. + * only check the structure of the repo. No pack data is read. * - * @generated from field: bool disabled = 100; + * @generated from field: bool structure_only = 100; */ value: boolean; - case: "disabled"; + case: "structureOnly"; } | { /** - * check a percentage of snapshots. + * check a percentage of pack data. * - * @generated from field: int32 read_percent = 101; + * @generated from field: int32 read_data_subset_percent = 101; */ value: number; - case: "readPercent"; + case: "readDataSubsetPercent"; } | { case: undefined; value?: undefined } = { case: undefined }; constructor(data?: PartialMessage) { @@ -675,8 +675,8 @@ export class CheckPolicy extends Message { static readonly typeName = "v1.CheckPolicy"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "schedule", kind: "message", T: Schedule }, - { no: 100, name: "disabled", kind: "scalar", T: 8 /* ScalarType.BOOL */, oneof: "read_policy" }, - { no: 101, name: "read_percent", kind: "scalar", T: 5 /* ScalarType.INT32 */, oneof: "read_policy" }, + { no: 100, name: "structure_only", kind: "scalar", T: 8 /* ScalarType.BOOL */, oneof: "mode" }, + { no: 101, name: "read_data_subset_percent", kind: "scalar", T: 5 /* ScalarType.INT32 */, oneof: "mode" }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): CheckPolicy { diff --git a/webui/gen/ts/v1/service_connect.ts b/webui/gen/ts/v1/service_connect.ts index 63f23313..38b50949 100644 --- a/webui/gen/ts/v1/service_connect.ts +++ b/webui/gen/ts/v1/service_connect.ts @@ -6,7 +6,7 @@ import { Empty, MethodKind } from "@bufbuild/protobuf"; import { Config, Repo } from "./config_pb.js"; import { OperationEvent, OperationList } from "./operations_pb.js"; -import { ClearHistoryRequest, ForgetRequest, GetOperationsRequest, ListSnapshotFilesRequest, ListSnapshotFilesResponse, ListSnapshotsRequest, LogDataRequest, RestoreSnapshotRequest, RunCommandRequest } from "./service_pb.js"; +import { ClearHistoryRequest, DoRepoTaskRequest, ForgetRequest, GetOperationsRequest, ListSnapshotFilesRequest, ListSnapshotFilesResponse, ListSnapshotsRequest, LogDataRequest, RestoreSnapshotRequest, RunCommandRequest } from "./service_pb.js"; import { ResticSnapshotList } from "./restic_pb.js"; import { BytesValue, Int64Value, StringList, StringValue } from "../types/value_pb.js"; @@ -79,17 +79,6 @@ export const Backrest = { O: ListSnapshotFilesResponse, kind: MethodKind.Unary, }, - /** - * IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. - * - * @generated from rpc v1.Backrest.IndexSnapshots - */ - indexSnapshots: { - name: "IndexSnapshots", - I: StringValue, - O: Empty, - kind: MethodKind.Unary, - }, /** * Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. * @@ -102,13 +91,13 @@ export const Backrest = { kind: MethodKind.Unary, }, /** - * Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. + * DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. * - * @generated from rpc v1.Backrest.Prune + * @generated from rpc v1.Backrest.DoRepoTask */ - prune: { - name: "Prune", - I: StringValue, + doRepoTask: { + name: "DoRepoTask", + I: DoRepoTaskRequest, O: Empty, kind: MethodKind.Unary, }, @@ -134,28 +123,6 @@ export const Backrest = { O: Empty, kind: MethodKind.Unary, }, - /** - * Unlock synchronously attempts to unlock the repo. Will block if other operations are in progress. - * - * @generated from rpc v1.Backrest.Unlock - */ - unlock: { - name: "Unlock", - I: StringValue, - 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. * diff --git a/webui/gen/ts/v1/service_pb.ts b/webui/gen/ts/v1/service_pb.ts index b86a1d6f..487e7d05 100644 --- a/webui/gen/ts/v1/service_pb.ts +++ b/webui/gen/ts/v1/service_pb.ts @@ -69,6 +69,93 @@ export class OpSelector extends Message { } } +/** + * @generated from message v1.DoRepoTaskRequest + */ +export class DoRepoTaskRequest extends Message { + /** + * @generated from field: string repo_id = 1; + */ + repoId = ""; + + /** + * @generated from field: v1.DoRepoTaskRequest.Task task = 2; + */ + task = DoRepoTaskRequest_Task.NONE; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "v1.DoRepoTaskRequest"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "repo_id", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "task", kind: "enum", T: proto3.getEnumType(DoRepoTaskRequest_Task) }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): DoRepoTaskRequest { + return new DoRepoTaskRequest().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): DoRepoTaskRequest { + return new DoRepoTaskRequest().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): DoRepoTaskRequest { + return new DoRepoTaskRequest().fromJsonString(jsonString, options); + } + + static equals(a: DoRepoTaskRequest | PlainMessage | undefined, b: DoRepoTaskRequest | PlainMessage | undefined): boolean { + return proto3.util.equals(DoRepoTaskRequest, a, b); + } +} + +/** + * @generated from enum v1.DoRepoTaskRequest.Task + */ +export enum DoRepoTaskRequest_Task { + /** + * @generated from enum value: TASK_NONE = 0; + */ + NONE = 0, + + /** + * @generated from enum value: TASK_INDEX_SNAPSHOTS = 1; + */ + INDEX_SNAPSHOTS = 1, + + /** + * @generated from enum value: TASK_PRUNE = 2; + */ + PRUNE = 2, + + /** + * @generated from enum value: TASK_CHECK = 3; + */ + CHECK = 3, + + /** + * @generated from enum value: TASK_STATS = 4; + */ + STATS = 4, + + /** + * @generated from enum value: TASK_UNLOCK = 5; + */ + UNLOCK = 5, +} +// Retrieve enum metadata with: proto3.getEnumType(DoRepoTaskRequest_Task) +proto3.util.setEnumType(DoRepoTaskRequest_Task, "v1.DoRepoTaskRequest.Task", [ + { no: 0, name: "TASK_NONE" }, + { no: 1, name: "TASK_INDEX_SNAPSHOTS" }, + { no: 2, name: "TASK_PRUNE" }, + { no: 3, name: "TASK_CHECK" }, + { no: 4, name: "TASK_STATS" }, + { no: 5, name: "TASK_UNLOCK" }, +]); + /** * @generated from message v1.ClearHistoryRequest */ diff --git a/webui/src/components/OperationList.tsx b/webui/src/components/OperationList.tsx index 1df1d743..d526bf58 100644 --- a/webui/src/components/OperationList.tsx +++ b/webui/src/components/OperationList.tsx @@ -9,6 +9,7 @@ import { BackupInfo, BackupInfoCollector, getOperations, + matchSelector, subscribeToOperations, unsubscribeFromOperations, } from "../state/oplog"; @@ -45,10 +46,11 @@ export const OperationList = ({ const backupCollector = new BackupInfoCollector(filter); const lis = (opEvent: OperationEvent) => { - if (!!req.planId && opEvent.operation!.planId !== req.planId) { - return; - } - if (!!req.repoId && opEvent.operation!.repoId !== req.repoId) { + if ( + !req.selector || + !opEvent.operation || + !matchSelector(req.selector, opEvent.operation) + ) { return; } if (opEvent.type !== OperationEventType.EVENT_DELETED) { @@ -66,7 +68,7 @@ export const OperationList = ({ return b.startTimeMs - a.startTimeMs; }); setBackups(backups); - }, 50), + }, 50) ); getOperations(req) diff --git a/webui/src/components/OperationRow.tsx b/webui/src/components/OperationRow.tsx index 368ccf0a..7f0d20a6 100644 --- a/webui/src/components/OperationRow.tsx +++ b/webui/src/components/OperationRow.tsx @@ -25,6 +25,7 @@ import { DownloadOutlined, RobotOutlined, InfoCircleOutlined, + FileSearchOutlined, } from "@ant-design/icons"; import { BackupProgressEntry, ResticSnapshot } from "../../gen/ts/v1/restic_pb"; import { @@ -97,6 +98,8 @@ export const OperationRow = ({ case DisplayType.PRUNE: avatar = ; break; + case DisplayType.CHECK: + avatar = ; case DisplayType.RUNHOOK: avatar = ; break; @@ -241,6 +244,21 @@ export const OperationRow = ({ ]} /> ); + } else if (operation.op.case === "operationCheck") { + const check = operation.op.value; + body = ( + {check.output}, + }, + ]} + /> + ); } else if (operation.op.case === "operationRestore") { const restore = operation.op.value; const progress = Math.round((details.percentage || 0) * 10) / 10; diff --git a/webui/src/state/oplog.ts b/webui/src/state/oplog.ts index 2d926e52..96c188e0 100644 --- a/webui/src/state/oplog.ts +++ b/webui/src/state/oplog.ts @@ -99,6 +99,7 @@ export enum DisplayType { SNAPSHOT, FORGET, PRUNE, + CHECK, RESTORE, STATS, RUNHOOK, @@ -335,6 +336,8 @@ export const getTypeForDisplay = (op: Operation) => { return DisplayType.FORGET; case "operationPrune": return DisplayType.PRUNE; + case "operationCheck": + return DisplayType.CHECK; case "operationRestore": return DisplayType.RESTORE; case "operationStats": @@ -356,6 +359,8 @@ export const displayTypeToString = (type: DisplayType) => { return "Forget"; case DisplayType.PRUNE: return "Prune"; + case DisplayType.CHECK: + return "Check"; case DisplayType.RESTORE: return "Restore"; case DisplayType.STATS: diff --git a/webui/src/views/PlanView.tsx b/webui/src/views/PlanView.tsx index c907fdd6..d8bb066b 100644 --- a/webui/src/views/PlanView.tsx +++ b/webui/src/views/PlanView.tsx @@ -6,7 +6,12 @@ import { OperationList } from "../components/OperationList"; import { OperationTree } from "../components/OperationTree"; import { MAX_OPERATION_HISTORY } from "../constants"; import { backrestService } from "../api"; -import { GetOperationsRequest, OpSelector } from "../../gen/ts/v1/service_pb"; +import { + DoRepoTaskRequest, + DoRepoTaskRequest_Task, + GetOperationsRequest, + OpSelector, +} from "../../gen/ts/v1/service_pb"; import { SpinButton } from "../components/SpinButton"; import { shouldHideStatus } from "../state/oplog"; import { useShowModal } from "../components/ModalManager"; @@ -27,7 +32,12 @@ export const PlanView = ({ plan }: React.PropsWithChildren<{ plan: Plan }>) => { const handleUnlockNow = async () => { try { alertsApi.info("Unlocking repo..."); - await backrestService.unlock({ value: plan.repo! }); + await backrestService.doRepoTask( + new DoRepoTaskRequest({ + repoId: plan.repo!, + task: DoRepoTaskRequest_Task.UNLOCK, + }) + ); alertsApi.success("Repo unlocked."); } catch (e: any) { alertsApi.error("Failed to unlock repo: " + e.message); diff --git a/webui/src/views/RepoView.tsx b/webui/src/views/RepoView.tsx index 4570c9ae..f42e4ce9 100644 --- a/webui/src/views/RepoView.tsx +++ b/webui/src/views/RepoView.tsx @@ -4,7 +4,12 @@ import { Flex, Tabs, Tooltip, Typography, Button } from "antd"; import { OperationList } from "../components/OperationList"; import { OperationTree } from "../components/OperationTree"; import { MAX_OPERATION_HISTORY, STATS_OPERATION_HISTORY } from "../constants"; -import { GetOperationsRequest, OpSelector } from "../../gen/ts/v1/service_pb"; +import { + DoRepoTaskRequest, + DoRepoTaskRequest_Task, + GetOperationsRequest, + OpSelector, +} from "../../gen/ts/v1/service_pb"; import { shouldHideStatus } from "../state/oplog"; import { backrestService } from "../api"; import { StringValue } from "@bufbuild/protobuf"; @@ -23,8 +28,11 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => { // Task handlers const handleIndexNow = async () => { try { - await backrestService.indexSnapshots( - new StringValue({ value: repo.id! }) + await backrestService.doRepoTask( + new DoRepoTaskRequest({ + repoId: repo.id!, + task: DoRepoTaskRequest_Task.INDEX_SNAPSHOTS, + }) ); } catch (e: any) { alertsApi.error("Failed to index snapshots: " + e.message); @@ -33,7 +41,12 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => { const handleStatsNow = async () => { try { - await backrestService.stats(new StringValue({ value: repo.id! })); + await backrestService.doRepoTask( + new DoRepoTaskRequest({ + repoId: repo.id!, + task: DoRepoTaskRequest_Task.STATS, + }) + ); } catch (e: any) { alertsApi.error("Failed to compute stats: " + e.message); } @@ -41,12 +54,30 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => { const handlePruneNow = async () => { try { - await backrestService.prune({ value: repo.id }); + await backrestService.doRepoTask( + new DoRepoTaskRequest({ + repoId: repo.id!, + task: DoRepoTaskRequest_Task.PRUNE, + }) + ); } catch (e: any) { alertsApi.error("Failed to prune: " + e.message); } }; + const handleCheckNow = async () => { + try { + await backrestService.doRepoTask( + new DoRepoTaskRequest({ + repoId: repo.id!, + task: DoRepoTaskRequest_Task.CHECK, + }) + ); + } catch (e: any) { + alertsApi.error("Failed to check: " + e.message); + } + }; + // Gracefully handle deletions by checking if the plan is still in the config. let repoInConfig = config?.repos?.find((r) => r.id === repo.id); if (!repoInConfig) { @@ -143,6 +174,12 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => { + + + Check Now + + + Compute Stats From 23a5b6c60663e5560a397b3fe99bc7263053144c Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 01:13:22 -0700 Subject: [PATCH 04/14] enable scheduling check operation --- internal/orchestrator/orchestrator.go | 8 +++- internal/orchestrator/repo/repo.go | 4 +- internal/orchestrator/tasks/taskcheck.go | 8 ++-- webui/src/components/ScheduleFormItem.tsx | 46 +++++++++++++++++++---- webui/src/views/AddPlanModal.tsx | 10 ++++- webui/src/views/AddRepoModal.tsx | 36 ++++++++++++++++++ 6 files changed, 97 insertions(+), 15 deletions(-) diff --git a/internal/orchestrator/orchestrator.go b/internal/orchestrator/orchestrator.go index 6b9437e0..78114435 100644 --- a/internal/orchestrator/orchestrator.go +++ b/internal/orchestrator/orchestrator.go @@ -166,9 +166,15 @@ func (o *Orchestrator) ScheduleDefaultTasks(config *v1.Config) error { for _, repo := range config.Repos { // Schedule a prune task for the repo t := tasks.NewPruneTask(repo.GetId(), tasks.PlanForSystemTasks, false) - if err := o.ScheduleTask(t, tasks.TaskPriorityDefault); err != nil { + if err := o.ScheduleTask(t, tasks.TaskPriorityPrune); err != nil { return fmt.Errorf("schedule prune task for repo %q: %w", repo.GetId(), err) } + + // Schedule a check task for the repo + t = tasks.NewCheckTask(repo.GetId(), tasks.PlanForSystemTasks, false) + if err := o.ScheduleTask(t, tasks.TaskPriorityCheck); err != nil { + return fmt.Errorf("schedule check task for repo %q: %w", repo.GetId(), err) + } } return nil diff --git a/internal/orchestrator/repo/repo.go b/internal/orchestrator/repo/repo.go index df17636d..bc2d2ae3 100644 --- a/internal/orchestrator/repo/repo.go +++ b/internal/orchestrator/repo/repo.go @@ -273,7 +273,9 @@ func (r *RepoOrchestrator) Check(ctx context.Context, output io.Writer) error { if r.repoConfig.CheckPolicy != nil { switch m := r.repoConfig.CheckPolicy.Mode.(type) { case *v1.CheckPolicy_ReadDataSubsetPercent: - opts = append(opts, restic.WithFlags(fmt.Sprintf("--read-data-subset=%v%%", m.ReadDataSubsetPercent))) + if m.ReadDataSubsetPercent > 0 { + opts = append(opts, restic.WithFlags(fmt.Sprintf("--read-data-subset=%v%%", m.ReadDataSubsetPercent))) + } case *v1.CheckPolicy_StructureOnly: default: } diff --git a/internal/orchestrator/tasks/taskcheck.go b/internal/orchestrator/tasks/taskcheck.go index 1659540f..dea47d39 100644 --- a/internal/orchestrator/tasks/taskcheck.go +++ b/internal/orchestrator/tasks/taskcheck.go @@ -43,7 +43,7 @@ func (t *CheckTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, error Task: t, RunAt: now, Op: &v1.Operation{ - Op: &v1.Operation_OperationPrune{}, + Op: &v1.Operation_OperationCheck{}, }, }, nil } @@ -53,13 +53,13 @@ func (t *CheckTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, error return ScheduledTask{}, fmt.Errorf("get repo %v: %w", t.RepoID(), err) } - if repo.PrunePolicy.GetSchedule() == nil { + if repo.CheckPolicy.GetSchedule() == nil { return NeverScheduledTask, nil } var lastRan time.Time if err := runner.OpLog().ForEach(oplog.Query{RepoId: t.RepoID()}, indexutil.Reversed(indexutil.CollectAll()), func(op *v1.Operation) error { - if _, ok := op.Op.(*v1.Operation_OperationPrune); ok { + if _, ok := op.Op.(*v1.Operation_OperationCheck); ok { lastRan = time.Unix(0, op.UnixTimeEndMs*int64(time.Millisecond)) return oplog.ErrStopIteration } @@ -70,7 +70,7 @@ func (t *CheckTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, error zap.L().Debug("last prune time", zap.Time("time", lastRan), zap.String("repo", t.RepoID())) - runAt, err := protoutil.ResolveSchedule(repo.PrunePolicy.GetSchedule(), lastRan) + runAt, err := protoutil.ResolveSchedule(repo.CheckPolicy.GetSchedule(), lastRan) if errors.Is(err, protoutil.ErrScheduleDisabled) { return NeverScheduledTask, nil } else if err != nil { diff --git a/webui/src/components/ScheduleFormItem.tsx b/webui/src/components/ScheduleFormItem.tsx index d461b57d..73f0466f 100644 --- a/webui/src/components/ScheduleFormItem.tsx +++ b/webui/src/components/ScheduleFormItem.tsx @@ -12,10 +12,38 @@ import { NamePath } from "antd/es/form/interface"; import React from "react"; import Cron from "react-js-cron"; -export const ScheduleFormItem = ({ name }: { name: string[] }) => { +interface ScheduleDefaults { + maxFrequencyDays: number; + maxFrequencyHours: number; + cron: string; +} + +export const ScheduleDefaultsInfrequent: ScheduleDefaults = { + maxFrequencyDays: 30, + maxFrequencyHours: 30 * 24, + // midnight on the first day of the month + cron: "0 0 1 * *", +}; + +export const ScheduleDefaultsDaily: ScheduleDefaults = { + maxFrequencyDays: 1, + maxFrequencyHours: 24, + // midnight every day + cron: "0 0 * * *", +}; + +export const ScheduleFormItem = ({ + name, + defaults, +}: { + name: string[]; + defaults?: ScheduleDefaults; +}) => { const form = Form.useFormInstance(); const retention = Form.useWatch(name, { form, preserve: true }) as any; + defaults = defaults || ScheduleDefaultsInfrequent; + const determineMode = () => { if (!retention) { return ""; @@ -37,7 +65,7 @@ export const ScheduleFormItem = ({ name }: { name: string[] }) => { elem = ( { elem = ( { elem = ( { onChange={(e) => { const selected = e.target.value; if (selected === "maxFrequencyDays") { - form.setFieldValue(name, { maxFrequencyDays: 1 }); + form.setFieldValue(name, { + maxFrequencyDays: defaults!.maxFrequencyDays, + }); } else if (selected === "maxFrequencyHours") { - form.setFieldValue(name, { maxFrequencyHours: 1 }); + form.setFieldValue(name, { + maxFrequencyHours: defaults!.maxFrequencyHours, + }); } else if (selected === "cron") { - form.setFieldValue(name, { cron: "0 * * * *" }); + form.setFieldValue(name, { cron: defaults!.cron }); } else { form.setFieldValue(name, { disabled: true }); } diff --git a/webui/src/views/AddPlanModal.tsx b/webui/src/views/AddPlanModal.tsx index 438fc183..e9d26266 100644 --- a/webui/src/views/AddPlanModal.tsx +++ b/webui/src/views/AddPlanModal.tsx @@ -30,7 +30,10 @@ import { import { ConfirmButton, SpinButton } from "../components/SpinButton"; import { useConfig } from "../components/ConfigProvider"; import { backrestService } from "../api"; -import { ScheduleFormItem } from "../components/ScheduleFormItem"; +import { + ScheduleDefaultsDaily, + ScheduleFormItem, +} from "../components/ScheduleFormItem"; export const AddPlanModal = ({ template }: { template: Plan | null }) => { const [confirmLoading, setConfirmLoading] = useState(false); @@ -399,7 +402,10 @@ export const AddPlanModal = ({ template }: { template: Plan | null }) => { {/* Plan.cron */} - + {/* Plan.backup_flags */} diff --git a/webui/src/views/AddRepoModal.tsx b/webui/src/views/AddRepoModal.tsx index 1ab6a169..4813b9f3 100644 --- a/webui/src/views/AddRepoModal.tsx +++ b/webui/src/views/AddRepoModal.tsx @@ -450,6 +450,42 @@ export const AddRepoModal = ({ template }: { template: Repo | null }) => { + {/* Repo.checkPolicy */} + + The schedule on which check operations are run for this + repository. Restic check operations verify the integrity of + your repository by scanning the on-disk structures that make + up your backup data. Check can optionally be configured to + re-read and re-hash data, this is slow and can be bandwidth + expensive but will catch any bitrot or silent corruption in + the storage medium. + + } + > + Check Policy + + } + > + + +
Read Pack Data %
+ + } + /> +
+ + + Date: Mon, 27 May 2024 01:13:58 -0700 Subject: [PATCH 05/14] only allow cancelling running operations --- webui/src/components/OperationRow.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/webui/src/components/OperationRow.tsx b/webui/src/components/OperationRow.tsx index 7f0d20a6..062bc157 100644 --- a/webui/src/components/OperationRow.tsx +++ b/webui/src/components/OperationRow.tsx @@ -117,10 +117,7 @@ export const OperationRow = ({ ); - if ( - operation.status === OperationStatus.STATUS_PENDING || - operation.status == OperationStatus.STATUS_INPROGRESS - ) { + if (operation.status == OperationStatus.STATUS_INPROGRESS) { title = ( <> {title} From ff91b4b6a188d0c64d696910bd00cb9f10641ef6 Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 01:22:42 -0700 Subject: [PATCH 06/14] improve restic package errors --- internal/orchestrator/tasks/task.go | 4 ++-- pkg/restic/error.go | 6 +++++- pkg/restic/restic.go | 17 ++++++++++------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/internal/orchestrator/tasks/task.go b/internal/orchestrator/tasks/task.go index 3388d658..2ed0f3e8 100644 --- a/internal/orchestrator/tasks/task.go +++ b/internal/orchestrator/tasks/task.go @@ -21,8 +21,8 @@ const ( TaskPriorityDefault = 1 << 1 // default priority TaskPriorityForget = 1 << 2 TaskPriorityIndexSnapshots = 1 << 3 - TaskPriorityPrune = 1 << 4 - TaskPriorityCheck = 1 << 4 + TaskPriorityCheck = 1 << 4 // check should always run after prune. + TaskPriorityPrune = 1 << 5 TaskPriorityInteractive = 1 << 6 // highest priority ) diff --git a/pkg/restic/error.go b/pkg/restic/error.go index b2866e25..410af4bb 100644 --- a/pkg/restic/error.go +++ b/pkg/restic/error.go @@ -60,12 +60,16 @@ func (e *ErrorWithOutput) Is(target error) bool { } // newErrorWithOutput creates a new error with the given output. -func newErrorWithOutput(err error, output string) *ErrorWithOutput { +func newErrorWithOutput(err error, output string) error { firstNewLine := strings.Index(output, "\n") if firstNewLine > 0 { output = output[:firstNewLine] } + if len(output) == 0 { + return err + } + return &ErrorWithOutput{ Err: err, Output: output, diff --git a/pkg/restic/restic.go b/pkg/restic/restic.go index 59f25e78..553e4739 100644 --- a/pkg/restic/restic.go +++ b/pkg/restic/restic.go @@ -124,7 +124,7 @@ func (r *Repo) init(ctx context.Context, opts ...GenericOption) error { if strings.Contains(output.String(), "config file already exists") || strings.Contains(output.String(), "already initialized") { r.initialized = errAlreadyInitialized } else { - r.initialized = newCmdError(ctx, cmd, fmt.Errorf("%w: %v", err, output.String())) + r.initialized = newCmdError(ctx, cmd, newCmdError(ctx, cmd, newErrorWithOutput(err, output.String()))) } } }) @@ -202,7 +202,7 @@ func (r *Repo) Snapshots(ctx context.Context, opts ...GenericOption) ([]*Snapsho var snapshots []*Snapshot if err := json.Unmarshal(output.Bytes(), &snapshots); err != nil { - return nil, newCmdError(ctx, cmd, fmt.Errorf("command output is not valid JSON: %w", err)) + return nil, newCmdError(ctx, cmd, newErrorWithOutput(fmt.Errorf("command output is not valid JSON: %w", err), output.String())) } for _, snapshot := range snapshots { @@ -226,7 +226,7 @@ func (r *Repo) Forget(ctx context.Context, policy *RetentionPolicy, opts ...Gene var result []ForgetResult if err := json.Unmarshal(output.Bytes(), &result); err != nil { - return nil, newCmdError(ctx, cmd, fmt.Errorf("command output is not valid JSON: %w", err)) + return nil, newCmdError(ctx, cmd, newErrorWithOutput(fmt.Errorf("command output is not valid JSON: %w", err), output.String())) } if len(result) != 1 { return nil, fmt.Errorf("expected 1 output from forget, got %v", len(result)) @@ -241,9 +241,11 @@ func (r *Repo) Forget(ctx context.Context, policy *RetentionPolicy, opts ...Gene func (r *Repo) ForgetSnapshot(ctx context.Context, snapshotId string, opts ...GenericOption) error { args := []string{"forget", "--json", snapshotId} + output := bytes.NewBuffer(nil) cmd := r.commandWithContext(ctx, args, opts...) + r.pipeCmdOutputToWriter(cmd, output) if err := cmd.Run(); err != nil { - return newCmdError(ctx, cmd, err) + return newCmdError(ctx, cmd, newErrorWithOutput(err, output.String())) } return nil @@ -331,16 +333,17 @@ func (r *Repo) ListDirectory(ctx context.Context, snapshot string, path string, snapshots, entries, err := readLs(output) if err != nil { - return nil, nil, newCmdError(ctx, cmd, err) + return nil, nil, newCmdError(ctx, cmd, newErrorWithOutput(err, output.String())) } return snapshots, entries, nil } func (r *Repo) Unlock(ctx context.Context, opts ...GenericOption) error { + output := bytes.NewBuffer(nil) cmd := r.commandWithContext(ctx, []string{"unlock"}, opts...) if err := cmd.Run(); err != nil { - return newCmdError(ctx, cmd, err) + return newCmdError(ctx, cmd, newErrorWithOutput(err, output.String())) } return nil } @@ -356,7 +359,7 @@ func (r *Repo) Stats(ctx context.Context, opts ...GenericOption) (*RepoStats, er var stats RepoStats if err := json.Unmarshal(output.Bytes(), &stats); err != nil { - return nil, newCmdError(ctx, cmd, fmt.Errorf("command output is not valid JSON: %w", err)) + return nil, newCmdError(ctx, cmd, newErrorWithOutput(fmt.Errorf("command output is not valid JSON: %w", err), output.String())) } return &stats, nil From 7df964b0039f4daebccecef742dacd2d82f93f1c Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 01:38:12 -0700 Subject: [PATCH 07/14] add hooks --- gen/go/v1/config.pb.go | 90 +++++++++++++++++------- internal/api/backresthandler.go | 1 + internal/hook/hookvars.go | 2 +- internal/orchestrator/tasks/taskcheck.go | 20 ++++++ internal/orchestrator/tasks/taskprune.go | 19 +++++ proto/v1/config.proto | 11 +++ webui/gen/ts/v1/config_pb.ts | 60 ++++++++++++++++ 7 files changed, 175 insertions(+), 28 deletions(-) diff --git a/gen/go/v1/config.pb.go b/gen/go/v1/config.pb.go index bc620be1..23876474 100644 --- a/gen/go/v1/config.pb.go +++ b/gen/go/v1/config.pb.go @@ -30,17 +30,33 @@ const ( Hook_CONDITION_SNAPSHOT_END Hook_Condition = 3 // backup completed (success or fail). Hook_CONDITION_SNAPSHOT_ERROR Hook_Condition = 4 // snapshot failed. Hook_CONDITION_SNAPSHOT_WARNING Hook_Condition = 5 // snapshot completed with warnings. + Hook_CONDITION_SNAPSHOT_SUCCESS Hook_Condition = 6 // snapshot succeeded. + // prune conditions + Hook_CONDITION_PRUNE_START Hook_Condition = 100 // prune started. + Hook_CONDITION_PRUNE_ERROR Hook_Condition = 101 // prune failed. + Hook_CONDITION_PRUNE_SUCCESS Hook_Condition = 102 // prune succeeded. + // check conditions + Hook_CONDITION_CHECK_START Hook_Condition = 200 // check started. + Hook_CONDITION_CHECK_ERROR Hook_Condition = 201 // check failed. + Hook_CONDITION_CHECK_SUCCESS Hook_Condition = 202 // check succeeded. ) // Enum value maps for Hook_Condition. var ( Hook_Condition_name = map[int32]string{ - 0: "CONDITION_UNKNOWN", - 1: "CONDITION_ANY_ERROR", - 2: "CONDITION_SNAPSHOT_START", - 3: "CONDITION_SNAPSHOT_END", - 4: "CONDITION_SNAPSHOT_ERROR", - 5: "CONDITION_SNAPSHOT_WARNING", + 0: "CONDITION_UNKNOWN", + 1: "CONDITION_ANY_ERROR", + 2: "CONDITION_SNAPSHOT_START", + 3: "CONDITION_SNAPSHOT_END", + 4: "CONDITION_SNAPSHOT_ERROR", + 5: "CONDITION_SNAPSHOT_WARNING", + 6: "CONDITION_SNAPSHOT_SUCCESS", + 100: "CONDITION_PRUNE_START", + 101: "CONDITION_PRUNE_ERROR", + 102: "CONDITION_PRUNE_SUCCESS", + 200: "CONDITION_CHECK_START", + 201: "CONDITION_CHECK_ERROR", + 202: "CONDITION_CHECK_SUCCESS", } Hook_Condition_value = map[string]int32{ "CONDITION_UNKNOWN": 0, @@ -49,6 +65,13 @@ var ( "CONDITION_SNAPSHOT_END": 3, "CONDITION_SNAPSHOT_ERROR": 4, "CONDITION_SNAPSHOT_WARNING": 5, + "CONDITION_SNAPSHOT_SUCCESS": 6, + "CONDITION_PRUNE_START": 100, + "CONDITION_PRUNE_ERROR": 101, + "CONDITION_PRUNE_SUCCESS": 102, + "CONDITION_CHECK_START": 200, + "CONDITION_CHECK_ERROR": 201, + "CONDITION_CHECK_SUCCESS": 202, } ) @@ -1905,7 +1928,7 @@ var file_v1_config_proto_rawDesc = []byte{ 0x12, 0x2e, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x11, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x6f, 0x75, 0x72, 0x73, - 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x22, 0xec, 0x09, 0x0a, + 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x22, 0xb5, 0x0b, 0x0a, 0x04, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x32, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, @@ -1968,7 +1991,7 @@ var file_v1_config_proto_rawDesc = []byte{ 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x68, 0x6f, 0x75, 0x74, 0x72, 0x72, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x74, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x74, 0x65, 0x22, 0xfc, 0x02, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4e, 0x59, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, @@ -1979,25 +2002,38 @@ var file_v1_config_proto_rawDesc = []byte{ 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x57, - 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x22, 0x47, 0x0a, 0x07, 0x4f, 0x6e, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, - 0x0e, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, - 0x02, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x42, 0x0a, 0x04, 0x41, - 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, - 0x1e, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, - 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, - 0x51, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x62, 0x63, 0x72, 0x79, 0x70, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x42, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 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, + 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4e, 0x44, + 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x53, + 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x44, + 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x55, 0x4e, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, + 0x54, 0x10, 0x64, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x50, 0x52, 0x55, 0x4e, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x65, 0x12, 0x1b, + 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x55, 0x4e, + 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x66, 0x12, 0x1a, 0x0a, 0x15, 0x43, + 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x53, + 0x54, 0x41, 0x52, 0x54, 0x10, 0xc8, 0x01, 0x12, 0x1a, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x44, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x10, 0xc9, 0x01, 0x12, 0x1c, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0xca, + 0x01, 0x22, 0x47, 0x0a, 0x07, 0x4f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x13, 0x0a, 0x0f, + 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, + 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x41, + 0x4e, 0x43, 0x45, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x02, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x42, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x51, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x5f, 0x62, 0x63, 0x72, 0x79, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x0e, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, + 0x0a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 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 ( diff --git a/internal/api/backresthandler.go b/internal/api/backresthandler.go index 3b9f7e9c..d8a4e38f 100644 --- a/internal/api/backresthandler.go +++ b/internal/api/backresthandler.go @@ -354,6 +354,7 @@ func (s BackrestHandler) DoRepoTask(ctx context.Context, req *connect.Request[v1 if err := repo.Unlock(ctx); err != nil { return nil, fmt.Errorf("failed to unlock repo %q: %w", req.Msg.RepoId, err) } + return connect.NewResponse(&emptypb.Empty{}), nil default: return nil, fmt.Errorf("unknown task %v", req.Msg.Task.String()) } diff --git a/internal/hook/hookvars.go b/internal/hook/hookvars.go index 07fb161c..08b2be93 100644 --- a/internal/hook/hookvars.go +++ b/internal/hook/hookvars.go @@ -47,7 +47,7 @@ func (v HookVars) FormatTime(t time.Time) string { } func (v HookVars) FormatDuration(d time.Duration) string { - return d.String() + return d.Truncate(time.Millisecond).String() } func (v HookVars) number(n any) int { diff --git a/internal/orchestrator/tasks/taskcheck.go b/internal/orchestrator/tasks/taskcheck.go index dea47d39..2a58f76e 100644 --- a/internal/orchestrator/tasks/taskcheck.go +++ b/internal/orchestrator/tasks/taskcheck.go @@ -94,6 +94,19 @@ func (t *CheckTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner return fmt.Errorf("couldn't get repo %q: %w", t.RepoID(), err) } + if err := runner.ExecuteHooks([]v1.Hook_Condition{ + v1.Hook_CONDITION_CHECK_START, + }, hook.HookVars{}); err != nil { + // TODO: generalize this logic + var cancelErr *hook.HookErrorRequestCancel + if errors.As(err, &cancelErr) { + op.Status = v1.OperationStatus_STATUS_USER_CANCELLED // user visible cancelled status + op.DisplayMessage = err.Error() + return nil + } + return fmt.Errorf("execute prune start hooks: %w", err) + } + err = repo.UnlockIfAutoEnabled(ctx) if err != nil { return fmt.Errorf("auto unlock repo %q: %w", t.RepoID(), err) @@ -137,6 +150,7 @@ func (t *CheckTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner cancel() runner.ExecuteHooks([]v1.Hook_Condition{ + v1.Hook_CONDITION_CHECK_ERROR, v1.Hook_CONDITION_ANY_ERROR, }, hook.HookVars{ Error: err.Error(), @@ -154,5 +168,11 @@ func (t *CheckTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner zap.L().Error("schedule stats task", zap.Error(err)) } + if err := runner.ExecuteHooks([]v1.Hook_Condition{ + v1.Hook_CONDITION_CHECK_SUCCESS, + }, hook.HookVars{}); err != nil { + return fmt.Errorf("execute prune success hooks: %w", err) + } + return nil } diff --git a/internal/orchestrator/tasks/taskprune.go b/internal/orchestrator/tasks/taskprune.go index 0fe2a7fe..572990d8 100644 --- a/internal/orchestrator/tasks/taskprune.go +++ b/internal/orchestrator/tasks/taskprune.go @@ -94,6 +94,19 @@ func (t *PruneTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner return fmt.Errorf("couldn't get repo %q: %w", t.RepoID(), err) } + if err := runner.ExecuteHooks([]v1.Hook_Condition{ + v1.Hook_CONDITION_PRUNE_START, + }, hook.HookVars{}); err != nil { + // TODO: generalize this logic + var cancelErr *hook.HookErrorRequestCancel + if errors.As(err, &cancelErr) { + op.Status = v1.OperationStatus_STATUS_USER_CANCELLED // user visible cancelled status + op.DisplayMessage = err.Error() + return nil + } + return fmt.Errorf("execute prune start hooks: %w", err) + } + err = repo.UnlockIfAutoEnabled(ctx) if err != nil { return fmt.Errorf("auto unlock repo %q: %w", t.RepoID(), err) @@ -154,5 +167,11 @@ func (t *PruneTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner zap.L().Error("schedule stats task", zap.Error(err)) } + if err := runner.ExecuteHooks([]v1.Hook_Condition{ + v1.Hook_CONDITION_PRUNE_SUCCESS, + }, hook.HookVars{}); err != nil { + return fmt.Errorf("execute prune end hooks: %w", err) + } + return nil } diff --git a/proto/v1/config.proto b/proto/v1/config.proto index f9744671..be82417f 100644 --- a/proto/v1/config.proto +++ b/proto/v1/config.proto @@ -116,6 +116,17 @@ message Hook { CONDITION_SNAPSHOT_END = 3; // backup completed (success or fail). CONDITION_SNAPSHOT_ERROR = 4; // snapshot failed. CONDITION_SNAPSHOT_WARNING = 5; // snapshot completed with warnings. + CONDITION_SNAPSHOT_SUCCESS = 6; // snapshot succeeded. + + // prune conditions + CONDITION_PRUNE_START = 100; // prune started. + CONDITION_PRUNE_ERROR = 101; // prune failed. + CONDITION_PRUNE_SUCCESS = 102; // prune succeeded. + + // check conditions + CONDITION_CHECK_START = 200; // check started. + CONDITION_CHECK_ERROR = 201; // check failed. + CONDITION_CHECK_SUCCESS = 202; // check succeeded. } enum OnError { diff --git a/webui/gen/ts/v1/config_pb.ts b/webui/gen/ts/v1/config_pb.ts index 1e7ead03..9c1dd8a7 100644 --- a/webui/gen/ts/v1/config_pb.ts +++ b/webui/gen/ts/v1/config_pb.ts @@ -901,6 +901,59 @@ export enum Hook_Condition { * @generated from enum value: CONDITION_SNAPSHOT_WARNING = 5; */ SNAPSHOT_WARNING = 5, + + /** + * snapshot succeeded. + * + * @generated from enum value: CONDITION_SNAPSHOT_SUCCESS = 6; + */ + SNAPSHOT_SUCCESS = 6, + + /** + * prune conditions + * + * prune started. + * + * @generated from enum value: CONDITION_PRUNE_START = 100; + */ + PRUNE_START = 100, + + /** + * prune failed. + * + * @generated from enum value: CONDITION_PRUNE_ERROR = 101; + */ + PRUNE_ERROR = 101, + + /** + * prune succeeded. + * + * @generated from enum value: CONDITION_PRUNE_SUCCESS = 102; + */ + PRUNE_SUCCESS = 102, + + /** + * check conditions + * + * check started. + * + * @generated from enum value: CONDITION_CHECK_START = 200; + */ + CHECK_START = 200, + + /** + * check failed. + * + * @generated from enum value: CONDITION_CHECK_ERROR = 201; + */ + CHECK_ERROR = 201, + + /** + * check succeeded. + * + * @generated from enum value: CONDITION_CHECK_SUCCESS = 202; + */ + CHECK_SUCCESS = 202, } // Retrieve enum metadata with: proto3.getEnumType(Hook_Condition) proto3.util.setEnumType(Hook_Condition, "v1.Hook.Condition", [ @@ -910,6 +963,13 @@ proto3.util.setEnumType(Hook_Condition, "v1.Hook.Condition", [ { no: 3, name: "CONDITION_SNAPSHOT_END" }, { no: 4, name: "CONDITION_SNAPSHOT_ERROR" }, { no: 5, name: "CONDITION_SNAPSHOT_WARNING" }, + { no: 6, name: "CONDITION_SNAPSHOT_SUCCESS" }, + { no: 100, name: "CONDITION_PRUNE_START" }, + { no: 101, name: "CONDITION_PRUNE_ERROR" }, + { no: 102, name: "CONDITION_PRUNE_SUCCESS" }, + { no: 200, name: "CONDITION_CHECK_START" }, + { no: 201, name: "CONDITION_CHECK_ERROR" }, + { no: 202, name: "CONDITION_CHECK_SUCCESS" }, ]); /** From e411c1c732f213774dcd1b0cdcb1a6da28f99984 Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 01:43:01 -0700 Subject: [PATCH 08/14] update docs --- docs/content/2.docs/2.hooks.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/content/2.docs/2.hooks.md b/docs/content/2.docs/2.hooks.md index 7e87d4c3..813eadda 100644 --- a/docs/content/2.docs/2.hooks.md +++ b/docs/content/2.docs/2.hooks.md @@ -7,10 +7,18 @@ Backrest supports hooks in response to operation lifecycle events e.g. in respon Available event types are - `CONDITION_ANY_ERROR` any operation has failed. -- `CONDITION_SNAPSHOT_START` the start of a backup operation (e.g. corresponds to a call to `restic backup`) +- `CONDITION_SNAPSHOT_START` the start of a backup operation (e.g. corresponds to a call to `restic backup`, supports error behavior) - `CONDITION_SNAPSHOT_END` the end of a backup operation (e.g. corresponds to `restic backup` completing). Note that Snapshot End will still be called if a backup failed. - `CONDITION_SNAPSHOT_ERROR` an error occurred during a backup operation (e.g. `restic backup` returned a non-zero exit code OR invalid output). - `CONDITION_SNAPSHOT_WARNING` a warning occurred during a backup operation (e.g. a file was partially read). +- Prune hooks: + - `CONDITION_PRUNE_START` the start of a prune operation (e.g. corresponds to a call to `restic prune`, supports error behavior) + - `CONDITION_PRUNE_SUCCESS` the end of a prune operation e.g. `restic prune` completed successfully. + - `CONDITION_PRUNE_ERROR` an error occurred during a prune operation (e.g. `restic prune` returned a non-zero exit code). +- Check hooks: + - `CONDITION_CHECK_START` the start of a check operation (e.g. corresponds to a call to `restic check`, supports error behavior) + - `CONDITION_CHECK_SUCCESS` the end of a check operation e.g. `restic check` completed successfully. + - `CONDITION_CHECK_ERROR` an error occurred during a check operation (e.g. `restic check` returned a non-zero exit code). ## Notification Services @@ -22,6 +30,17 @@ Available event types are | Shoutrrr | https://containrrr.dev/shoutrrr/v0.8/ | | Command | See command cookbook | + +## Error Behavior + +Some hooks can specify an error behavior (today this is only command hooks). This determines what happens when the hook generates an error. + +The available error behaviors are: + +- `ON_ERROR_IGNORE` - ignore the error and continue running hooks and the operation. +- `ON_ERROR_CANCEL` - cancel the operation and do not run any further hooks. The operation is marked as cancelled. +- `ON_ERROR_FATAL` - cancel the operation and do not run any further hooks. The operation is marked as failed and error handler hooks may be triggered. + ## Using Templates Most hooks will generate either a notification or execute a script. The script / notification is typically formatted as a Go template. The https://pkg.go.dev/text/template docs provide a very technical overview of Go template capabilities. See below for info about the available variables and for some examples. From 5a52c30c5e4a6e38490025824de6b6ea510be617 Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 02:05:41 -0700 Subject: [PATCH 09/14] misc fixes and improvements --- internal/hook/hook.go | 5 +++++ internal/orchestrator/taskrunnerimpl.go | 6 +----- internal/orchestrator/tasks/taskcheck.go | 5 +++-- internal/orchestrator/tasks/taskprune.go | 3 ++- webui/src/components/Alerts.tsx | 16 ++++++++++++++++ webui/src/views/AddPlanModal.tsx | 10 +++++++--- webui/src/views/AddRepoModal.tsx | 6 +++--- 7 files changed, 37 insertions(+), 14 deletions(-) diff --git a/internal/hook/hook.go b/internal/hook/hook.go index 587ae3bb..a504c377 100644 --- a/internal/hook/hook.go +++ b/internal/hook/hook.go @@ -38,6 +38,11 @@ func NewHookExecutor(config *v1.Config, oplog *oplog.OpLog, bigOutputStore *rota // ExecuteHooks schedules tasks for the hooks subscribed to the given event. The vars map is used to substitute variables // Hooks are pulled both from the provided plan and from the repo config. func (e *HookExecutor) ExecuteHooks(flowID int64, repo *v1.Repo, plan *v1.Plan, events []v1.Hook_Condition, vars HookVars) error { + planId := plan.GetId() + if planId == "" { + planId = "_system_" // TODO: clean this up when refactoring hook execution + } + operationBase := v1.Operation{ Status: v1.OperationStatus_STATUS_INPROGRESS, PlanId: plan.GetId(), diff --git a/internal/orchestrator/taskrunnerimpl.go b/internal/orchestrator/taskrunnerimpl.go index cc68464e..ece13ced 100644 --- a/internal/orchestrator/taskrunnerimpl.go +++ b/internal/orchestrator/taskrunnerimpl.go @@ -84,11 +84,7 @@ func (t *taskRunnerImpl) ExecuteHooks(events []v1.Hook_Condition, vars hook.Hook } } if planID != "" { - var err error - plan, err = t.FindPlan() - if err != nil { - return err - } + plan, _ = t.FindPlan() } var flowID int64 if t.op != nil { diff --git a/internal/orchestrator/tasks/taskcheck.go b/internal/orchestrator/tasks/taskcheck.go index 2a58f76e..eef6058a 100644 --- a/internal/orchestrator/tasks/taskcheck.go +++ b/internal/orchestrator/tasks/taskcheck.go @@ -98,13 +98,14 @@ func (t *CheckTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner v1.Hook_CONDITION_CHECK_START, }, hook.HookVars{}); err != nil { // TODO: generalize this logic + op.DisplayMessage = err.Error() var cancelErr *hook.HookErrorRequestCancel if errors.As(err, &cancelErr) { op.Status = v1.OperationStatus_STATUS_USER_CANCELLED // user visible cancelled status - op.DisplayMessage = err.Error() return nil } - return fmt.Errorf("execute prune start hooks: %w", err) + op.Status = v1.OperationStatus_STATUS_ERROR + return fmt.Errorf("execute check start hooks: %w", err) } err = repo.UnlockIfAutoEnabled(ctx) diff --git a/internal/orchestrator/tasks/taskprune.go b/internal/orchestrator/tasks/taskprune.go index 572990d8..0dbe2004 100644 --- a/internal/orchestrator/tasks/taskprune.go +++ b/internal/orchestrator/tasks/taskprune.go @@ -97,13 +97,14 @@ func (t *PruneTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner if err := runner.ExecuteHooks([]v1.Hook_Condition{ v1.Hook_CONDITION_PRUNE_START, }, hook.HookVars{}); err != nil { + op.DisplayMessage = err.Error() // TODO: generalize this logic var cancelErr *hook.HookErrorRequestCancel if errors.As(err, &cancelErr) { op.Status = v1.OperationStatus_STATUS_USER_CANCELLED // user visible cancelled status - op.DisplayMessage = err.Error() return nil } + op.Status = v1.OperationStatus_STATUS_ERROR return fmt.Errorf("execute prune start hooks: %w", err) } diff --git a/webui/src/components/Alerts.tsx b/webui/src/components/Alerts.tsx index 2ed8fc50..36960bfc 100644 --- a/webui/src/components/Alerts.tsx +++ b/webui/src/components/Alerts.tsx @@ -25,3 +25,19 @@ export const AlertContextProvider = ({ export const useAlertApi = () => { return useContext(MessageContext); }; + +export const formatErrorAlert = (error: any, prefix?: string) => { + prefix = prefix ? prefix.trim() + " " : "Error: "; + const contents = (error.message || "" + error) as string; + if (contents.includes("\n")) { + return ( + <> + {prefix} +
+          {contents}
+        
+ + ); + } + return `${prefix}: ${contents}`; +}; diff --git a/webui/src/views/AddPlanModal.tsx b/webui/src/views/AddPlanModal.tsx index e9d26266..88460a52 100644 --- a/webui/src/views/AddPlanModal.tsx +++ b/webui/src/views/AddPlanModal.tsx @@ -20,7 +20,11 @@ import { useShowModal } from "../components/ModalManager"; import { Plan, RetentionPolicy } from "../../gen/ts/v1/config_pb"; import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"; import { URIAutocomplete } from "../components/URIAutocomplete"; -import { useAlertApi } from "../components/Alerts"; +import { + formatError, + formatErrorAlert, + useAlertApi, +} from "../components/Alerts"; import { Cron } from "react-js-cron"; import { namePattern, validateForm } from "../lib/formutil"; import { @@ -75,7 +79,7 @@ export const AddPlanModal = ({ template }: { template: Plan | null }) => { 30 ); } catch (e: any) { - alertsApi.error("Operation failed: " + e.message, 15); + alertsApi.error(formatErrorAlert(e, "Destroy error:"), 15); } finally { setConfirmLoading(false); } @@ -111,7 +115,7 @@ export const AddPlanModal = ({ template }: { template: Plan | null }) => { setConfig(await backrestService.setConfig(configCopy)); showModal(null); } catch (e: any) { - alertsApi.error("Operation failed: " + e.message, 15); + alertsApi.error(formatErrorAlert(e, "Operation error: "), 15); console.error(e); } finally { setConfirmLoading(false); diff --git a/webui/src/views/AddRepoModal.tsx b/webui/src/views/AddRepoModal.tsx index 4813b9f3..083b41bd 100644 --- a/webui/src/views/AddRepoModal.tsx +++ b/webui/src/views/AddRepoModal.tsx @@ -19,7 +19,7 @@ import { useShowModal } from "../components/ModalManager"; import { Hook, Repo } from "../../gen/ts/v1/config_pb"; import { URIAutocomplete } from "../components/URIAutocomplete"; import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"; -import { useAlertApi } from "../components/Alerts"; +import { formatErrorAlert, useAlertApi } from "../components/Alerts"; import { namePattern, validateForm } from "../lib/formutil"; import { backrestService } from "../api"; import { @@ -81,7 +81,7 @@ export const AddRepoModal = ({ template }: { template: Repo | null }) => { template.uri ); } catch (e: any) { - alertsApi.error("Operation failed: " + e.message, 15); + alertsApi.error(formatErrorAlert(e, "Operation error: "), 15); } finally { setConfirmLoading(false); } @@ -118,7 +118,7 @@ export const AddRepoModal = ({ template }: { template: Repo | null }) => { alertsApi.success("Added repo " + repo.uri); } } catch (e: any) { - alertsApi.error("Operation failed: " + e.message, 15); + alertsApi.error(formatErrorAlert(e, "Operation error: "), 15); } finally { setConfirmLoading(false); } From e3e26913136e94fbcba77d27a7fad19583d1e47c Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 02:07:13 -0700 Subject: [PATCH 10/14] improve error formatting --- webui/src/views/RepoView.tsx | 10 +++++----- webui/src/views/SettingsModal.tsx | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/webui/src/views/RepoView.tsx b/webui/src/views/RepoView.tsx index f42e4ce9..ebdf5681 100644 --- a/webui/src/views/RepoView.tsx +++ b/webui/src/views/RepoView.tsx @@ -15,7 +15,7 @@ import { backrestService } from "../api"; import { StringValue } from "@bufbuild/protobuf"; import { SpinButton } from "../components/SpinButton"; import { useConfig } from "../components/ConfigProvider"; -import { useAlertApi } from "../components/Alerts"; +import { formatErrorAlert, useAlertApi } from "../components/Alerts"; import { useShowModal } from "../components/ModalManager"; const StatsPanel = React.lazy(() => import("../components/StatsPanel")); @@ -35,7 +35,7 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => { }) ); } catch (e: any) { - alertsApi.error("Failed to index snapshots: " + e.message); + alertsApi.error(formatErrorAlert(e, "Failed to index snapshots: ")); } }; @@ -48,7 +48,7 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => { }) ); } catch (e: any) { - alertsApi.error("Failed to compute stats: " + e.message); + alertsApi.error(formatErrorAlert(e, "Failed to compute stats: ")); } }; @@ -61,7 +61,7 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => { }) ); } catch (e: any) { - alertsApi.error("Failed to prune: " + e.message); + alertsApi.error(formatErrorAlert(e, "Failed to prune: ")); } }; @@ -74,7 +74,7 @@ export const RepoView = ({ repo }: React.PropsWithChildren<{ repo: Repo }>) => { }) ); } catch (e: any) { - alertsApi.error("Failed to check: " + e.message); + alertsApi.error(formatErrorAlert(e, "Failed to check: ")); } }; diff --git a/webui/src/views/SettingsModal.tsx b/webui/src/views/SettingsModal.tsx index 859e6c0c..dfc20549 100644 --- a/webui/src/views/SettingsModal.tsx +++ b/webui/src/views/SettingsModal.tsx @@ -18,7 +18,7 @@ import React, { useEffect, useState } from "react"; import { useShowModal } from "../components/ModalManager"; import { Auth, Config, User } from "../../gen/ts/v1/config_pb"; import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"; -import { useAlertApi } from "../components/Alerts"; +import { formatErrorAlert, useAlertApi } from "../components/Alerts"; import { namePattern, validateForm } from "../lib/formutil"; import { useConfig } from "../components/ConfigProvider"; import { authenticationService, backrestService } from "../api"; @@ -80,7 +80,7 @@ export const SettingsModal = () => { window.location.reload(); }, 500); } catch (e: any) { - alertsApi.error("Operation failed: " + e.message, 15); + alertsApi.error(formatErrorAlert(e, "Operation error: "), 15); console.error(e); } }; From d076348d9bec59dc5a4160cfe03fce756e1c9cfe Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 02:22:33 -0700 Subject: [PATCH 11/14] fix lag refreshing operation list / operation tree --- webui/src/components/OperationList.tsx | 18 +++++++++++------- webui/src/components/OperationTree.tsx | 18 +++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/webui/src/components/OperationList.tsx b/webui/src/components/OperationList.tsx index d526bf58..9b3489b2 100644 --- a/webui/src/components/OperationList.tsx +++ b/webui/src/components/OperationList.tsx @@ -62,13 +62,17 @@ export const OperationList = ({ subscribeToOperations(lis); backupCollector.subscribe( - _.debounce(() => { - let backups = backupCollector.getAll(); - backups.sort((a, b) => { - return b.startTimeMs - a.startTimeMs; - }); - setBackups(backups); - }, 50) + _.debounce( + () => { + let backups = backupCollector.getAll(); + backups.sort((a, b) => { + return b.startTimeMs - a.startTimeMs; + }); + setBackups(backups); + }, + 100, + { leading: true, trailing: true } + ) ); getOperations(req) diff --git a/webui/src/components/OperationTree.tsx b/webui/src/components/OperationTree.tsx index 08b6f3d9..1ac5074c 100644 --- a/webui/src/components/OperationTree.tsx +++ b/webui/src/components/OperationTree.tsx @@ -79,13 +79,17 @@ export const OperationTree = ({ subscribeToOperations(lis); backupCollector.subscribe( - _.debounce(() => { - let backups = backupCollector.getAll(); - backups.sort((a, b) => { - return b.startTimeMs - a.startTimeMs; - }); - setBackups(backups); - }, 50) + _.debounce( + () => { + let backups = backupCollector.getAll(); + backups.sort((a, b) => { + return b.startTimeMs - a.startTimeMs; + }); + setBackups(backups); + }, + 100, + { leading: true, trailing: true } + ) ); getOperations(req) From f347bf0736958906781d8c5a33857dc5976c1bfb Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 02:25:19 -0700 Subject: [PATCH 12/14] skip check or prune if no backups have run yet --- internal/orchestrator/tasks/taskcheck.go | 8 +++++++- internal/orchestrator/tasks/taskprune.go | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/internal/orchestrator/tasks/taskcheck.go b/internal/orchestrator/tasks/taskcheck.go index eef6058a..583eb8b8 100644 --- a/internal/orchestrator/tasks/taskcheck.go +++ b/internal/orchestrator/tasks/taskcheck.go @@ -58,14 +58,20 @@ func (t *CheckTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, error } var lastRan time.Time + var foundBackup bool if err := runner.OpLog().ForEach(oplog.Query{RepoId: t.RepoID()}, indexutil.Reversed(indexutil.CollectAll()), func(op *v1.Operation) error { if _, ok := op.Op.(*v1.Operation_OperationCheck); ok { lastRan = time.Unix(0, op.UnixTimeEndMs*int64(time.Millisecond)) return oplog.ErrStopIteration } + if _, ok := op.Op.(*v1.Operation_OperationBackup); ok { + foundBackup = true + } return nil }); err != nil { - return NeverScheduledTask, fmt.Errorf("finding last backup run time: %w", err) + return NeverScheduledTask, fmt.Errorf("finding last check run time: %w", err) + } else if !foundBackup { + return NeverScheduledTask, nil } zap.L().Debug("last prune time", zap.Time("time", lastRan), zap.String("repo", t.RepoID())) diff --git a/internal/orchestrator/tasks/taskprune.go b/internal/orchestrator/tasks/taskprune.go index 0dbe2004..dcbcacd1 100644 --- a/internal/orchestrator/tasks/taskprune.go +++ b/internal/orchestrator/tasks/taskprune.go @@ -58,14 +58,20 @@ func (t *PruneTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, error } var lastRan time.Time + var foundBackup bool if err := runner.OpLog().ForEach(oplog.Query{RepoId: t.RepoID()}, indexutil.Reversed(indexutil.CollectAll()), func(op *v1.Operation) error { if _, ok := op.Op.(*v1.Operation_OperationPrune); ok { lastRan = time.Unix(0, op.UnixTimeEndMs*int64(time.Millisecond)) return oplog.ErrStopIteration } + if _, ok := op.Op.(*v1.Operation_OperationBackup); ok { + foundBackup = true + } return nil }); err != nil { - return NeverScheduledTask, fmt.Errorf("finding last backup run time: %w", err) + return NeverScheduledTask, fmt.Errorf("finding last prune run time: %w", err) + } else if !foundBackup { + return NeverScheduledTask, nil } zap.L().Debug("last prune time", zap.Time("time", lastRan), zap.String("repo", t.RepoID())) From c4a1e6b7c42d0556c28622cd8e5eea70d6061e3e Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 02:32:40 -0700 Subject: [PATCH 13/14] fix tests --- .github/workflows/test.yml | 11 ++++------- internal/api/backresthandler_test.go | 6 ++---- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 18587a72..ccb08f32 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,13 +27,10 @@ jobs: with: go-version: "1.21" - - name: Setup NodeJS - uses: actions/setup-node@v4 - with: - node-version: "20" - - - name: Generate - run: go generate ./... + - name: Create Fake WebUI Sources + run: | + mkdir -p webui/dist + touch webui/dist/index.html.gz - name: Build run: go build ./... diff --git a/internal/api/backresthandler_test.go b/internal/api/backresthandler_test.go index 92390639..b1c7e969 100644 --- a/internal/api/backresthandler_test.go +++ b/internal/api/backresthandler_test.go @@ -179,8 +179,6 @@ func TestBackup(t *testing.T) { } func TestMultipleBackup(t *testing.T) { - t.Parallel() - sut := createSystemUnderTest(t, &config.MemoryStore{ Config: &v1.Config{ Modno: 1234, @@ -218,7 +216,7 @@ func TestMultipleBackup(t *testing.T) { sut.orch.Run(ctx) }() - for i := 0; i < 2; i++ { + for i := 0; i < 3; i++ { _, err := sut.handler.Backup(context.Background(), connect.NewRequest(&types.StringValue{Value: "test"})) if err != nil { t.Fatalf("Backup() error = %v", err) @@ -230,7 +228,7 @@ func TestMultipleBackup(t *testing.T) { operations := getOperations(t, sut.oplog) if index := slices.IndexFunc(operations, func(op *v1.Operation) bool { forget, ok := op.GetOp().(*v1.Operation_OperationForget) - return op.Status == v1.OperationStatus_STATUS_SUCCESS && ok && len(forget.OperationForget.Forget) == 1 + return op.Status == v1.OperationStatus_STATUS_SUCCESS && ok && len(forget.OperationForget.Forget) > 0 }); index != -1 { return nil } From 5a7607afd86b5c0e47132a1b0b0219658982a375 Mon Sep 17 00:00:00 2001 From: garethgeorge Date: Mon, 27 May 2024 02:52:08 -0700 Subject: [PATCH 14/14] hook bug fix --- internal/api/backresthandler_test.go | 2 +- internal/hook/hook.go | 2 +- internal/orchestrator/tasks/taskcollectgarbage.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/api/backresthandler_test.go b/internal/api/backresthandler_test.go index b1c7e969..dbce941d 100644 --- a/internal/api/backresthandler_test.go +++ b/internal/api/backresthandler_test.go @@ -603,7 +603,7 @@ func retry(t *testing.T, times int, backoff time.Duration, f func() error) error } func getOperations(t *testing.T, oplog *oplog.OpLog) []*v1.Operation { - t.Logf("Reading oplog") + t.Logf("Reading oplog at time %v", time.Now()) operations := []*v1.Operation{} if err := oplog.ForAll(func(op *v1.Operation) error { operations = append(operations, op) diff --git a/internal/hook/hook.go b/internal/hook/hook.go index a504c377..2bf73411 100644 --- a/internal/hook/hook.go +++ b/internal/hook/hook.go @@ -45,7 +45,7 @@ func (e *HookExecutor) ExecuteHooks(flowID int64, repo *v1.Repo, plan *v1.Plan, operationBase := v1.Operation{ Status: v1.OperationStatus_STATUS_INPROGRESS, - PlanId: plan.GetId(), + PlanId: planId, RepoId: repo.GetId(), InstanceId: e.config.Instance, FlowId: flowID, diff --git a/internal/orchestrator/tasks/taskcollectgarbage.go b/internal/orchestrator/tasks/taskcollectgarbage.go index 07fb4872..573bf9ef 100644 --- a/internal/orchestrator/tasks/taskcollectgarbage.go +++ b/internal/orchestrator/tasks/taskcollectgarbage.go @@ -11,7 +11,7 @@ import ( ) const ( - gcStartupDelay = 5 * time.Second + gcStartupDelay = 60 * time.Second gcInterval = 24 * time.Hour // keep operations that are eligible for gc for 30 days OR up to a limit of 100 for any one plan. // an operation is eligible for gc if: