diff --git a/gen/go/v1/config.pb.go b/gen/go/v1/config.pb.go index 2387647..50278e6 100644 --- a/gen/go/v1/config.pb.go +++ b/gen/go/v1/config.pb.go @@ -21,6 +21,107 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type CommandPrefix_IONiceLevel int32 + +const ( + CommandPrefix_IO_DEFAULT CommandPrefix_IONiceLevel = 0 + CommandPrefix_IO_BEST_EFFORT_LOW CommandPrefix_IONiceLevel = 1 + CommandPrefix_IO_BEST_EFFORT_HIGH CommandPrefix_IONiceLevel = 2 + CommandPrefix_IO_IDLE CommandPrefix_IONiceLevel = 3 +) + +// Enum value maps for CommandPrefix_IONiceLevel. +var ( + CommandPrefix_IONiceLevel_name = map[int32]string{ + 0: "IO_DEFAULT", + 1: "IO_BEST_EFFORT_LOW", + 2: "IO_BEST_EFFORT_HIGH", + 3: "IO_IDLE", + } + CommandPrefix_IONiceLevel_value = map[string]int32{ + "IO_DEFAULT": 0, + "IO_BEST_EFFORT_LOW": 1, + "IO_BEST_EFFORT_HIGH": 2, + "IO_IDLE": 3, + } +) + +func (x CommandPrefix_IONiceLevel) Enum() *CommandPrefix_IONiceLevel { + p := new(CommandPrefix_IONiceLevel) + *p = x + return p +} + +func (x CommandPrefix_IONiceLevel) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CommandPrefix_IONiceLevel) Descriptor() protoreflect.EnumDescriptor { + return file_v1_config_proto_enumTypes[0].Descriptor() +} + +func (CommandPrefix_IONiceLevel) Type() protoreflect.EnumType { + return &file_v1_config_proto_enumTypes[0] +} + +func (x CommandPrefix_IONiceLevel) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CommandPrefix_IONiceLevel.Descriptor instead. +func (CommandPrefix_IONiceLevel) EnumDescriptor() ([]byte, []int) { + return file_v1_config_proto_rawDescGZIP(), []int{4, 0} +} + +type CommandPrefix_CPUNiceLevel int32 + +const ( + CommandPrefix_CPU_DEFAULT CommandPrefix_CPUNiceLevel = 0 + CommandPrefix_CPU_HIGH CommandPrefix_CPUNiceLevel = 1 + CommandPrefix_CPU_LOW CommandPrefix_CPUNiceLevel = 2 +) + +// Enum value maps for CommandPrefix_CPUNiceLevel. +var ( + CommandPrefix_CPUNiceLevel_name = map[int32]string{ + 0: "CPU_DEFAULT", + 1: "CPU_HIGH", + 2: "CPU_LOW", + } + CommandPrefix_CPUNiceLevel_value = map[string]int32{ + "CPU_DEFAULT": 0, + "CPU_HIGH": 1, + "CPU_LOW": 2, + } +) + +func (x CommandPrefix_CPUNiceLevel) Enum() *CommandPrefix_CPUNiceLevel { + p := new(CommandPrefix_CPUNiceLevel) + *p = x + return p +} + +func (x CommandPrefix_CPUNiceLevel) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CommandPrefix_CPUNiceLevel) Descriptor() protoreflect.EnumDescriptor { + return file_v1_config_proto_enumTypes[1].Descriptor() +} + +func (CommandPrefix_CPUNiceLevel) Type() protoreflect.EnumType { + return &file_v1_config_proto_enumTypes[1] +} + +func (x CommandPrefix_CPUNiceLevel) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CommandPrefix_CPUNiceLevel.Descriptor instead. +func (CommandPrefix_CPUNiceLevel) EnumDescriptor() ([]byte, []int) { + return file_v1_config_proto_rawDescGZIP(), []int{4, 1} +} + type Hook_Condition int32 const ( @@ -86,11 +187,11 @@ func (x Hook_Condition) String() string { } func (Hook_Condition) Descriptor() protoreflect.EnumDescriptor { - return file_v1_config_proto_enumTypes[0].Descriptor() + return file_v1_config_proto_enumTypes[2].Descriptor() } func (Hook_Condition) Type() protoreflect.EnumType { - return &file_v1_config_proto_enumTypes[0] + return &file_v1_config_proto_enumTypes[2] } func (x Hook_Condition) Number() protoreflect.EnumNumber { @@ -99,7 +200,7 @@ func (x Hook_Condition) Number() protoreflect.EnumNumber { // Deprecated: Use Hook_Condition.Descriptor instead. func (Hook_Condition) EnumDescriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8, 0} + return file_v1_config_proto_rawDescGZIP(), []int{9, 0} } type Hook_OnError int32 @@ -135,11 +236,11 @@ func (x Hook_OnError) String() string { } func (Hook_OnError) Descriptor() protoreflect.EnumDescriptor { - return file_v1_config_proto_enumTypes[1].Descriptor() + return file_v1_config_proto_enumTypes[3].Descriptor() } func (Hook_OnError) Type() protoreflect.EnumType { - return &file_v1_config_proto_enumTypes[1] + return &file_v1_config_proto_enumTypes[3] } func (x Hook_OnError) Number() protoreflect.EnumNumber { @@ -148,7 +249,7 @@ func (x Hook_OnError) Number() protoreflect.EnumNumber { // Deprecated: Use Hook_OnError.Descriptor instead. func (Hook_OnError) EnumDescriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8, 1} + return file_v1_config_proto_rawDescGZIP(), []int{9, 1} } type Hook_Webhook_Method int32 @@ -184,11 +285,11 @@ func (x Hook_Webhook_Method) String() string { } func (Hook_Webhook_Method) Descriptor() protoreflect.EnumDescriptor { - return file_v1_config_proto_enumTypes[2].Descriptor() + return file_v1_config_proto_enumTypes[4].Descriptor() } func (Hook_Webhook_Method) Type() protoreflect.EnumType { - return &file_v1_config_proto_enumTypes[2] + return &file_v1_config_proto_enumTypes[4] } func (x Hook_Webhook_Method) Number() protoreflect.EnumNumber { @@ -197,7 +298,7 @@ func (x Hook_Webhook_Method) Number() protoreflect.EnumNumber { // Deprecated: Use Hook_Webhook_Method.Descriptor instead. func (Hook_Webhook_Method) EnumDescriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8, 1, 0} + return file_v1_config_proto_rawDescGZIP(), []int{9, 1, 0} } type HubConfig struct { @@ -343,15 +444,16 @@ type Repo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // unique but human readable ID for this repo. - Uri string `protobuf:"bytes,2,opt,name=uri,proto3" json:"uri,omitempty"` // restic repo URI - Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` // plaintext password - Env []string `protobuf:"bytes,4,rep,name=env,proto3" json:"env,omitempty"` // extra environment variables to set for restic. - Flags []string `protobuf:"bytes,5,rep,name=flags,proto3" json:"flags,omitempty"` // extra flags set on the restic command. - PrunePolicy *PrunePolicy `protobuf:"bytes,6,opt,name=prune_policy,json=prunePolicy,proto3" json:"prune_policy,omitempty"` // policy for when to run prune. - CheckPolicy *CheckPolicy `protobuf:"bytes,9,opt,name=check_policy,json=checkPolicy,proto3" json:"check_policy,omitempty"` // policy for when to run check. - Hooks []*Hook `protobuf:"bytes,7,rep,name=hooks,proto3" json:"hooks,omitempty"` // hooks to run on events for this repo. - AutoUnlock bool `protobuf:"varint,8,opt,name=auto_unlock,json=autoUnlock,proto3" json:"auto_unlock,omitempty"` // automatically unlock the repo when needed. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // unique but human readable ID for this repo. + Uri string `protobuf:"bytes,2,opt,name=uri,proto3" json:"uri,omitempty"` // restic repo URI + Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` // plaintext password + Env []string `protobuf:"bytes,4,rep,name=env,proto3" json:"env,omitempty"` // extra environment variables to set for restic. + Flags []string `protobuf:"bytes,5,rep,name=flags,proto3" json:"flags,omitempty"` // extra flags set on the restic command. + PrunePolicy *PrunePolicy `protobuf:"bytes,6,opt,name=prune_policy,json=prunePolicy,proto3" json:"prune_policy,omitempty"` // policy for when to run prune. + CheckPolicy *CheckPolicy `protobuf:"bytes,9,opt,name=check_policy,json=checkPolicy,proto3" json:"check_policy,omitempty"` // policy for when to run check. + Hooks []*Hook `protobuf:"bytes,7,rep,name=hooks,proto3" json:"hooks,omitempty"` // hooks to run on events for this repo. + AutoUnlock bool `protobuf:"varint,8,opt,name=auto_unlock,json=autoUnlock,proto3" json:"auto_unlock,omitempty"` // automatically unlock the repo when needed. + CommandPrefix *CommandPrefix `protobuf:"bytes,10,opt,name=command_prefix,json=commandPrefix,proto3" json:"command_prefix,omitempty"` // modifiers for the restic commands } func (x *Repo) Reset() { @@ -449,6 +551,13 @@ func (x *Repo) GetAutoUnlock() bool { return false } +func (x *Repo) GetCommandPrefix() *CommandPrefix { + if x != nil { + return x.CommandPrefix + } + return nil +} + type Plan struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -580,6 +689,61 @@ func (x *Plan) GetBackupFlags() []string { return nil } +type CommandPrefix struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IoNice CommandPrefix_IONiceLevel `protobuf:"varint,1,opt,name=io_nice,json=ioNice,proto3,enum=v1.CommandPrefix_IONiceLevel" json:"io_nice,omitempty"` // ionice level to set. + CpuNice CommandPrefix_CPUNiceLevel `protobuf:"varint,2,opt,name=cpu_nice,json=cpuNice,proto3,enum=v1.CommandPrefix_CPUNiceLevel" json:"cpu_nice,omitempty"` // nice level to set. +} + +func (x *CommandPrefix) Reset() { + *x = CommandPrefix{} + if protoimpl.UnsafeEnabled { + mi := &file_v1_config_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommandPrefix) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommandPrefix) ProtoMessage() {} + +func (x *CommandPrefix) ProtoReflect() protoreflect.Message { + mi := &file_v1_config_proto_msgTypes[4] + 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 CommandPrefix.ProtoReflect.Descriptor instead. +func (*CommandPrefix) Descriptor() ([]byte, []int) { + return file_v1_config_proto_rawDescGZIP(), []int{4} +} + +func (x *CommandPrefix) GetIoNice() CommandPrefix_IONiceLevel { + if x != nil { + return x.IoNice + } + return CommandPrefix_IO_DEFAULT +} + +func (x *CommandPrefix) GetCpuNice() CommandPrefix_CPUNiceLevel { + if x != nil { + return x.CpuNice + } + return CommandPrefix_CPU_DEFAULT +} + type RetentionPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -612,7 +776,7 @@ type RetentionPolicy struct { func (x *RetentionPolicy) Reset() { *x = RetentionPolicy{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[4] + mi := &file_v1_config_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -625,7 +789,7 @@ func (x *RetentionPolicy) String() string { func (*RetentionPolicy) ProtoMessage() {} func (x *RetentionPolicy) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[4] + mi := &file_v1_config_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -638,7 +802,7 @@ func (x *RetentionPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use RetentionPolicy.ProtoReflect.Descriptor instead. func (*RetentionPolicy) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{4} + return file_v1_config_proto_rawDescGZIP(), []int{5} } // Deprecated: Marked as deprecated in v1/config.proto. @@ -770,7 +934,7 @@ type PrunePolicy struct { func (x *PrunePolicy) Reset() { *x = PrunePolicy{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[5] + mi := &file_v1_config_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -783,7 +947,7 @@ func (x *PrunePolicy) String() string { func (*PrunePolicy) ProtoMessage() {} func (x *PrunePolicy) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[5] + mi := &file_v1_config_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -796,7 +960,7 @@ func (x *PrunePolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use PrunePolicy.ProtoReflect.Descriptor instead. func (*PrunePolicy) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{5} + return file_v1_config_proto_rawDescGZIP(), []int{6} } // Deprecated: Marked as deprecated in v1/config.proto. @@ -844,7 +1008,7 @@ type CheckPolicy struct { func (x *CheckPolicy) Reset() { *x = CheckPolicy{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[6] + mi := &file_v1_config_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -857,7 +1021,7 @@ func (x *CheckPolicy) String() string { func (*CheckPolicy) ProtoMessage() {} func (x *CheckPolicy) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[6] + mi := &file_v1_config_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -870,7 +1034,7 @@ func (x *CheckPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckPolicy.ProtoReflect.Descriptor instead. func (*CheckPolicy) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{6} + return file_v1_config_proto_rawDescGZIP(), []int{7} } func (x *CheckPolicy) GetSchedule() *Schedule { @@ -934,7 +1098,7 @@ type Schedule struct { func (x *Schedule) Reset() { *x = Schedule{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[7] + mi := &file_v1_config_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -947,7 +1111,7 @@ func (x *Schedule) String() string { func (*Schedule) ProtoMessage() {} func (x *Schedule) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[7] + mi := &file_v1_config_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -960,7 +1124,7 @@ func (x *Schedule) ProtoReflect() protoreflect.Message { // Deprecated: Use Schedule.ProtoReflect.Descriptor instead. func (*Schedule) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{7} + return file_v1_config_proto_rawDescGZIP(), []int{8} } func (m *Schedule) GetSchedule() isSchedule_Schedule { @@ -1047,7 +1211,7 @@ type Hook struct { func (x *Hook) Reset() { *x = Hook{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[8] + mi := &file_v1_config_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1060,7 +1224,7 @@ func (x *Hook) String() string { func (*Hook) ProtoMessage() {} func (x *Hook) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[8] + mi := &file_v1_config_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1073,7 +1237,7 @@ func (x *Hook) ProtoReflect() protoreflect.Message { // Deprecated: Use Hook.ProtoReflect.Descriptor instead. func (*Hook) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8} + return file_v1_config_proto_rawDescGZIP(), []int{9} } func (x *Hook) GetConditions() []Hook_Condition { @@ -1191,7 +1355,7 @@ type Auth struct { func (x *Auth) Reset() { *x = Auth{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[9] + mi := &file_v1_config_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1204,7 +1368,7 @@ func (x *Auth) String() string { func (*Auth) ProtoMessage() {} func (x *Auth) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[9] + mi := &file_v1_config_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1217,7 +1381,7 @@ func (x *Auth) ProtoReflect() protoreflect.Message { // Deprecated: Use Auth.ProtoReflect.Descriptor instead. func (*Auth) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{9} + return file_v1_config_proto_rawDescGZIP(), []int{10} } func (x *Auth) GetDisabled() bool { @@ -1249,7 +1413,7 @@ type User struct { func (x *User) Reset() { *x = User{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[10] + mi := &file_v1_config_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1262,7 +1426,7 @@ func (x *User) String() string { func (*User) ProtoMessage() {} func (x *User) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[10] + mi := &file_v1_config_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1275,7 +1439,7 @@ func (x *User) ProtoReflect() protoreflect.Message { // Deprecated: Use User.ProtoReflect.Descriptor instead. func (*User) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{10} + return file_v1_config_proto_rawDescGZIP(), []int{11} } func (x *User) GetName() string { @@ -1321,7 +1485,7 @@ type HubConfig_InstanceInfo struct { func (x *HubConfig_InstanceInfo) Reset() { *x = HubConfig_InstanceInfo{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[11] + mi := &file_v1_config_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1334,7 +1498,7 @@ func (x *HubConfig_InstanceInfo) String() string { func (*HubConfig_InstanceInfo) ProtoMessage() {} func (x *HubConfig_InstanceInfo) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[11] + mi := &file_v1_config_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1379,7 +1543,7 @@ type RetentionPolicy_TimeBucketedCounts struct { func (x *RetentionPolicy_TimeBucketedCounts) Reset() { *x = RetentionPolicy_TimeBucketedCounts{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[12] + mi := &file_v1_config_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1392,7 +1556,7 @@ func (x *RetentionPolicy_TimeBucketedCounts) String() string { func (*RetentionPolicy_TimeBucketedCounts) ProtoMessage() {} func (x *RetentionPolicy_TimeBucketedCounts) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[12] + mi := &file_v1_config_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1405,7 +1569,7 @@ func (x *RetentionPolicy_TimeBucketedCounts) ProtoReflect() protoreflect.Message // Deprecated: Use RetentionPolicy_TimeBucketedCounts.ProtoReflect.Descriptor instead. func (*RetentionPolicy_TimeBucketedCounts) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{4, 0} + return file_v1_config_proto_rawDescGZIP(), []int{5, 0} } func (x *RetentionPolicy_TimeBucketedCounts) GetHourly() int32 { @@ -1454,7 +1618,7 @@ type Hook_Command struct { func (x *Hook_Command) Reset() { *x = Hook_Command{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[13] + mi := &file_v1_config_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1467,7 +1631,7 @@ func (x *Hook_Command) String() string { func (*Hook_Command) ProtoMessage() {} func (x *Hook_Command) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[13] + mi := &file_v1_config_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1480,7 +1644,7 @@ func (x *Hook_Command) ProtoReflect() protoreflect.Message { // Deprecated: Use Hook_Command.ProtoReflect.Descriptor instead. func (*Hook_Command) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8, 0} + return file_v1_config_proto_rawDescGZIP(), []int{9, 0} } func (x *Hook_Command) GetCommand() string { @@ -1503,7 +1667,7 @@ type Hook_Webhook struct { func (x *Hook_Webhook) Reset() { *x = Hook_Webhook{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[14] + mi := &file_v1_config_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1516,7 +1680,7 @@ func (x *Hook_Webhook) String() string { func (*Hook_Webhook) ProtoMessage() {} func (x *Hook_Webhook) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[14] + mi := &file_v1_config_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1529,7 +1693,7 @@ func (x *Hook_Webhook) ProtoReflect() protoreflect.Message { // Deprecated: Use Hook_Webhook.ProtoReflect.Descriptor instead. func (*Hook_Webhook) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8, 1} + return file_v1_config_proto_rawDescGZIP(), []int{9, 1} } func (x *Hook_Webhook) GetWebhookUrl() string { @@ -1565,7 +1729,7 @@ type Hook_Discord struct { func (x *Hook_Discord) Reset() { *x = Hook_Discord{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[15] + mi := &file_v1_config_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1578,7 +1742,7 @@ func (x *Hook_Discord) String() string { func (*Hook_Discord) ProtoMessage() {} func (x *Hook_Discord) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[15] + mi := &file_v1_config_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1591,7 +1755,7 @@ func (x *Hook_Discord) ProtoReflect() protoreflect.Message { // Deprecated: Use Hook_Discord.ProtoReflect.Descriptor instead. func (*Hook_Discord) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8, 2} + return file_v1_config_proto_rawDescGZIP(), []int{9, 2} } func (x *Hook_Discord) GetWebhookUrl() string { @@ -1622,7 +1786,7 @@ type Hook_Gotify struct { func (x *Hook_Gotify) Reset() { *x = Hook_Gotify{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[16] + mi := &file_v1_config_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1635,7 +1799,7 @@ func (x *Hook_Gotify) String() string { func (*Hook_Gotify) ProtoMessage() {} func (x *Hook_Gotify) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[16] + mi := &file_v1_config_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1648,7 +1812,7 @@ func (x *Hook_Gotify) ProtoReflect() protoreflect.Message { // Deprecated: Use Hook_Gotify.ProtoReflect.Descriptor instead. func (*Hook_Gotify) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8, 3} + return file_v1_config_proto_rawDescGZIP(), []int{9, 3} } func (x *Hook_Gotify) GetBaseUrl() string { @@ -1691,7 +1855,7 @@ type Hook_Slack struct { func (x *Hook_Slack) Reset() { *x = Hook_Slack{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[17] + mi := &file_v1_config_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1704,7 +1868,7 @@ func (x *Hook_Slack) String() string { func (*Hook_Slack) ProtoMessage() {} func (x *Hook_Slack) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[17] + mi := &file_v1_config_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1717,7 +1881,7 @@ func (x *Hook_Slack) ProtoReflect() protoreflect.Message { // Deprecated: Use Hook_Slack.ProtoReflect.Descriptor instead. func (*Hook_Slack) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8, 4} + return file_v1_config_proto_rawDescGZIP(), []int{9, 4} } func (x *Hook_Slack) GetWebhookUrl() string { @@ -1746,7 +1910,7 @@ type Hook_Shoutrrr struct { func (x *Hook_Shoutrrr) Reset() { *x = Hook_Shoutrrr{} if protoimpl.UnsafeEnabled { - mi := &file_v1_config_proto_msgTypes[18] + mi := &file_v1_config_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1759,7 +1923,7 @@ func (x *Hook_Shoutrrr) String() string { func (*Hook_Shoutrrr) ProtoMessage() {} func (x *Hook_Shoutrrr) ProtoReflect() protoreflect.Message { - mi := &file_v1_config_proto_msgTypes[18] + mi := &file_v1_config_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1772,7 +1936,7 @@ func (x *Hook_Shoutrrr) ProtoReflect() protoreflect.Message { // Deprecated: Use Hook_Shoutrrr.ProtoReflect.Descriptor instead. func (*Hook_Shoutrrr) Descriptor() ([]byte, []int) { - return file_v1_config_proto_rawDescGZIP(), []int{8, 5} + return file_v1_config_proto_rawDescGZIP(), []int{9, 5} } func (x *Hook_Shoutrrr) GetShoutrrrUrl() string { @@ -1814,7 +1978,7 @@ var file_v1_config_proto_rawDesc = []byte{ 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x05, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, - 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x95, 0x02, 0x0a, 0x04, 0x52, 0x65, 0x70, 0x6f, 0x12, + 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0xcf, 0x02, 0x0a, 0x04, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, @@ -1831,209 +1995,230 @@ var file_v1_config_proto_rawDesc = []byte{ 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x75, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0xd3, - 0x02, 0x0a, 0x04, 0x50, 0x6c, 0x61, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x1e, 0x0a, 0x08, 0x64, - 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x70, - 0x61, 0x74, 0x68, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, - 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x1c, 0x0a, - 0x09, 0x69, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x09, 0x69, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x63, - 0x72, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x63, - 0x72, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, - 0x0c, 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, 0x31, 0x0a, - 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 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, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x1e, 0x0a, 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, - 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, - 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x66, - 0x6c, 0x61, 0x67, 0x73, 0x22, 0xa0, 0x05, 0x0a, 0x0f, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2c, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, - 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x55, 0x6e, 0x75, 0x73, 0x65, - 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x22, 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6c, - 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, - 0x09, 0x6b, 0x65, 0x65, 0x70, 0x4c, 0x61, 0x73, 0x74, 0x4e, 0x12, 0x23, 0x0a, 0x0b, 0x6b, 0x65, - 0x65, 0x70, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, - 0x02, 0x18, 0x01, 0x52, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, - 0x21, 0x0a, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x69, - 0x6c, 0x79, 0x12, 0x23, 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x77, 0x65, 0x65, 0x6b, 0x6c, - 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x6b, 0x65, 0x65, - 0x70, 0x57, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x12, 0x25, 0x0a, 0x0c, 0x6b, 0x65, 0x65, 0x70, 0x5f, - 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x12, 0x23, - 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x79, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x59, 0x65, 0x61, - 0x72, 0x6c, 0x79, 0x12, 0x34, 0x0a, 0x14, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x77, 0x69, 0x74, 0x68, - 0x69, 0x6e, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x57, 0x69, 0x74, 0x68, 0x69, - 0x6e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4b, - 0x65, 0x65, 0x70, 0x4c, 0x61, 0x73, 0x74, 0x4e, 0x12, 0x5a, 0x0a, 0x14, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x65, 0x64, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x74, 0x65, - 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x48, 0x00, - 0x52, 0x12, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x75, 0x63, 0x6b, - 0x65, 0x74, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6b, - 0x65, 0x65, 0x70, 0x5f, 0x61, 0x6c, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, - 0x0d, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x6c, 0x1a, 0x8c, - 0x01, 0x0a, 0x12, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x65, 0x64, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x64, 0x61, - 0x69, 0x6c, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, - 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x6f, - 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x79, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x79, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x42, 0x08, 0x0a, - 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0xc1, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x75, 0x6e, - 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x30, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x66, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x64, 0x61, 0x79, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x6e, 0x63, 0x79, 0x44, 0x61, 0x79, 0x73, 0x12, 0x28, 0x0a, 0x08, 0x73, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x02, 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, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x6e, 0x75, 0x73, 0x65, - 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6d, - 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, 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, 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, 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, - 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, 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, - 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, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4e, 0x44, + 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x38, + 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0xd3, 0x02, 0x0a, 0x04, 0x50, 0x6c, 0x61, + 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x1e, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, + 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, + 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x65, 0x78, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x69, 0x65, 0x78, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x12, 0x28, 0x0a, + 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x0c, 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, 0x31, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 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, + 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x05, 0x68, 0x6f, + 0x6f, 0x6b, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x48, + 0x6f, 0x6f, 0x6b, 0x52, 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x9b, + 0x02, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, + 0x12, 0x36, 0x0a, 0x07, 0x69, 0x6f, 0x5f, 0x6e, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x1d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x2e, 0x49, 0x4f, 0x4e, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x52, 0x06, 0x69, 0x6f, 0x4e, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x63, 0x70, 0x75, 0x5f, + 0x6e, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x2e, 0x43, 0x50, + 0x55, 0x4e, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x07, 0x63, 0x70, 0x75, 0x4e, + 0x69, 0x63, 0x65, 0x22, 0x5b, 0x0a, 0x0b, 0x49, 0x4f, 0x4e, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x4f, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, + 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4f, 0x5f, 0x42, 0x45, 0x53, 0x54, 0x5f, 0x45, 0x46, + 0x46, 0x4f, 0x52, 0x54, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x49, 0x4f, + 0x5f, 0x42, 0x45, 0x53, 0x54, 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, 0x5f, 0x48, 0x49, 0x47, + 0x48, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4f, 0x5f, 0x49, 0x44, 0x4c, 0x45, 0x10, 0x03, + 0x22, 0x3a, 0x0a, 0x0c, 0x43, 0x50, 0x55, 0x4e, 0x69, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x50, 0x55, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x50, 0x55, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x01, 0x12, + 0x0b, 0x0a, 0x07, 0x43, 0x50, 0x55, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x02, 0x22, 0xa0, 0x05, 0x0a, + 0x0f, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x12, 0x2c, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, + 0x6d, 0x61, 0x78, 0x55, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x22, + 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x4c, 0x61, 0x73, + 0x74, 0x4e, 0x12, 0x23, 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x6b, 0x65, 0x65, + 0x70, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, 0x21, 0x0a, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x5f, + 0x64, 0x61, 0x69, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x09, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x12, 0x23, 0x0a, 0x0b, 0x6b, 0x65, + 0x65, 0x70, 0x5f, 0x77, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x42, + 0x02, 0x18, 0x01, 0x52, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x57, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x12, + 0x25, 0x0a, 0x0c, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x4d, + 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x12, 0x23, 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x79, + 0x65, 0x61, 0x72, 0x6c, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x59, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x12, 0x34, 0x0a, 0x14, 0x6b, + 0x65, 0x65, 0x70, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x12, 0x6b, + 0x65, 0x65, 0x70, 0x57, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6b, 0x65, 0x65, 0x70, + 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, + 0x0f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4b, 0x65, 0x65, 0x70, 0x4c, 0x61, 0x73, 0x74, 0x4e, + 0x12, 0x5a, 0x0a, 0x14, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x65, 0x64, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x48, 0x00, 0x52, 0x12, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x54, 0x69, 0x6d, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x0f, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x61, 0x6c, 0x6c, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4b, + 0x65, 0x65, 0x70, 0x41, 0x6c, 0x6c, 0x1a, 0x8c, 0x01, 0x0a, 0x12, 0x54, 0x69, 0x6d, 0x65, 0x42, + 0x75, 0x63, 0x6b, 0x65, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, + 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x77, + 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65, 0x65, + 0x6b, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x12, 0x16, 0x0a, + 0x06, 0x79, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x79, + 0x65, 0x61, 0x72, 0x6c, 0x79, 0x42, 0x08, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, + 0xc1, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x30, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, + 0x5f, 0x64, 0x61, 0x79, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x10, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x44, 0x61, 0x79, + 0x73, 0x12, 0x28, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x02, 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, 0x28, 0x0a, 0x10, 0x6d, + 0x61, 0x78, 0x5f, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6d, 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, 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, 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, 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, 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, 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, 0x12, 0x1c, 0x0a, 0x18, 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, + 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, + 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, - 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, + 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 ( @@ -2048,61 +2233,67 @@ func file_v1_config_proto_rawDescGZIP() []byte { return file_v1_config_proto_rawDescData } -var file_v1_config_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_v1_config_proto_msgTypes = make([]protoimpl.MessageInfo, 19) +var file_v1_config_proto_enumTypes = make([]protoimpl.EnumInfo, 5) +var file_v1_config_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_v1_config_proto_goTypes = []interface{}{ - (Hook_Condition)(0), // 0: v1.Hook.Condition - (Hook_OnError)(0), // 1: v1.Hook.OnError - (Hook_Webhook_Method)(0), // 2: v1.Hook.Webhook.Method - (*HubConfig)(nil), // 3: v1.HubConfig - (*Config)(nil), // 4: v1.Config - (*Repo)(nil), // 5: v1.Repo - (*Plan)(nil), // 6: v1.Plan - (*RetentionPolicy)(nil), // 7: v1.RetentionPolicy - (*PrunePolicy)(nil), // 8: v1.PrunePolicy - (*CheckPolicy)(nil), // 9: v1.CheckPolicy - (*Schedule)(nil), // 10: v1.Schedule - (*Hook)(nil), // 11: v1.Hook - (*Auth)(nil), // 12: v1.Auth - (*User)(nil), // 13: v1.User - (*HubConfig_InstanceInfo)(nil), // 14: v1.HubConfig.InstanceInfo - (*RetentionPolicy_TimeBucketedCounts)(nil), // 15: v1.RetentionPolicy.TimeBucketedCounts - (*Hook_Command)(nil), // 16: v1.Hook.Command - (*Hook_Webhook)(nil), // 17: v1.Hook.Webhook - (*Hook_Discord)(nil), // 18: v1.Hook.Discord - (*Hook_Gotify)(nil), // 19: v1.Hook.Gotify - (*Hook_Slack)(nil), // 20: v1.Hook.Slack - (*Hook_Shoutrrr)(nil), // 21: v1.Hook.Shoutrrr + (CommandPrefix_IONiceLevel)(0), // 0: v1.CommandPrefix.IONiceLevel + (CommandPrefix_CPUNiceLevel)(0), // 1: v1.CommandPrefix.CPUNiceLevel + (Hook_Condition)(0), // 2: v1.Hook.Condition + (Hook_OnError)(0), // 3: v1.Hook.OnError + (Hook_Webhook_Method)(0), // 4: v1.Hook.Webhook.Method + (*HubConfig)(nil), // 5: v1.HubConfig + (*Config)(nil), // 6: v1.Config + (*Repo)(nil), // 7: v1.Repo + (*Plan)(nil), // 8: v1.Plan + (*CommandPrefix)(nil), // 9: v1.CommandPrefix + (*RetentionPolicy)(nil), // 10: v1.RetentionPolicy + (*PrunePolicy)(nil), // 11: v1.PrunePolicy + (*CheckPolicy)(nil), // 12: v1.CheckPolicy + (*Schedule)(nil), // 13: v1.Schedule + (*Hook)(nil), // 14: v1.Hook + (*Auth)(nil), // 15: v1.Auth + (*User)(nil), // 16: v1.User + (*HubConfig_InstanceInfo)(nil), // 17: v1.HubConfig.InstanceInfo + (*RetentionPolicy_TimeBucketedCounts)(nil), // 18: v1.RetentionPolicy.TimeBucketedCounts + (*Hook_Command)(nil), // 19: v1.Hook.Command + (*Hook_Webhook)(nil), // 20: v1.Hook.Webhook + (*Hook_Discord)(nil), // 21: v1.Hook.Discord + (*Hook_Gotify)(nil), // 22: v1.Hook.Gotify + (*Hook_Slack)(nil), // 23: v1.Hook.Slack + (*Hook_Shoutrrr)(nil), // 24: v1.Hook.Shoutrrr } var file_v1_config_proto_depIdxs = []int32{ - 14, // 0: v1.HubConfig.instances:type_name -> v1.HubConfig.InstanceInfo - 5, // 1: v1.Config.repos:type_name -> v1.Repo - 6, // 2: v1.Config.plans:type_name -> v1.Plan - 12, // 3: v1.Config.auth:type_name -> v1.Auth - 8, // 4: v1.Repo.prune_policy:type_name -> v1.PrunePolicy - 9, // 5: v1.Repo.check_policy:type_name -> v1.CheckPolicy - 11, // 6: v1.Repo.hooks:type_name -> v1.Hook - 10, // 7: v1.Plan.schedule:type_name -> v1.Schedule - 7, // 8: v1.Plan.retention:type_name -> v1.RetentionPolicy - 11, // 9: v1.Plan.hooks:type_name -> v1.Hook - 15, // 10: v1.RetentionPolicy.policy_time_bucketed:type_name -> v1.RetentionPolicy.TimeBucketedCounts - 10, // 11: v1.PrunePolicy.schedule:type_name -> v1.Schedule - 10, // 12: v1.CheckPolicy.schedule:type_name -> v1.Schedule - 0, // 13: v1.Hook.conditions:type_name -> v1.Hook.Condition - 1, // 14: v1.Hook.on_error:type_name -> v1.Hook.OnError - 16, // 15: v1.Hook.action_command:type_name -> v1.Hook.Command - 17, // 16: v1.Hook.action_webhook:type_name -> v1.Hook.Webhook - 18, // 17: v1.Hook.action_discord:type_name -> v1.Hook.Discord - 19, // 18: v1.Hook.action_gotify:type_name -> v1.Hook.Gotify - 20, // 19: v1.Hook.action_slack:type_name -> v1.Hook.Slack - 21, // 20: v1.Hook.action_shoutrrr:type_name -> v1.Hook.Shoutrrr - 13, // 21: v1.Auth.users:type_name -> v1.User - 2, // 22: v1.Hook.Webhook.method:type_name -> v1.Hook.Webhook.Method - 23, // [23:23] is the sub-list for method output_type - 23, // [23:23] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name + 17, // 0: v1.HubConfig.instances:type_name -> v1.HubConfig.InstanceInfo + 7, // 1: v1.Config.repos:type_name -> v1.Repo + 8, // 2: v1.Config.plans:type_name -> v1.Plan + 15, // 3: v1.Config.auth:type_name -> v1.Auth + 11, // 4: v1.Repo.prune_policy:type_name -> v1.PrunePolicy + 12, // 5: v1.Repo.check_policy:type_name -> v1.CheckPolicy + 14, // 6: v1.Repo.hooks:type_name -> v1.Hook + 9, // 7: v1.Repo.command_prefix:type_name -> v1.CommandPrefix + 13, // 8: v1.Plan.schedule:type_name -> v1.Schedule + 10, // 9: v1.Plan.retention:type_name -> v1.RetentionPolicy + 14, // 10: v1.Plan.hooks:type_name -> v1.Hook + 0, // 11: v1.CommandPrefix.io_nice:type_name -> v1.CommandPrefix.IONiceLevel + 1, // 12: v1.CommandPrefix.cpu_nice:type_name -> v1.CommandPrefix.CPUNiceLevel + 18, // 13: v1.RetentionPolicy.policy_time_bucketed:type_name -> v1.RetentionPolicy.TimeBucketedCounts + 13, // 14: v1.PrunePolicy.schedule:type_name -> v1.Schedule + 13, // 15: v1.CheckPolicy.schedule:type_name -> v1.Schedule + 2, // 16: v1.Hook.conditions:type_name -> v1.Hook.Condition + 3, // 17: v1.Hook.on_error:type_name -> v1.Hook.OnError + 19, // 18: v1.Hook.action_command:type_name -> v1.Hook.Command + 20, // 19: v1.Hook.action_webhook:type_name -> v1.Hook.Webhook + 21, // 20: v1.Hook.action_discord:type_name -> v1.Hook.Discord + 22, // 21: v1.Hook.action_gotify:type_name -> v1.Hook.Gotify + 23, // 22: v1.Hook.action_slack:type_name -> v1.Hook.Slack + 24, // 23: v1.Hook.action_shoutrrr:type_name -> v1.Hook.Shoutrrr + 16, // 24: v1.Auth.users:type_name -> v1.User + 4, // 25: v1.Hook.Webhook.method:type_name -> v1.Hook.Webhook.Method + 26, // [26:26] is the sub-list for method output_type + 26, // [26:26] is the sub-list for method input_type + 26, // [26:26] is the sub-list for extension type_name + 26, // [26:26] is the sub-list for extension extendee + 0, // [0:26] is the sub-list for field type_name } func init() { file_v1_config_proto_init() } @@ -2160,7 +2351,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RetentionPolicy); i { + switch v := v.(*CommandPrefix); i { case 0: return &v.state case 1: @@ -2172,7 +2363,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PrunePolicy); i { + switch v := v.(*RetentionPolicy); i { case 0: return &v.state case 1: @@ -2184,7 +2375,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckPolicy); i { + switch v := v.(*PrunePolicy); i { case 0: return &v.state case 1: @@ -2196,7 +2387,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Schedule); i { + switch v := v.(*CheckPolicy); i { case 0: return &v.state case 1: @@ -2208,7 +2399,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Hook); i { + switch v := v.(*Schedule); i { case 0: return &v.state case 1: @@ -2220,7 +2411,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Auth); i { + switch v := v.(*Hook); i { case 0: return &v.state case 1: @@ -2232,7 +2423,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*User); i { + switch v := v.(*Auth); i { case 0: return &v.state case 1: @@ -2244,7 +2435,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HubConfig_InstanceInfo); i { + switch v := v.(*User); i { case 0: return &v.state case 1: @@ -2256,7 +2447,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RetentionPolicy_TimeBucketedCounts); i { + switch v := v.(*HubConfig_InstanceInfo); i { case 0: return &v.state case 1: @@ -2268,7 +2459,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Hook_Command); i { + switch v := v.(*RetentionPolicy_TimeBucketedCounts); i { case 0: return &v.state case 1: @@ -2280,7 +2471,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Hook_Webhook); i { + switch v := v.(*Hook_Command); i { case 0: return &v.state case 1: @@ -2292,7 +2483,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Hook_Discord); i { + switch v := v.(*Hook_Webhook); i { case 0: return &v.state case 1: @@ -2304,7 +2495,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Hook_Gotify); i { + switch v := v.(*Hook_Discord); i { case 0: return &v.state case 1: @@ -2316,7 +2507,7 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Hook_Slack); i { + switch v := v.(*Hook_Gotify); i { case 0: return &v.state case 1: @@ -2328,6 +2519,18 @@ func file_v1_config_proto_init() { } } file_v1_config_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Hook_Slack); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_v1_config_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Hook_Shoutrrr); i { case 0: return &v.state @@ -2340,22 +2543,22 @@ func file_v1_config_proto_init() { } } } - file_v1_config_proto_msgTypes[4].OneofWrappers = []interface{}{ + file_v1_config_proto_msgTypes[5].OneofWrappers = []interface{}{ (*RetentionPolicy_PolicyKeepLastN)(nil), (*RetentionPolicy_PolicyTimeBucketed)(nil), (*RetentionPolicy_PolicyKeepAll)(nil), } - file_v1_config_proto_msgTypes[6].OneofWrappers = []interface{}{ + file_v1_config_proto_msgTypes[7].OneofWrappers = []interface{}{ (*CheckPolicy_StructureOnly)(nil), (*CheckPolicy_ReadDataSubsetPercent)(nil), } - file_v1_config_proto_msgTypes[7].OneofWrappers = []interface{}{ + file_v1_config_proto_msgTypes[8].OneofWrappers = []interface{}{ (*Schedule_Disabled)(nil), (*Schedule_Cron)(nil), (*Schedule_MaxFrequencyDays)(nil), (*Schedule_MaxFrequencyHours)(nil), } - file_v1_config_proto_msgTypes[8].OneofWrappers = []interface{}{ + file_v1_config_proto_msgTypes[9].OneofWrappers = []interface{}{ (*Hook_ActionCommand)(nil), (*Hook_ActionWebhook)(nil), (*Hook_ActionDiscord)(nil), @@ -2363,7 +2566,7 @@ func file_v1_config_proto_init() { (*Hook_ActionSlack)(nil), (*Hook_ActionShoutrrr)(nil), } - file_v1_config_proto_msgTypes[10].OneofWrappers = []interface{}{ + file_v1_config_proto_msgTypes[11].OneofWrappers = []interface{}{ (*User_PasswordBcrypt)(nil), } type x struct{} @@ -2371,8 +2574,8 @@ func file_v1_config_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_v1_config_proto_rawDesc, - NumEnums: 3, - NumMessages: 19, + NumEnums: 5, + NumMessages: 20, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/orchestrator/logging/logging.go b/internal/orchestrator/logging/logging.go index 12ede80..9127611 100644 --- a/internal/orchestrator/logging/logging.go +++ b/internal/orchestrator/logging/logging.go @@ -3,6 +3,9 @@ package logging import ( "context" "io" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) type contextKey int @@ -22,3 +25,20 @@ func WriterFromContext(ctx context.Context) io.Writer { func ContextWithWriter(ctx context.Context, logger io.Writer) context.Context { return context.WithValue(ctx, contextKeyLogWriter, logger) } + +// Logger returns a logger from the context, or the global logger if none is found. +// this is somewhat expensive, it should be called once per task. +func Logger(ctx context.Context) *zap.Logger { + writer := WriterFromContext(ctx) + if writer == nil { + return zap.L() + } + p := zap.NewProductionEncoderConfig() + p.EncodeTime = zapcore.ISO8601TimeEncoder + fe := zapcore.NewJSONEncoder(p) + l := zap.New(zapcore.NewTee( + zap.L().Core(), + zapcore.NewCore(fe, zapcore.AddSync(writer), zapcore.DebugLevel), + )) + return l +} diff --git a/internal/orchestrator/repo/command_prefix.go b/internal/orchestrator/repo/command_prefix.go new file mode 100644 index 0000000..6cf3eca --- /dev/null +++ b/internal/orchestrator/repo/command_prefix.go @@ -0,0 +1,52 @@ +package repo + +import ( + "errors" + "os/exec" + + v1 "github.com/garethgeorge/backrest/gen/go/v1" + "github.com/garethgeorge/backrest/pkg/restic" +) + +func niceAvailable() bool { + _, err := exec.LookPath("nice") + return err == nil +} + +func ioniceAvailable() bool { + _, err := exec.LookPath("ionice") + return err == nil +} + +// resolveCommandPrefix returns a list of restic.GenericOption that should be applied to a restic command based on the given prefix. +func resolveCommandPrefix(prefix *v1.CommandPrefix) ([]restic.GenericOption, error) { + var opts []restic.GenericOption + + if prefix.GetCpuNice() != v1.CommandPrefix_CPU_DEFAULT { + if !niceAvailable() { + return nil, errors.New("nice not available, cpu_nice cannot be used") + } + switch prefix.GetCpuNice() { + case v1.CommandPrefix_CPU_HIGH: + opts = append(opts, restic.WithPrefixCommand("nice", "-n", "-10")) + case v1.CommandPrefix_CPU_LOW: + opts = append(opts, restic.WithPrefixCommand("nice", "-n", "10")) + } + } + + if prefix.GetIoNice() != v1.CommandPrefix_IO_DEFAULT { + if !ioniceAvailable() { + return nil, errors.New("ionice not available, io_nice cannot be used") + } + switch prefix.GetIoNice() { + case v1.CommandPrefix_IO_IDLE: + opts = append(opts, restic.WithPrefixCommand("ionice", "-c", "3")) // idle priority, only runs when other IO is not queued. + case v1.CommandPrefix_IO_BEST_EFFORT_LOW: + opts = append(opts, restic.WithPrefixCommand("ionice", "-c", "2", "-n", "7")) // best effort, low priority. Default is -n 4. + case v1.CommandPrefix_IO_BEST_EFFORT_HIGH: + opts = append(opts, restic.WithPrefixCommand("ionice", "-c", "2", "-n", "0")) // best effort, high(er) than default priority. Default is -n 4. + } + } + + return opts, nil +} diff --git a/internal/orchestrator/repo/repo.go b/internal/orchestrator/repo/repo.go index bc2d2ae..cbd5539 100644 --- a/internal/orchestrator/repo/repo.go +++ b/internal/orchestrator/repo/repo.go @@ -52,11 +52,18 @@ func NewRepoOrchestrator(config *v1.Config, repoConfig *v1.Repo, resticPath stri for _, f := range repoConfig.GetFlags() { args, err := shlex.Split(f) if err != nil { - return nil, fmt.Errorf("failed to parse flag %q for repo %q: %w", f, repoConfig.Id, err) + return nil, fmt.Errorf("parse flag %q for repo %q: %w", f, repoConfig.Id, err) } opts = append(opts, restic.WithFlags(args...)) } + // Resolve command prefix + if extraOpts, err := resolveCommandPrefix(repoConfig.GetCommandPrefix()); err != nil { + return nil, fmt.Errorf("resolve command prefix: %w", err) + } else { + opts = append(opts, extraOpts...) + } + // Add BatchMode=yes to sftp.args if it's not already set. if slices.IndexFunc(repoConfig.GetFlags(), func(a string) bool { return strings.Contains(a, "sftp.args") diff --git a/internal/orchestrator/repo/repo_test.go b/internal/orchestrator/repo/repo_test.go index 744d349..9c490ac 100644 --- a/internal/orchestrator/repo/repo_test.go +++ b/internal/orchestrator/repo/repo_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "os" + "runtime" "slices" "strings" "testing" @@ -20,39 +21,71 @@ var configForTest = &v1.Config{ func TestBackup(t *testing.T) { t.Parallel() - repo := t.TempDir() testData := test.CreateTestData(t) - // create a new repo with cache disabled for testing - r := &v1.Repo{ - Id: "test", - Uri: repo, - Password: "test", - Flags: []string{"--no-cache"}, + tcs := []struct { + name string + repo *v1.Repo + plan *v1.Plan + unixOnly bool + }{ + { + name: "backup", + repo: &v1.Repo{ + Id: "test", + Uri: t.TempDir(), + Password: "test", + }, + plan: &v1.Plan{ + Id: "test", + Repo: "test", + Paths: []string{testData}, + }, + }, + { + name: "backup with ionice", + repo: &v1.Repo{ + Id: "test", + Uri: t.TempDir(), + Password: "test", + CommandPrefix: &v1.CommandPrefix{ + IoNice: v1.CommandPrefix_IO_BEST_EFFORT_LOW, + CpuNice: v1.CommandPrefix_CPU_LOW, + }, + }, + plan: &v1.Plan{ + Id: "test", + Repo: "test", + Paths: []string{testData}, + }, + unixOnly: true, + }, } - plan := &v1.Plan{ - Id: "test", - Repo: "test", - Paths: []string{testData}, - } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + if tc.unixOnly && runtime.GOOS == "windows" { + t.Skip("skipping on windows") + } - orchestrator, err := NewRepoOrchestrator(configForTest, r, helpers.ResticBinary(t)) - if err != nil { - t.Fatalf("failed to create repo orchestrator: %v", err) - } + orchestrator, err := NewRepoOrchestrator(configForTest, tc.repo, helpers.ResticBinary(t)) + if err != nil { + t.Fatalf("failed to create repo orchestrator: %v", err) + } - summary, err := orchestrator.Backup(context.Background(), plan, nil) - if err != nil { - t.Fatalf("backup error: %v", err) - } + summary, err := orchestrator.Backup(context.Background(), tc.plan, nil) + if err != nil { + t.Fatalf("backup error: %v", err) + } - if summary.SnapshotId == "" { - t.Fatal("expected snapshot id") - } + if summary.SnapshotId == "" { + t.Fatal("expected snapshot id") + } - if summary.FilesNew != 100 { - t.Fatalf("expected 100 new files, got %d", summary.FilesNew) + if summary.FilesNew != 100 { + t.Fatalf("expected 100 new files, got %d", summary.FilesNew) + } + }) } } diff --git a/internal/orchestrator/taskrunnerimpl.go b/internal/orchestrator/taskrunnerimpl.go index ece13ce..396aa14 100644 --- a/internal/orchestrator/taskrunnerimpl.go +++ b/internal/orchestrator/taskrunnerimpl.go @@ -1,13 +1,16 @@ package orchestrator import ( + "context" "time" v1 "github.com/garethgeorge/backrest/gen/go/v1" "github.com/garethgeorge/backrest/internal/hook" "github.com/garethgeorge/backrest/internal/oplog" + "github.com/garethgeorge/backrest/internal/orchestrator/logging" "github.com/garethgeorge/backrest/internal/orchestrator/repo" "github.com/garethgeorge/backrest/internal/orchestrator/tasks" + "go.uber.org/zap" ) // taskRunnerImpl is an implementation of TaskRunner for the default orchestrator. @@ -117,3 +120,7 @@ func (t *taskRunnerImpl) Config() *v1.Config { t.config = t.orchestrator.Config() return t.config } + +func (t *taskRunnerImpl) Logger(ctx context.Context) *zap.Logger { + return logging.Logger(ctx).Named(t.t.Name()) +} diff --git a/internal/orchestrator/tasks/loggingutil.go b/internal/orchestrator/tasks/loggingutil.go deleted file mode 100644 index cba2e91..0000000 --- a/internal/orchestrator/tasks/loggingutil.go +++ /dev/null @@ -1,26 +0,0 @@ -package tasks - -import ( - "context" - - "github.com/garethgeorge/backrest/internal/orchestrator/logging" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// LoggerFromContext returns a logger from the context, or the global logger if none is found. -// this is somewhat expensive, it should be called once per task. -func Logger(ctx context.Context, task Task) *zap.Logger { - writer := logging.WriterFromContext(ctx) - if writer == nil { - return zap.L() - } - p := zap.NewProductionEncoderConfig() - p.EncodeTime = zapcore.ISO8601TimeEncoder - fe := zapcore.NewJSONEncoder(p) - l := zap.New(zapcore.NewTee( - zap.L().Core(), - zapcore.NewCore(fe, zapcore.AddSync(writer), zapcore.DebugLevel), - )) - return l -} diff --git a/internal/orchestrator/tasks/task.go b/internal/orchestrator/tasks/task.go index 2ed0f3e..011c3af 100644 --- a/internal/orchestrator/tasks/task.go +++ b/internal/orchestrator/tasks/task.go @@ -8,6 +8,7 @@ import ( "github.com/garethgeorge/backrest/internal/hook" "github.com/garethgeorge/backrest/internal/oplog" "github.com/garethgeorge/backrest/internal/orchestrator/repo" + "go.uber.org/zap" "google.golang.org/protobuf/proto" ) @@ -46,6 +47,8 @@ type TaskRunner interface { ScheduleTask(task Task, priority int) error // Config returns the current config. Config() *v1.Config + // Logger returns the logger. + Logger(ctx context.Context) *zap.Logger } // ScheduledTask is a task that is scheduled to run at a specific time. diff --git a/internal/orchestrator/tasks/taskbackup.go b/internal/orchestrator/tasks/taskbackup.go index cc2a2e8..45fc0c8 100644 --- a/internal/orchestrator/tasks/taskbackup.go +++ b/internal/orchestrator/tasks/taskbackup.go @@ -87,7 +87,7 @@ func (t *BackupTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, erro } func (t *BackupTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunner) error { - l := Logger(ctx, st.Task) + l := runner.Logger(ctx) startTime := time.Now() op := st.Op @@ -133,10 +133,10 @@ func (t *BackupTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunne backupOp.OperationBackup.LastStatus = protoutil.BackupProgressEntryToProto(entry) } else if entry.MessageType == "error" { - zap.S().Warnf("an unknown error was encountered in processing item: %v", entry.Item) + l.Sugar().Warnf("an unknown error was encountered in processing item: %v", entry.Item) backupError, err := protoutil.BackupProgressEntryToBackupError(entry) if err != nil { - zap.S().Errorf("failed to convert backup progress entry to backup error: %v", err) + l.Sugar().Errorf("failed to convert backup progress entry to backup error: %v", err) return } if len(backupOp.OperationBackup.Errors) > maxBackupErrorHistoryLength || @@ -158,7 +158,7 @@ func (t *BackupTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunne sendWg.Add(1) go func() { if err := runner.UpdateOperation(op); err != nil { - zap.S().Errorf("failed to update oplog with progress for backup: %v", err) + l.Sugar().Errorf("failed to update oplog with progress for backup: %v", err) } sendWg.Done() }() diff --git a/internal/orchestrator/tasks/taskforget.go b/internal/orchestrator/tasks/taskforget.go index d51225b..bee1cfd 100644 --- a/internal/orchestrator/tasks/taskforget.go +++ b/internal/orchestrator/tasks/taskforget.go @@ -52,6 +52,7 @@ func NewOneoffForgetTask(repoID, planID string, flowID int64, at time.Time) Task func forgetHelper(ctx context.Context, st ScheduledTask, taskRunner TaskRunner) error { t := st.Task log := taskRunner.OpLog() + l := taskRunner.Logger(ctx) r, err := taskRunner.GetRepoOrchestrator(t.RepoID()) if err != nil { @@ -69,13 +70,13 @@ func forgetHelper(ctx context.Context, st ScheduledTask, taskRunner TaskRunner) } tags := []string{repo.TagForPlan(t.PlanID())} - if compat, err := useLegacyCompatMode(log, t.RepoID(), t.PlanID()); err != nil { + if compat, err := useLegacyCompatMode(l, log, t.RepoID(), t.PlanID()); err != nil { return fmt.Errorf("check legacy compat mode: %w", err) } else if !compat { tags = append(tags, repo.TagForInstance(taskRunner.Config().Instance)) } else { - zap.L().Warn("forgetting snapshots without instance ID, using legacy behavior (e.g. --tags not including instance ID)") - zap.S().Warnf("to avoid this warning, tag all snapshots with the instance ID e.g. by running: \r\n"+ + l.Warn("forgetting snapshots without instance ID, using legacy behavior (e.g. --tags not including instance ID)") + l.Sugar().Warnf("to avoid this warning, tag all snapshots with the instance ID e.g. by running: \r\n"+ "restic tag --set '%s' --set '%s' --tag '%s'", repo.TagForPlan(t.PlanID()), repo.TagForInstance(taskRunner.Config().Instance), repo.TagForPlan(t.PlanID())) } @@ -103,7 +104,7 @@ func forgetHelper(ctx context.Context, st ScheduledTask, taskRunner TaskRunner) } } - zap.S().Debugf("found %v snapshots were forgotten, marking this in oplog", len(ops)) + l.Sugar().Debugf("found %v snapshots were forgotten, marking this in oplog", len(ops)) for _, op := range ops { if indexOp, ok := op.Op.(*v1.Operation_OperationIndexSnapshot); ok { @@ -120,7 +121,7 @@ func forgetHelper(ctx context.Context, st ScheduledTask, taskRunner TaskRunner) // useLegacyCompatMode checks if there are any snapshots that were created without a `created-by` tag still exist in the repo. // The property is overridden if mixed `created-by` tag values are found. -func useLegacyCompatMode(log *oplog.OpLog, repoID, planID string) (bool, error) { +func useLegacyCompatMode(l *zap.Logger, log *oplog.OpLog, repoID, planID string) (bool, error) { instanceIDs := make(map[string]struct{}) if err := log.ForEach(oplog.Query{RepoId: repoID, PlanId: planID}, indexutil.CollectAll(), func(op *v1.Operation) error { if snapshotOp, ok := op.Op.(*v1.Operation_OperationIndexSnapshot); ok && !snapshotOp.OperationIndexSnapshot.GetForgot() { @@ -136,9 +137,9 @@ func useLegacyCompatMode(log *oplog.OpLog, repoID, planID string) (bool, error) } delete(instanceIDs, "") if len(instanceIDs) > 1 { - zap.L().Warn("found mixed instance IDs in indexed snapshots, overriding legacy forget behavior to include instance ID tags. This may result in unexpected behavior -- please inspect the tags on your snapshots.") + l.Sugar().Warn("found mixed instance IDs in indexed snapshots, overriding legacy forget behavior to include instance ID tags. This may result in unexpected behavior -- please inspect the tags on your snapshots.") return false, nil } - zap.L().Warn("found legacy snapshots without instance ID, recommending legacy forget behavior.") + l.Sugar().Warn("found legacy snapshots without instance ID, recommending legacy forget behavior.") return true, nil } diff --git a/internal/orchestrator/tasks/taskindexsnapshots.go b/internal/orchestrator/tasks/taskindexsnapshots.go index 4547fa4..51890d6 100644 --- a/internal/orchestrator/tasks/taskindexsnapshots.go +++ b/internal/orchestrator/tasks/taskindexsnapshots.go @@ -49,6 +49,7 @@ func NewOneoffIndexSnapshotsTask(repoID string, at time.Time) Task { func indexSnapshotsHelper(ctx context.Context, st ScheduledTask, taskRunner TaskRunner) error { t := st.Task oplog := taskRunner.OpLog() + l := taskRunner.Logger(ctx) repo, err := taskRunner.GetRepoOrchestrator(t.RepoID()) if err != nil { @@ -148,7 +149,7 @@ func indexSnapshotsHelper(ctx context.Context, st ScheduledTask, taskRunner Task } // Print stats at the end of indexing. - zap.L().Debug("indexed snapshots", + l.Debug("indexed snapshots", zap.String("repo", t.RepoID()), zap.Duration("duration", time.Since(startTime)), zap.Int("alreadyIndexed", len(foundIds)), diff --git a/pkg/restic/restic.go b/pkg/restic/restic.go index 553e473..8828766 100644 --- a/pkg/restic/restic.go +++ b/pkg/restic/restic.go @@ -26,8 +26,7 @@ type Repo struct { cmd string uri string - extraArgs []string - extraEnv []string + opts []GenericOption exists error checkExists sync.Once @@ -37,29 +36,29 @@ type Repo struct { // NewRepo instantiates a new repository. func NewRepo(resticBin string, uri string, opts ...GenericOption) *Repo { - opt := &GenericOpts{} - for _, o := range opts { - o(opt) - } - - opt.extraEnv = append(opt.extraEnv, "RESTIC_REPOSITORY="+uri) + opts = append(opts, WithEnv("RESTIC_REPOSITORY="+uri)) return &Repo{ - cmd: resticBin, // TODO: configurable binary path - uri: uri, - extraArgs: opt.extraArgs, - extraEnv: opt.extraEnv, + cmd: resticBin, + uri: uri, + opts: opts, } } func (r *Repo) commandWithContext(ctx context.Context, args []string, opts ...GenericOption) *exec.Cmd { - opt := resolveOpts(opts) + opt := &GenericOpts{} + resolveOpts(opt, r.opts) + resolveOpts(opt, opts) - args = append(args, r.extraArgs...) - args = append(args, opt.extraArgs...) + fullCmd := append([]string{r.cmd}, args...) - cmd := exec.CommandContext(ctx, r.cmd, args...) - cmd.Env = append(cmd.Env, r.extraEnv...) + if len(opt.prefixCmd) > 0 { + fullCmd = append(slices.Clone(opt.prefixCmd), fullCmd...) + } + + fullCmd = append(fullCmd, opt.extraArgs...) + + cmd := exec.CommandContext(ctx, fullCmd[0], fullCmd[1:]...) cmd.Env = append(cmd.Env, opt.extraEnv...) logger := LoggerFromContext(ctx) @@ -70,7 +69,7 @@ func (r *Repo) commandWithContext(ctx context.Context, args []string, opts ...Ge } if logger := LoggerFromContext(ctx); logger != nil { - fmt.Fprintf(logger, "\ncommand: %v %v\n", r.cmd, strings.Join(args, " ")) + fmt.Fprintf(logger, "\ncommand: %v %v\n", fullCmd[0], strings.Join(fullCmd[1:], " ")) } return cmd @@ -146,12 +145,12 @@ func (r *Repo) Backup(ctx context.Context, paths []string, progressCallback func } } - args := []string{"backup", "--json", "--exclude-caches"} + args := []string{"backup", "--json"} args = append(args, paths...) - opts = append(slices.Clone(opts), WithEnv("RESTIC_PROGRESS_FPS=2")) - cmd := r.commandWithContext(ctx, args, opts...) + cmdCtx, cancel := context.WithCancel(ctx) + cmd := r.commandWithContext(cmdCtx, args, opts...) outputForErr := ioutil.NewOutputCapturer(outputBufferLimit) buf := buffer.New(32 * 1024) // 32KB IO buffer for the realtime event parsing reader, writer := nio.Pipe(buf) @@ -163,11 +162,11 @@ func (r *Repo) Backup(ctx context.Context, paths []string, progressCallback func wg.Add(1) go func() { defer wg.Done() + defer cancel() var err error summary, err = readBackupProgressEntries(reader, progressCallback) if err != nil { readErr = fmt.Errorf("processing command output: %w", err) - _ = cmd.Cancel() // cancel the command to prevent it from hanging now that we're not reading from it. } }() @@ -278,7 +277,8 @@ func (r *Repo) Check(ctx context.Context, checkOutput io.Writer, opts ...Generic 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...) + cmdCtx, cancel := context.WithCancel(ctx) + cmd := r.commandWithContext(cmdCtx, []string{"restore", "--json", snapshot}, opts...) buf := buffer.New(32 * 1024) // 32KB IO buffer for the realtime event parsing reader, writer := nio.Pipe(buf) r.pipeCmdOutputToWriter(cmd, writer) @@ -289,11 +289,11 @@ func (r *Repo) Restore(ctx context.Context, snapshot string, callback func(*Rest wg.Add(1) go func() { defer wg.Done() + defer cancel() var err error summary, err = readRestoreProgressEntries(reader, callback) if err != nil { readErr = fmt.Errorf("processing command output: %w", err) - _ = cmd.Cancel() // cancel the command to prevent it from hanging now that we're not reading from it. } }() @@ -342,6 +342,7 @@ func (r *Repo) ListDirectory(ctx context.Context, snapshot string, path string, func (r *Repo) Unlock(ctx context.Context, opts ...GenericOption) error { output := bytes.NewBuffer(nil) cmd := r.commandWithContext(ctx, []string{"unlock"}, opts...) + r.pipeCmdOutputToWriter(cmd, output) if err := cmd.Run(); err != nil { return newCmdError(ctx, cmd, newErrorWithOutput(err, output.String())) } @@ -425,14 +426,13 @@ func (r *RetentionPolicy) toForgetFlags() []string { type GenericOpts struct { extraArgs []string extraEnv []string + prefixCmd []string } -func resolveOpts(opts []GenericOption) *GenericOpts { - opt := &GenericOpts{} +func resolveOpts(opt *GenericOpts, opts []GenericOption) { for _, o := range opts { o(opt) } - return opt } type GenericOption func(opts *GenericOpts) @@ -479,3 +479,9 @@ func WithPropagatedEnvVars(extras ...string) GenericOption { func WithEnviron() GenericOption { return WithEnv(os.Environ()...) } + +func WithPrefixCommand(args ...string) GenericOption { + return func(opts *GenericOpts) { + opts.prefixCmd = append(opts.prefixCmd, args...) + } +} diff --git a/pkg/restic/restic_test.go b/pkg/restic/restic_test.go index 2ee5e9e..ff566fe 100644 --- a/pkg/restic/restic_test.go +++ b/pkg/restic/restic_test.go @@ -44,11 +44,12 @@ func TestResticBackup(t *testing.T) { helpers.CreateUnreadable(t, testDataUnreadable+"/unreadable") var tests = []struct { - name string - opts []GenericOption - paths []string - files int64 // expected files at the end of the backup - wantErr bool + name string + opts []GenericOption + paths []string + files int64 // expected files at the end of the backup + wantErr bool + unixOnly bool }{ { name: "no options", @@ -86,10 +87,32 @@ func TestResticBackup(t *testing.T) { opts: []GenericOption{}, wantErr: true, }, + { + name: "with wrapper process", + paths: []string{testData}, + opts: []GenericOption{ + WithPrefixCommand("nice", "-n", "19"), + }, + files: 100, + unixOnly: true, + }, + { + name: "with invalid wrapper process", + paths: []string{testData}, + opts: []GenericOption{ + WithPrefixCommand("invalid-wrapper"), + }, + wantErr: true, + }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { + t.Parallel() + if runtime.GOOS == "windows" && tc.unixOnly { + t.Skip("test is unix only") + } + gotEvent := false summary, err := r.Backup(context.Background(), tc.paths, func(event *BackupProgressEntry) { t.Logf("backup event: %v", event) diff --git a/proto/v1/config.proto b/proto/v1/config.proto index be82417..7e344c1 100644 --- a/proto/v1/config.proto +++ b/proto/v1/config.proto @@ -41,6 +41,7 @@ message Repo { CheckPolicy check_policy = 9 [json_name="checkPolicy"]; // policy for when to run check. repeated Hook hooks = 7 [json_name="hooks"]; // hooks to run on events for this repo. bool auto_unlock = 8 [json_name="autoUnlock"]; // automatically unlock the repo when needed. + CommandPrefix command_prefix = 10 [json_name="commandPrefix"]; // modifiers for the restic commands } message Plan { @@ -57,6 +58,24 @@ message Plan { repeated string backup_flags = 10 [json_name="backup_flags"]; // extra flags to set when running a backup command. } +message CommandPrefix { + enum IONiceLevel { + IO_DEFAULT = 0; + IO_BEST_EFFORT_LOW = 1; + IO_BEST_EFFORT_HIGH = 2; + IO_IDLE = 3; + } + + enum CPUNiceLevel { + CPU_DEFAULT = 0; + CPU_HIGH = 1; + CPU_LOW = 2; + } + + IONiceLevel io_nice = 1 [json_name="ioNice"]; // ionice level to set. + CPUNiceLevel cpu_nice = 2 [json_name="cpuNice"]; // nice level to set. +} + message RetentionPolicy { string max_unused_limit = 1 [json_name="maxUnusedLimit", deprecated = true]; diff --git a/webui/gen/ts/v1/config_pb.ts b/webui/gen/ts/v1/config_pb.ts index 9c1dd8a..065b34e 100644 --- a/webui/gen/ts/v1/config_pb.ts +++ b/webui/gen/ts/v1/config_pb.ts @@ -231,6 +231,13 @@ export class Repo extends Message { */ autoUnlock = false; + /** + * modifiers for the restic commands + * + * @generated from field: v1.CommandPrefix command_prefix = 10; + */ + commandPrefix?: CommandPrefix; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -248,6 +255,7 @@ export class Repo extends Message { { no: 9, name: "check_policy", kind: "message", T: CheckPolicy }, { no: 7, name: "hooks", kind: "message", T: Hook, repeated: true }, { no: 8, name: "auto_unlock", kind: "scalar", T: 8 /* ScalarType.BOOL */ }, + { no: 10, name: "command_prefix", kind: "message", T: CommandPrefix }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): Repo { @@ -388,6 +396,111 @@ export class Plan extends Message { } } +/** + * @generated from message v1.CommandPrefix + */ +export class CommandPrefix extends Message { + /** + * ionice level to set. + * + * @generated from field: v1.CommandPrefix.IONiceLevel io_nice = 1; + */ + ioNice = CommandPrefix_IONiceLevel.IO_DEFAULT; + + /** + * nice level to set. + * + * @generated from field: v1.CommandPrefix.CPUNiceLevel cpu_nice = 2; + */ + cpuNice = CommandPrefix_CPUNiceLevel.CPU_DEFAULT; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "v1.CommandPrefix"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "io_nice", kind: "enum", T: proto3.getEnumType(CommandPrefix_IONiceLevel) }, + { no: 2, name: "cpu_nice", kind: "enum", T: proto3.getEnumType(CommandPrefix_CPUNiceLevel) }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): CommandPrefix { + return new CommandPrefix().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): CommandPrefix { + return new CommandPrefix().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): CommandPrefix { + return new CommandPrefix().fromJsonString(jsonString, options); + } + + static equals(a: CommandPrefix | PlainMessage | undefined, b: CommandPrefix | PlainMessage | undefined): boolean { + return proto3.util.equals(CommandPrefix, a, b); + } +} + +/** + * @generated from enum v1.CommandPrefix.IONiceLevel + */ +export enum CommandPrefix_IONiceLevel { + /** + * @generated from enum value: IO_DEFAULT = 0; + */ + IO_DEFAULT = 0, + + /** + * @generated from enum value: IO_BEST_EFFORT_LOW = 1; + */ + IO_BEST_EFFORT_LOW = 1, + + /** + * @generated from enum value: IO_BEST_EFFORT_HIGH = 2; + */ + IO_BEST_EFFORT_HIGH = 2, + + /** + * @generated from enum value: IO_IDLE = 3; + */ + IO_IDLE = 3, +} +// Retrieve enum metadata with: proto3.getEnumType(CommandPrefix_IONiceLevel) +proto3.util.setEnumType(CommandPrefix_IONiceLevel, "v1.CommandPrefix.IONiceLevel", [ + { no: 0, name: "IO_DEFAULT" }, + { no: 1, name: "IO_BEST_EFFORT_LOW" }, + { no: 2, name: "IO_BEST_EFFORT_HIGH" }, + { no: 3, name: "IO_IDLE" }, +]); + +/** + * @generated from enum v1.CommandPrefix.CPUNiceLevel + */ +export enum CommandPrefix_CPUNiceLevel { + /** + * @generated from enum value: CPU_DEFAULT = 0; + */ + CPU_DEFAULT = 0, + + /** + * @generated from enum value: CPU_HIGH = 1; + */ + CPU_HIGH = 1, + + /** + * @generated from enum value: CPU_LOW = 2; + */ + CPU_LOW = 2, +} +// Retrieve enum metadata with: proto3.getEnumType(CommandPrefix_CPUNiceLevel) +proto3.util.setEnumType(CommandPrefix_CPUNiceLevel, "v1.CommandPrefix.CPUNiceLevel", [ + { no: 0, name: "CPU_DEFAULT" }, + { no: 1, name: "CPU_HIGH" }, + { no: 2, name: "CPU_LOW" }, +]); + /** * @generated from message v1.RetentionPolicy */ diff --git a/webui/src/api.ts b/webui/src/api.ts index c4d19a4..9939551 100644 --- a/webui/src/api.ts +++ b/webui/src/api.ts @@ -26,7 +26,7 @@ const fetch = ( const transport = createConnectTransport({ baseUrl: "./", - useBinaryFormat: false, + useBinaryFormat: true, fetch: fetch as typeof globalThis.fetch, }); diff --git a/webui/src/views/AddRepoModal.tsx b/webui/src/views/AddRepoModal.tsx index 083b41b..2f82e3a 100644 --- a/webui/src/views/AddRepoModal.tsx +++ b/webui/src/views/AddRepoModal.tsx @@ -13,10 +13,17 @@ import { FormInstance, Collapse, Checkbox, + Select, + Space, } from "antd"; import React, { useEffect, useState } from "react"; import { useShowModal } from "../components/ModalManager"; -import { Hook, Repo } from "../../gen/ts/v1/config_pb"; +import { + CommandPrefix_CPUNiceLevel, + CommandPrefix_IONiceLevel, + Hook, + Repo, +} from "../../gen/ts/v1/config_pb"; import { URIAutocomplete } from "../components/URIAutocomplete"; import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"; import { formatErrorAlert, useAlertApi } from "../components/Alerts"; @@ -31,6 +38,8 @@ import { ConfirmButton } from "../components/SpinButton"; import { useConfig } from "../components/ConfigProvider"; import Cron from "react-js-cron"; import { ScheduleFormItem } from "../components/ScheduleFormItem"; +import { proto3 } from "@bufbuild/protobuf"; +import { isWindows } from "../state/buildcfg"; export const AddRepoModal = ({ template }: { template: Repo | null }) => { const [confirmLoading, setConfirmLoading] = useState(false); @@ -97,14 +106,15 @@ export const AddRepoModal = ({ template }: { template: Repo | null }) => { }); if (template !== null) { + const configCopy = config.clone(); // We are in the edit repo flow, update the repo in the config - const idx = config.repos!.findIndex((r) => r.id === template!.id); + const idx = configCopy.repos!.findIndex((r) => r.id === template!.id); if (idx === -1) { alertsApi.error("Can't update repo, not found"); return; } - config.repos![idx] = repo; - setConfig(await backrestService.setConfig(config)); + configCopy.repos![idx] = repo; + setConfig(await backrestService.setConfig(configCopy)); showModal(null); alertsApi.success("Updated repo " + repo.uri); @@ -486,12 +496,112 @@ export const AddRepoModal = ({ template }: { template: Repo | null }) => { + {/* Repo.commandPrefix */} + {!isWindows && ( + + Modifiers for the backup operation e.g. set the CPU or IO + priority. + + } + > + Command Modifiers + + } + colon={false} + > + + + + Available IO priority modes +
    +
  • + IO_BEST_EFFORT_LOW - runs at lower than default disk + priority (will prioritize other processes) +
  • +
  • + IO_BEST_EFFORT_HIGH - runs at higher than default + disk priority (top of disk IO queue) +
  • +
  • + IO_IDLE - only runs when disk bandwidth is idle + (e.g. no other operations are queued) +
  • +
+ + } + > + IO Priority: +
+ + ({ + label: v.name, + value: v.name, + }))} + /> + +
+ +
+
+ )} + Auto Unlock