From 4063d8fafcf00e59ab259556002abc63e51fa20c Mon Sep 17 00:00:00 2001 From: Gareth Evans <63365672+ggfevans@users.noreply.github.com> Date: Sun, 1 Feb 2026 11:43:05 -0800 Subject: [PATCH] feat: add Dry Run Backup action (#1098) --- gen/go/google/api/annotations.pb.go | 2 +- gen/go/google/api/http.pb.go | 2 +- gen/go/types/value.pb.go | 2 +- gen/go/v1/authentication.pb.go | 2 +- gen/go/v1/authentication_grpc.pb.go | 8 +- gen/go/v1/config.pb.go | 2 +- gen/go/v1/crypto.pb.go | 2 +- gen/go/v1/operations.pb.go | 15 +- gen/go/v1/restic.pb.go | 2 +- gen/go/v1/service.pb.go | 366 ++++++++++-------- gen/go/v1/service_grpc.pb.go | 58 +-- gen/go/v1/v1connect/service.connect.go | 12 +- gen/go/v1sync/syncservice.pb.go | 2 +- gen/go/v1sync/syncservice_grpc.pb.go | 10 +- internal/api/backresthandler.go | 4 +- internal/api/backresthandler_test.go | 16 +- internal/orchestrator/repo/repo.go | 6 +- internal/orchestrator/repo/repo_test.go | 8 +- internal/orchestrator/tasks/taskbackup.go | 50 ++- proto/v1/operations.proto | 1 + proto/v1/service.proto | 7 +- test/e2e/first_run_test.go | 3 +- webui/gen/ts/google/api/annotations_pb.ts | 2 +- webui/gen/ts/google/api/http_pb.ts | 2 +- webui/gen/ts/types/value_pb.ts | 2 +- webui/gen/ts/v1/authentication_pb.ts | 2 +- webui/gen/ts/v1/config_pb.ts | 2 +- webui/gen/ts/v1/crypto_pb.ts | 2 +- webui/gen/ts/v1/operations_pb.ts | 11 +- webui/gen/ts/v1/restic_pb.ts | 2 +- webui/gen/ts/v1/service_pb.ts | 76 ++-- webui/gen/ts/v1sync/syncservice_pb.ts | 2 +- webui/messages/en.json | 3 + webui/src/api/flowDisplayAggregator.ts | 7 +- webui/src/api/oplog.ts | 12 +- .../src/features/operations/OperationIcon.tsx | 1 + .../src/features/operations/OperationRow.tsx | 6 +- webui/src/features/plans/PlanView.tsx | 19 +- 38 files changed, 449 insertions(+), 282 deletions(-) diff --git a/gen/go/google/api/annotations.pb.go b/gen/go/google/api/annotations.pb.go index 9c17136e..d3764c8d 100644 --- a/gen/go/google/api/annotations.pb.go +++ b/gen/go/google/api/annotations.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: google/api/annotations.proto diff --git a/gen/go/google/api/http.pb.go b/gen/go/google/api/http.pb.go index 212e065e..b72638e2 100644 --- a/gen/go/google/api/http.pb.go +++ b/gen/go/google/api/http.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: google/api/http.proto diff --git a/gen/go/types/value.pb.go b/gen/go/types/value.pb.go index 7bf66a30..b8a49147 100644 --- a/gen/go/types/value.pb.go +++ b/gen/go/types/value.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: types/value.proto diff --git a/gen/go/v1/authentication.pb.go b/gen/go/v1/authentication.pb.go index 4c524605..a2a00c5f 100644 --- a/gen/go/v1/authentication.pb.go +++ b/gen/go/v1/authentication.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: v1/authentication.proto diff --git a/gen/go/v1/authentication_grpc.pb.go b/gen/go/v1/authentication_grpc.pb.go index 9be66eda..26789b95 100644 --- a/gen/go/v1/authentication_grpc.pb.go +++ b/gen/go/v1/authentication_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 +// - protoc-gen-go-grpc v1.6.0 // - protoc (unknown) // source: v1/authentication.proto @@ -77,10 +77,10 @@ type AuthenticationServer interface { type UnimplementedAuthenticationServer struct{} func (UnimplementedAuthenticationServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Login not implemented") + return nil, status.Error(codes.Unimplemented, "method Login not implemented") } func (UnimplementedAuthenticationServer) HashPassword(context.Context, *types.StringValue) (*types.StringValue, error) { - return nil, status.Errorf(codes.Unimplemented, "method HashPassword not implemented") + return nil, status.Error(codes.Unimplemented, "method HashPassword not implemented") } func (UnimplementedAuthenticationServer) mustEmbedUnimplementedAuthenticationServer() {} func (UnimplementedAuthenticationServer) testEmbeddedByValue() {} @@ -93,7 +93,7 @@ type UnsafeAuthenticationServer interface { } func RegisterAuthenticationServer(s grpc.ServiceRegistrar, srv AuthenticationServer) { - // If the following call pancis, it indicates UnimplementedAuthenticationServer was + // If the following call panics, it indicates UnimplementedAuthenticationServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. diff --git a/gen/go/v1/config.pb.go b/gen/go/v1/config.pb.go index eae8d60c..1d951633 100644 --- a/gen/go/v1/config.pb.go +++ b/gen/go/v1/config.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: v1/config.proto diff --git a/gen/go/v1/crypto.pb.go b/gen/go/v1/crypto.pb.go index ce064c0e..8a1eaed7 100644 --- a/gen/go/v1/crypto.pb.go +++ b/gen/go/v1/crypto.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: v1/crypto.proto diff --git a/gen/go/v1/operations.pb.go b/gen/go/v1/operations.pb.go index 8baa7554..85e504b1 100644 --- a/gen/go/v1/operations.pb.go +++ b/gen/go/v1/operations.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: v1/operations.proto @@ -638,6 +638,7 @@ type OperationBackup struct { state protoimpl.MessageState `protogen:"open.v1"` LastStatus *BackupProgressEntry `protobuf:"bytes,3,opt,name=last_status,json=lastStatus,proto3" json:"last_status,omitempty"` Errors []*BackupProgressError `protobuf:"bytes,4,rep,name=errors,proto3" json:"errors,omitempty"` + DryRun bool `protobuf:"varint,5,opt,name=dry_run,json=dryRun,proto3" json:"dry_run,omitempty"` // indicates this was a dry run backup (no snapshot created) unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -686,6 +687,13 @@ func (x *OperationBackup) GetErrors() []*BackupProgressError { return nil } +func (x *OperationBackup) GetDryRun() bool { + if x != nil { + return x.DryRun + } + return false +} + // OperationIndexSnapshot tracks that a snapshot was detected by backrest. type OperationIndexSnapshot struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1184,11 +1192,12 @@ const file_v1_operations_proto_rawDesc = "" + "\x12created_operations\x18\x02 \x01(\v2\x11.v1.OperationListH\x00R\x11createdOperations\x12B\n" + "\x12updated_operations\x18\x03 \x01(\v2\x11.v1.OperationListH\x00R\x11updatedOperations\x12A\n" + "\x12deleted_operations\x18\x04 \x01(\v2\x10.types.Int64ListH\x00R\x11deletedOperationsB\a\n" + - "\x05event\"|\n" + + "\x05event\"\x95\x01\n" + "\x0fOperationBackup\x128\n" + "\vlast_status\x18\x03 \x01(\v2\x17.v1.BackupProgressEntryR\n" + "lastStatus\x12/\n" + - "\x06errors\x18\x04 \x03(\v2\x17.v1.BackupProgressErrorR\x06errors\"`\n" + + "\x06errors\x18\x04 \x03(\v2\x17.v1.BackupProgressErrorR\x06errors\x12\x17\n" + + "\adry_run\x18\x05 \x01(\bR\x06dryRun\"`\n" + "\x16OperationIndexSnapshot\x12.\n" + "\bsnapshot\x18\x02 \x01(\v2\x12.v1.ResticSnapshotR\bsnapshot\x12\x16\n" + "\x06forgot\x18\x03 \x01(\bR\x06forgot\"j\n" + diff --git a/gen/go/v1/restic.pb.go b/gen/go/v1/restic.pb.go index e588c223..e6f917d7 100644 --- a/gen/go/v1/restic.pb.go +++ b/gen/go/v1/restic.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: v1/restic.proto diff --git a/gen/go/v1/service.pb.go b/gen/go/v1/service.pb.go index f57c2f9d..02f636c7 100644 --- a/gen/go/v1/service.pb.go +++ b/gen/go/v1/service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: v1/service.proto @@ -79,7 +79,59 @@ func (x DoRepoTaskRequest_Task) Number() protoreflect.EnumNumber { // Deprecated: Use DoRepoTaskRequest_Task.Descriptor instead. func (DoRepoTaskRequest_Task) EnumDescriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{6, 0} + return file_v1_service_proto_rawDescGZIP(), []int{7, 0} +} + +type BackupRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // plan_id - named 'value' for curl script backwards compatibility + DryRun bool `protobuf:"varint,2,opt,name=dry_run,json=dryRun,proto3" json:"dry_run,omitempty"` // optional, simulate backup without creating snapshot + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BackupRequest) Reset() { + *x = BackupRequest{} + mi := &file_v1_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BackupRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BackupRequest) ProtoMessage() {} + +func (x *BackupRequest) ProtoReflect() protoreflect.Message { + mi := &file_v1_service_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BackupRequest.ProtoReflect.Descriptor instead. +func (*BackupRequest) Descriptor() ([]byte, []int) { + return file_v1_service_proto_rawDescGZIP(), []int{0} +} + +func (x *BackupRequest) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *BackupRequest) GetDryRun() bool { + if x != nil { + return x.DryRun + } + return false } // OpSelector is a message that can be used to select operations e.g. by query. @@ -99,7 +151,7 @@ type OpSelector struct { func (x *OpSelector) Reset() { *x = OpSelector{} - mi := &file_v1_service_proto_msgTypes[0] + mi := &file_v1_service_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -111,7 +163,7 @@ func (x *OpSelector) String() string { func (*OpSelector) ProtoMessage() {} func (x *OpSelector) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[0] + mi := &file_v1_service_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -124,7 +176,7 @@ func (x *OpSelector) ProtoReflect() protoreflect.Message { // Deprecated: Use OpSelector.ProtoReflect.Descriptor instead. func (*OpSelector) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{0} + return file_v1_service_proto_rawDescGZIP(), []int{1} } func (x *OpSelector) GetIds() []int64 { @@ -195,7 +247,7 @@ type SetupSftpRequest struct { func (x *SetupSftpRequest) Reset() { *x = SetupSftpRequest{} - mi := &file_v1_service_proto_msgTypes[1] + mi := &file_v1_service_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -207,7 +259,7 @@ func (x *SetupSftpRequest) String() string { func (*SetupSftpRequest) ProtoMessage() {} func (x *SetupSftpRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[1] + mi := &file_v1_service_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -220,7 +272,7 @@ func (x *SetupSftpRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetupSftpRequest.ProtoReflect.Descriptor instead. func (*SetupSftpRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{1} + return file_v1_service_proto_rawDescGZIP(), []int{2} } func (x *SetupSftpRequest) GetHost() string { @@ -263,7 +315,7 @@ type SetupSftpResponse struct { func (x *SetupSftpResponse) Reset() { *x = SetupSftpResponse{} - mi := &file_v1_service_proto_msgTypes[2] + mi := &file_v1_service_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -275,7 +327,7 @@ func (x *SetupSftpResponse) String() string { func (*SetupSftpResponse) ProtoMessage() {} func (x *SetupSftpResponse) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[2] + mi := &file_v1_service_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -288,7 +340,7 @@ func (x *SetupSftpResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetupSftpResponse.ProtoReflect.Descriptor instead. func (*SetupSftpResponse) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{2} + return file_v1_service_proto_rawDescGZIP(), []int{3} } func (x *SetupSftpResponse) GetPublicKey() string { @@ -329,7 +381,7 @@ type CheckRepoExistsRequest struct { func (x *CheckRepoExistsRequest) Reset() { *x = CheckRepoExistsRequest{} - mi := &file_v1_service_proto_msgTypes[3] + mi := &file_v1_service_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -341,7 +393,7 @@ func (x *CheckRepoExistsRequest) String() string { func (*CheckRepoExistsRequest) ProtoMessage() {} func (x *CheckRepoExistsRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[3] + mi := &file_v1_service_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -354,7 +406,7 @@ func (x *CheckRepoExistsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckRepoExistsRequest.ProtoReflect.Descriptor instead. func (*CheckRepoExistsRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{3} + return file_v1_service_proto_rawDescGZIP(), []int{4} } func (x *CheckRepoExistsRequest) GetRepo() *Repo { @@ -382,7 +434,7 @@ type CheckRepoExistsResponse struct { func (x *CheckRepoExistsResponse) Reset() { *x = CheckRepoExistsResponse{} - mi := &file_v1_service_proto_msgTypes[4] + mi := &file_v1_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -394,7 +446,7 @@ func (x *CheckRepoExistsResponse) String() string { func (*CheckRepoExistsResponse) ProtoMessage() {} func (x *CheckRepoExistsResponse) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[4] + mi := &file_v1_service_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -407,7 +459,7 @@ func (x *CheckRepoExistsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckRepoExistsResponse.ProtoReflect.Descriptor instead. func (*CheckRepoExistsResponse) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{4} + return file_v1_service_proto_rawDescGZIP(), []int{5} } func (x *CheckRepoExistsResponse) GetExists() bool { @@ -441,7 +493,7 @@ type AddRepoRequest struct { func (x *AddRepoRequest) Reset() { *x = AddRepoRequest{} - mi := &file_v1_service_proto_msgTypes[5] + mi := &file_v1_service_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -453,7 +505,7 @@ func (x *AddRepoRequest) String() string { func (*AddRepoRequest) ProtoMessage() {} func (x *AddRepoRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[5] + mi := &file_v1_service_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -466,7 +518,7 @@ func (x *AddRepoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddRepoRequest.ProtoReflect.Descriptor instead. func (*AddRepoRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{5} + return file_v1_service_proto_rawDescGZIP(), []int{6} } func (x *AddRepoRequest) GetRepo() *Repo { @@ -493,7 +545,7 @@ type DoRepoTaskRequest struct { func (x *DoRepoTaskRequest) Reset() { *x = DoRepoTaskRequest{} - mi := &file_v1_service_proto_msgTypes[6] + mi := &file_v1_service_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -505,7 +557,7 @@ func (x *DoRepoTaskRequest) String() string { func (*DoRepoTaskRequest) ProtoMessage() {} func (x *DoRepoTaskRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[6] + mi := &file_v1_service_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -518,7 +570,7 @@ func (x *DoRepoTaskRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DoRepoTaskRequest.ProtoReflect.Descriptor instead. func (*DoRepoTaskRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{6} + return file_v1_service_proto_rawDescGZIP(), []int{7} } func (x *DoRepoTaskRequest) GetRepoId() string { @@ -545,7 +597,7 @@ type ClearHistoryRequest struct { func (x *ClearHistoryRequest) Reset() { *x = ClearHistoryRequest{} - mi := &file_v1_service_proto_msgTypes[7] + mi := &file_v1_service_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -557,7 +609,7 @@ func (x *ClearHistoryRequest) String() string { func (*ClearHistoryRequest) ProtoMessage() {} func (x *ClearHistoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[7] + mi := &file_v1_service_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -570,7 +622,7 @@ func (x *ClearHistoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearHistoryRequest.ProtoReflect.Descriptor instead. func (*ClearHistoryRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{7} + return file_v1_service_proto_rawDescGZIP(), []int{8} } func (x *ClearHistoryRequest) GetSelector() *OpSelector { @@ -598,7 +650,7 @@ type ForgetRequest struct { func (x *ForgetRequest) Reset() { *x = ForgetRequest{} - mi := &file_v1_service_proto_msgTypes[8] + mi := &file_v1_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -610,7 +662,7 @@ func (x *ForgetRequest) String() string { func (*ForgetRequest) ProtoMessage() {} func (x *ForgetRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[8] + mi := &file_v1_service_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -623,7 +675,7 @@ func (x *ForgetRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ForgetRequest.ProtoReflect.Descriptor instead. func (*ForgetRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{8} + return file_v1_service_proto_rawDescGZIP(), []int{9} } func (x *ForgetRequest) GetRepoId() string { @@ -657,7 +709,7 @@ type ListSnapshotsRequest struct { func (x *ListSnapshotsRequest) Reset() { *x = ListSnapshotsRequest{} - mi := &file_v1_service_proto_msgTypes[9] + mi := &file_v1_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -669,7 +721,7 @@ func (x *ListSnapshotsRequest) String() string { func (*ListSnapshotsRequest) ProtoMessage() {} func (x *ListSnapshotsRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[9] + mi := &file_v1_service_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -682,7 +734,7 @@ func (x *ListSnapshotsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSnapshotsRequest.ProtoReflect.Descriptor instead. func (*ListSnapshotsRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{9} + return file_v1_service_proto_rawDescGZIP(), []int{10} } func (x *ListSnapshotsRequest) GetRepoId() string { @@ -709,7 +761,7 @@ type GetOperationsRequest struct { func (x *GetOperationsRequest) Reset() { *x = GetOperationsRequest{} - mi := &file_v1_service_proto_msgTypes[10] + mi := &file_v1_service_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -721,7 +773,7 @@ func (x *GetOperationsRequest) String() string { func (*GetOperationsRequest) ProtoMessage() {} func (x *GetOperationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[10] + mi := &file_v1_service_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -734,7 +786,7 @@ func (x *GetOperationsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetOperationsRequest.ProtoReflect.Descriptor instead. func (*GetOperationsRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{10} + return file_v1_service_proto_rawDescGZIP(), []int{11} } func (x *GetOperationsRequest) GetSelector() *OpSelector { @@ -764,7 +816,7 @@ type RestoreSnapshotRequest struct { func (x *RestoreSnapshotRequest) Reset() { *x = RestoreSnapshotRequest{} - mi := &file_v1_service_proto_msgTypes[11] + mi := &file_v1_service_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -776,7 +828,7 @@ func (x *RestoreSnapshotRequest) String() string { func (*RestoreSnapshotRequest) ProtoMessage() {} func (x *RestoreSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[11] + mi := &file_v1_service_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -789,7 +841,7 @@ func (x *RestoreSnapshotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreSnapshotRequest.ProtoReflect.Descriptor instead. func (*RestoreSnapshotRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{11} + return file_v1_service_proto_rawDescGZIP(), []int{12} } func (x *RestoreSnapshotRequest) GetPlanId() string { @@ -838,7 +890,7 @@ type ListSnapshotFilesRequest struct { func (x *ListSnapshotFilesRequest) Reset() { *x = ListSnapshotFilesRequest{} - mi := &file_v1_service_proto_msgTypes[12] + mi := &file_v1_service_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -850,7 +902,7 @@ func (x *ListSnapshotFilesRequest) String() string { func (*ListSnapshotFilesRequest) ProtoMessage() {} func (x *ListSnapshotFilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[12] + mi := &file_v1_service_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -863,7 +915,7 @@ func (x *ListSnapshotFilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSnapshotFilesRequest.ProtoReflect.Descriptor instead. func (*ListSnapshotFilesRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{12} + return file_v1_service_proto_rawDescGZIP(), []int{13} } func (x *ListSnapshotFilesRequest) GetRepoGuid() string { @@ -897,7 +949,7 @@ type ListSnapshotFilesResponse struct { func (x *ListSnapshotFilesResponse) Reset() { *x = ListSnapshotFilesResponse{} - mi := &file_v1_service_proto_msgTypes[13] + mi := &file_v1_service_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -909,7 +961,7 @@ func (x *ListSnapshotFilesResponse) String() string { func (*ListSnapshotFilesResponse) ProtoMessage() {} func (x *ListSnapshotFilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[13] + mi := &file_v1_service_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -922,7 +974,7 @@ func (x *ListSnapshotFilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSnapshotFilesResponse.ProtoReflect.Descriptor instead. func (*ListSnapshotFilesResponse) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{13} + return file_v1_service_proto_rawDescGZIP(), []int{14} } func (x *ListSnapshotFilesResponse) GetPath() string { @@ -948,7 +1000,7 @@ type LogDataRequest struct { func (x *LogDataRequest) Reset() { *x = LogDataRequest{} - mi := &file_v1_service_proto_msgTypes[14] + mi := &file_v1_service_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -960,7 +1012,7 @@ func (x *LogDataRequest) String() string { func (*LogDataRequest) ProtoMessage() {} func (x *LogDataRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[14] + mi := &file_v1_service_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -973,7 +1025,7 @@ func (x *LogDataRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LogDataRequest.ProtoReflect.Descriptor instead. func (*LogDataRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{14} + return file_v1_service_proto_rawDescGZIP(), []int{15} } func (x *LogDataRequest) GetRef() string { @@ -993,7 +1045,7 @@ type GetDownloadURLRequest struct { func (x *GetDownloadURLRequest) Reset() { *x = GetDownloadURLRequest{} - mi := &file_v1_service_proto_msgTypes[15] + mi := &file_v1_service_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1005,7 +1057,7 @@ func (x *GetDownloadURLRequest) String() string { func (*GetDownloadURLRequest) ProtoMessage() {} func (x *GetDownloadURLRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[15] + mi := &file_v1_service_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1018,7 +1070,7 @@ func (x *GetDownloadURLRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDownloadURLRequest.ProtoReflect.Descriptor instead. func (*GetDownloadURLRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{15} + return file_v1_service_proto_rawDescGZIP(), []int{16} } func (x *GetDownloadURLRequest) GetOpId() int64 { @@ -1053,7 +1105,7 @@ type LsEntry struct { func (x *LsEntry) Reset() { *x = LsEntry{} - mi := &file_v1_service_proto_msgTypes[16] + mi := &file_v1_service_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1065,7 +1117,7 @@ func (x *LsEntry) String() string { func (*LsEntry) ProtoMessage() {} func (x *LsEntry) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[16] + mi := &file_v1_service_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1078,7 +1130,7 @@ func (x *LsEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use LsEntry.ProtoReflect.Descriptor instead. func (*LsEntry) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{16} + return file_v1_service_proto_rawDescGZIP(), []int{17} } func (x *LsEntry) GetName() string { @@ -1161,7 +1213,7 @@ type RunCommandRequest struct { func (x *RunCommandRequest) Reset() { *x = RunCommandRequest{} - mi := &file_v1_service_proto_msgTypes[17] + mi := &file_v1_service_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1173,7 +1225,7 @@ func (x *RunCommandRequest) String() string { func (*RunCommandRequest) ProtoMessage() {} func (x *RunCommandRequest) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[17] + mi := &file_v1_service_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1186,7 +1238,7 @@ func (x *RunCommandRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RunCommandRequest.ProtoReflect.Descriptor instead. func (*RunCommandRequest) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{17} + return file_v1_service_proto_rawDescGZIP(), []int{18} } func (x *RunCommandRequest) GetRepoId() string { @@ -1215,7 +1267,7 @@ type SummaryDashboardResponse struct { func (x *SummaryDashboardResponse) Reset() { *x = SummaryDashboardResponse{} - mi := &file_v1_service_proto_msgTypes[18] + mi := &file_v1_service_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1227,7 +1279,7 @@ func (x *SummaryDashboardResponse) String() string { func (*SummaryDashboardResponse) ProtoMessage() {} func (x *SummaryDashboardResponse) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[18] + mi := &file_v1_service_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1240,7 +1292,7 @@ func (x *SummaryDashboardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SummaryDashboardResponse.ProtoReflect.Descriptor instead. func (*SummaryDashboardResponse) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{18} + return file_v1_service_proto_rawDescGZIP(), []int{19} } func (x *SummaryDashboardResponse) GetRepoSummaries() []*SummaryDashboardResponse_Summary { @@ -1291,7 +1343,7 @@ type SummaryDashboardResponse_Summary struct { func (x *SummaryDashboardResponse_Summary) Reset() { *x = SummaryDashboardResponse_Summary{} - mi := &file_v1_service_proto_msgTypes[19] + mi := &file_v1_service_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1303,7 +1355,7 @@ func (x *SummaryDashboardResponse_Summary) String() string { func (*SummaryDashboardResponse_Summary) ProtoMessage() {} func (x *SummaryDashboardResponse_Summary) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[19] + mi := &file_v1_service_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1316,7 +1368,7 @@ func (x *SummaryDashboardResponse_Summary) ProtoReflect() protoreflect.Message { // Deprecated: Use SummaryDashboardResponse_Summary.ProtoReflect.Descriptor instead. func (*SummaryDashboardResponse_Summary) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{18, 0} + return file_v1_service_proto_rawDescGZIP(), []int{19, 0} } func (x *SummaryDashboardResponse_Summary) GetId() string { @@ -1409,7 +1461,7 @@ type SummaryDashboardResponse_BackupChart struct { func (x *SummaryDashboardResponse_BackupChart) Reset() { *x = SummaryDashboardResponse_BackupChart{} - mi := &file_v1_service_proto_msgTypes[20] + mi := &file_v1_service_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1421,7 +1473,7 @@ func (x *SummaryDashboardResponse_BackupChart) String() string { func (*SummaryDashboardResponse_BackupChart) ProtoMessage() {} func (x *SummaryDashboardResponse_BackupChart) ProtoReflect() protoreflect.Message { - mi := &file_v1_service_proto_msgTypes[20] + mi := &file_v1_service_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1434,7 +1486,7 @@ func (x *SummaryDashboardResponse_BackupChart) ProtoReflect() protoreflect.Messa // Deprecated: Use SummaryDashboardResponse_BackupChart.ProtoReflect.Descriptor instead. func (*SummaryDashboardResponse_BackupChart) Descriptor() ([]byte, []int) { - return file_v1_service_proto_rawDescGZIP(), []int{18, 1} + return file_v1_service_proto_rawDescGZIP(), []int{19, 1} } func (x *SummaryDashboardResponse_BackupChart) GetFlowId() []int64 { @@ -1476,7 +1528,10 @@ var File_v1_service_proto protoreflect.FileDescriptor const file_v1_service_proto_rawDesc = "" + "\n" + - "\x10v1/service.proto\x12\x02v1\x1a\x0fv1/config.proto\x1a\x0fv1/restic.proto\x1a\x13v1/operations.proto\x1a\x11types/value.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/api/annotations.proto\"\x97\x03\n" + + "\x10v1/service.proto\x12\x02v1\x1a\x0fv1/config.proto\x1a\x0fv1/restic.proto\x1a\x13v1/operations.proto\x1a\x11types/value.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/api/annotations.proto\">\n" + + "\rBackupRequest\x12\x14\n" + + "\x05value\x18\x01 \x01(\tR\x05value\x12\x17\n" + + "\adry_run\x18\x02 \x01(\bR\x06dryRun\"\x97\x03\n" + "\n" + "OpSelector\x12\x10\n" + "\x03ids\x18\x01 \x03(\x03R\x03ids\x12$\n" + @@ -1612,7 +1667,7 @@ const file_v1_service_proto_rawDesc = "" + "durationMs\x12+\n" + "\x06status\x18\x04 \x03(\x0e2\x13.v1.OperationStatusR\x06status\x12\x1f\n" + "\vbytes_added\x18\x05 \x03(\x03R\n" + - "bytesAdded2\x92\n" + + "bytesAdded2\x91\n" + "\n" + "\bBackrest\x121\n" + "\tGetConfig\x12\x16.google.protobuf.Empty\x1a\n" + @@ -1630,8 +1685,8 @@ const file_v1_service_proto_rawDesc = "" + "\x12GetOperationEvents\x12\x16.google.protobuf.Empty\x1a\x12.v1.OperationEvent\"\x000\x01\x12>\n" + "\rGetOperations\x12\x18.v1.GetOperationsRequest\x1a\x11.v1.OperationList\"\x00\x12C\n" + "\rListSnapshots\x12\x18.v1.ListSnapshotsRequest\x1a\x16.v1.ResticSnapshotList\"\x00\x12R\n" + - "\x11ListSnapshotFiles\x12\x1c.v1.ListSnapshotFilesRequest\x1a\x1d.v1.ListSnapshotFilesResponse\"\x00\x126\n" + - "\x06Backup\x12\x12.types.StringValue\x1a\x16.google.protobuf.Empty\"\x00\x12=\n" + + "\x11ListSnapshotFiles\x12\x1c.v1.ListSnapshotFilesRequest\x1a\x1d.v1.ListSnapshotFilesResponse\"\x00\x125\n" + + "\x06Backup\x12\x11.v1.BackupRequest\x1a\x16.google.protobuf.Empty\"\x00\x12=\n" + "\n" + "DoRepoTask\x12\x15.v1.DoRepoTaskRequest\x1a\x16.google.protobuf.Empty\"\x00\x125\n" + "\x06Forget\x12\x11.v1.ForgetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12?\n" + @@ -1658,95 +1713,96 @@ func file_v1_service_proto_rawDescGZIP() []byte { } var file_v1_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_v1_service_proto_goTypes = []any{ (DoRepoTaskRequest_Task)(0), // 0: v1.DoRepoTaskRequest.Task - (*OpSelector)(nil), // 1: v1.OpSelector - (*SetupSftpRequest)(nil), // 2: v1.SetupSftpRequest - (*SetupSftpResponse)(nil), // 3: v1.SetupSftpResponse - (*CheckRepoExistsRequest)(nil), // 4: v1.CheckRepoExistsRequest - (*CheckRepoExistsResponse)(nil), // 5: v1.CheckRepoExistsResponse - (*AddRepoRequest)(nil), // 6: v1.AddRepoRequest - (*DoRepoTaskRequest)(nil), // 7: v1.DoRepoTaskRequest - (*ClearHistoryRequest)(nil), // 8: v1.ClearHistoryRequest - (*ForgetRequest)(nil), // 9: v1.ForgetRequest - (*ListSnapshotsRequest)(nil), // 10: v1.ListSnapshotsRequest - (*GetOperationsRequest)(nil), // 11: v1.GetOperationsRequest - (*RestoreSnapshotRequest)(nil), // 12: v1.RestoreSnapshotRequest - (*ListSnapshotFilesRequest)(nil), // 13: v1.ListSnapshotFilesRequest - (*ListSnapshotFilesResponse)(nil), // 14: v1.ListSnapshotFilesResponse - (*LogDataRequest)(nil), // 15: v1.LogDataRequest - (*GetDownloadURLRequest)(nil), // 16: v1.GetDownloadURLRequest - (*LsEntry)(nil), // 17: v1.LsEntry - (*RunCommandRequest)(nil), // 18: v1.RunCommandRequest - (*SummaryDashboardResponse)(nil), // 19: v1.SummaryDashboardResponse - (*SummaryDashboardResponse_Summary)(nil), // 20: v1.SummaryDashboardResponse.Summary - (*SummaryDashboardResponse_BackupChart)(nil), // 21: v1.SummaryDashboardResponse.BackupChart - (*Repo)(nil), // 22: v1.Repo - (OperationStatus)(0), // 23: v1.OperationStatus - (*emptypb.Empty)(nil), // 24: google.protobuf.Empty - (*Config)(nil), // 25: v1.Config - (*types.StringValue)(nil), // 26: types.StringValue - (*types.Int64Value)(nil), // 27: types.Int64Value - (*OperationEvent)(nil), // 28: v1.OperationEvent - (*OperationList)(nil), // 29: v1.OperationList - (*ResticSnapshotList)(nil), // 30: v1.ResticSnapshotList - (*types.BytesValue)(nil), // 31: types.BytesValue - (*types.StringList)(nil), // 32: types.StringList + (*BackupRequest)(nil), // 1: v1.BackupRequest + (*OpSelector)(nil), // 2: v1.OpSelector + (*SetupSftpRequest)(nil), // 3: v1.SetupSftpRequest + (*SetupSftpResponse)(nil), // 4: v1.SetupSftpResponse + (*CheckRepoExistsRequest)(nil), // 5: v1.CheckRepoExistsRequest + (*CheckRepoExistsResponse)(nil), // 6: v1.CheckRepoExistsResponse + (*AddRepoRequest)(nil), // 7: v1.AddRepoRequest + (*DoRepoTaskRequest)(nil), // 8: v1.DoRepoTaskRequest + (*ClearHistoryRequest)(nil), // 9: v1.ClearHistoryRequest + (*ForgetRequest)(nil), // 10: v1.ForgetRequest + (*ListSnapshotsRequest)(nil), // 11: v1.ListSnapshotsRequest + (*GetOperationsRequest)(nil), // 12: v1.GetOperationsRequest + (*RestoreSnapshotRequest)(nil), // 13: v1.RestoreSnapshotRequest + (*ListSnapshotFilesRequest)(nil), // 14: v1.ListSnapshotFilesRequest + (*ListSnapshotFilesResponse)(nil), // 15: v1.ListSnapshotFilesResponse + (*LogDataRequest)(nil), // 16: v1.LogDataRequest + (*GetDownloadURLRequest)(nil), // 17: v1.GetDownloadURLRequest + (*LsEntry)(nil), // 18: v1.LsEntry + (*RunCommandRequest)(nil), // 19: v1.RunCommandRequest + (*SummaryDashboardResponse)(nil), // 20: v1.SummaryDashboardResponse + (*SummaryDashboardResponse_Summary)(nil), // 21: v1.SummaryDashboardResponse.Summary + (*SummaryDashboardResponse_BackupChart)(nil), // 22: v1.SummaryDashboardResponse.BackupChart + (*Repo)(nil), // 23: v1.Repo + (OperationStatus)(0), // 24: v1.OperationStatus + (*emptypb.Empty)(nil), // 25: google.protobuf.Empty + (*Config)(nil), // 26: v1.Config + (*types.StringValue)(nil), // 27: types.StringValue + (*types.Int64Value)(nil), // 28: types.Int64Value + (*OperationEvent)(nil), // 29: v1.OperationEvent + (*OperationList)(nil), // 30: v1.OperationList + (*ResticSnapshotList)(nil), // 31: v1.ResticSnapshotList + (*types.BytesValue)(nil), // 32: types.BytesValue + (*types.StringList)(nil), // 33: types.StringList } var file_v1_service_proto_depIdxs = []int32{ - 22, // 0: v1.CheckRepoExistsRequest.repo:type_name -> v1.Repo - 22, // 1: v1.AddRepoRequest.repo:type_name -> v1.Repo + 23, // 0: v1.CheckRepoExistsRequest.repo:type_name -> v1.Repo + 23, // 1: v1.AddRepoRequest.repo:type_name -> v1.Repo 0, // 2: v1.DoRepoTaskRequest.task:type_name -> v1.DoRepoTaskRequest.Task - 1, // 3: v1.ClearHistoryRequest.selector:type_name -> v1.OpSelector - 1, // 4: v1.GetOperationsRequest.selector:type_name -> v1.OpSelector - 17, // 5: v1.ListSnapshotFilesResponse.entries:type_name -> v1.LsEntry - 20, // 6: v1.SummaryDashboardResponse.repo_summaries:type_name -> v1.SummaryDashboardResponse.Summary - 20, // 7: v1.SummaryDashboardResponse.plan_summaries:type_name -> v1.SummaryDashboardResponse.Summary - 21, // 8: v1.SummaryDashboardResponse.Summary.recent_backups:type_name -> v1.SummaryDashboardResponse.BackupChart - 23, // 9: v1.SummaryDashboardResponse.BackupChart.status:type_name -> v1.OperationStatus - 24, // 10: v1.Backrest.GetConfig:input_type -> google.protobuf.Empty - 25, // 11: v1.Backrest.SetConfig:input_type -> v1.Config - 2, // 12: v1.Backrest.SetupSftp:input_type -> v1.SetupSftpRequest - 4, // 13: v1.Backrest.CheckRepoExists:input_type -> v1.CheckRepoExistsRequest - 6, // 14: v1.Backrest.AddRepo:input_type -> v1.AddRepoRequest - 26, // 15: v1.Backrest.RemoveRepo:input_type -> types.StringValue - 24, // 16: v1.Backrest.GetOperationEvents:input_type -> google.protobuf.Empty - 11, // 17: v1.Backrest.GetOperations:input_type -> v1.GetOperationsRequest - 10, // 18: v1.Backrest.ListSnapshots:input_type -> v1.ListSnapshotsRequest - 13, // 19: v1.Backrest.ListSnapshotFiles:input_type -> v1.ListSnapshotFilesRequest - 26, // 20: v1.Backrest.Backup:input_type -> types.StringValue - 7, // 21: v1.Backrest.DoRepoTask:input_type -> v1.DoRepoTaskRequest - 9, // 22: v1.Backrest.Forget:input_type -> v1.ForgetRequest - 12, // 23: v1.Backrest.Restore:input_type -> v1.RestoreSnapshotRequest - 27, // 24: v1.Backrest.Cancel:input_type -> types.Int64Value - 15, // 25: v1.Backrest.GetLogs:input_type -> v1.LogDataRequest - 18, // 26: v1.Backrest.RunCommand:input_type -> v1.RunCommandRequest - 16, // 27: v1.Backrest.GetDownloadURL:input_type -> v1.GetDownloadURLRequest - 8, // 28: v1.Backrest.ClearHistory:input_type -> v1.ClearHistoryRequest - 26, // 29: v1.Backrest.PathAutocomplete:input_type -> types.StringValue - 24, // 30: v1.Backrest.GetSummaryDashboard:input_type -> google.protobuf.Empty - 25, // 31: v1.Backrest.GetConfig:output_type -> v1.Config - 25, // 32: v1.Backrest.SetConfig:output_type -> v1.Config - 3, // 33: v1.Backrest.SetupSftp:output_type -> v1.SetupSftpResponse - 5, // 34: v1.Backrest.CheckRepoExists:output_type -> v1.CheckRepoExistsResponse - 25, // 35: v1.Backrest.AddRepo:output_type -> v1.Config - 25, // 36: v1.Backrest.RemoveRepo:output_type -> v1.Config - 28, // 37: v1.Backrest.GetOperationEvents:output_type -> v1.OperationEvent - 29, // 38: v1.Backrest.GetOperations:output_type -> v1.OperationList - 30, // 39: v1.Backrest.ListSnapshots:output_type -> v1.ResticSnapshotList - 14, // 40: v1.Backrest.ListSnapshotFiles:output_type -> v1.ListSnapshotFilesResponse - 24, // 41: v1.Backrest.Backup:output_type -> google.protobuf.Empty - 24, // 42: v1.Backrest.DoRepoTask:output_type -> google.protobuf.Empty - 24, // 43: v1.Backrest.Forget:output_type -> google.protobuf.Empty - 24, // 44: v1.Backrest.Restore:output_type -> google.protobuf.Empty - 24, // 45: v1.Backrest.Cancel:output_type -> google.protobuf.Empty - 31, // 46: v1.Backrest.GetLogs:output_type -> types.BytesValue - 27, // 47: v1.Backrest.RunCommand:output_type -> types.Int64Value - 26, // 48: v1.Backrest.GetDownloadURL:output_type -> types.StringValue - 24, // 49: v1.Backrest.ClearHistory:output_type -> google.protobuf.Empty - 32, // 50: v1.Backrest.PathAutocomplete:output_type -> types.StringList - 19, // 51: v1.Backrest.GetSummaryDashboard:output_type -> v1.SummaryDashboardResponse + 2, // 3: v1.ClearHistoryRequest.selector:type_name -> v1.OpSelector + 2, // 4: v1.GetOperationsRequest.selector:type_name -> v1.OpSelector + 18, // 5: v1.ListSnapshotFilesResponse.entries:type_name -> v1.LsEntry + 21, // 6: v1.SummaryDashboardResponse.repo_summaries:type_name -> v1.SummaryDashboardResponse.Summary + 21, // 7: v1.SummaryDashboardResponse.plan_summaries:type_name -> v1.SummaryDashboardResponse.Summary + 22, // 8: v1.SummaryDashboardResponse.Summary.recent_backups:type_name -> v1.SummaryDashboardResponse.BackupChart + 24, // 9: v1.SummaryDashboardResponse.BackupChart.status:type_name -> v1.OperationStatus + 25, // 10: v1.Backrest.GetConfig:input_type -> google.protobuf.Empty + 26, // 11: v1.Backrest.SetConfig:input_type -> v1.Config + 3, // 12: v1.Backrest.SetupSftp:input_type -> v1.SetupSftpRequest + 5, // 13: v1.Backrest.CheckRepoExists:input_type -> v1.CheckRepoExistsRequest + 7, // 14: v1.Backrest.AddRepo:input_type -> v1.AddRepoRequest + 27, // 15: v1.Backrest.RemoveRepo:input_type -> types.StringValue + 25, // 16: v1.Backrest.GetOperationEvents:input_type -> google.protobuf.Empty + 12, // 17: v1.Backrest.GetOperations:input_type -> v1.GetOperationsRequest + 11, // 18: v1.Backrest.ListSnapshots:input_type -> v1.ListSnapshotsRequest + 14, // 19: v1.Backrest.ListSnapshotFiles:input_type -> v1.ListSnapshotFilesRequest + 1, // 20: v1.Backrest.Backup:input_type -> v1.BackupRequest + 8, // 21: v1.Backrest.DoRepoTask:input_type -> v1.DoRepoTaskRequest + 10, // 22: v1.Backrest.Forget:input_type -> v1.ForgetRequest + 13, // 23: v1.Backrest.Restore:input_type -> v1.RestoreSnapshotRequest + 28, // 24: v1.Backrest.Cancel:input_type -> types.Int64Value + 16, // 25: v1.Backrest.GetLogs:input_type -> v1.LogDataRequest + 19, // 26: v1.Backrest.RunCommand:input_type -> v1.RunCommandRequest + 17, // 27: v1.Backrest.GetDownloadURL:input_type -> v1.GetDownloadURLRequest + 9, // 28: v1.Backrest.ClearHistory:input_type -> v1.ClearHistoryRequest + 27, // 29: v1.Backrest.PathAutocomplete:input_type -> types.StringValue + 25, // 30: v1.Backrest.GetSummaryDashboard:input_type -> google.protobuf.Empty + 26, // 31: v1.Backrest.GetConfig:output_type -> v1.Config + 26, // 32: v1.Backrest.SetConfig:output_type -> v1.Config + 4, // 33: v1.Backrest.SetupSftp:output_type -> v1.SetupSftpResponse + 6, // 34: v1.Backrest.CheckRepoExists:output_type -> v1.CheckRepoExistsResponse + 26, // 35: v1.Backrest.AddRepo:output_type -> v1.Config + 26, // 36: v1.Backrest.RemoveRepo:output_type -> v1.Config + 29, // 37: v1.Backrest.GetOperationEvents:output_type -> v1.OperationEvent + 30, // 38: v1.Backrest.GetOperations:output_type -> v1.OperationList + 31, // 39: v1.Backrest.ListSnapshots:output_type -> v1.ResticSnapshotList + 15, // 40: v1.Backrest.ListSnapshotFiles:output_type -> v1.ListSnapshotFilesResponse + 25, // 41: v1.Backrest.Backup:output_type -> google.protobuf.Empty + 25, // 42: v1.Backrest.DoRepoTask:output_type -> google.protobuf.Empty + 25, // 43: v1.Backrest.Forget:output_type -> google.protobuf.Empty + 25, // 44: v1.Backrest.Restore:output_type -> google.protobuf.Empty + 25, // 45: v1.Backrest.Cancel:output_type -> google.protobuf.Empty + 32, // 46: v1.Backrest.GetLogs:output_type -> types.BytesValue + 28, // 47: v1.Backrest.RunCommand:output_type -> types.Int64Value + 27, // 48: v1.Backrest.GetDownloadURL:output_type -> types.StringValue + 25, // 49: v1.Backrest.ClearHistory:output_type -> google.protobuf.Empty + 33, // 50: v1.Backrest.PathAutocomplete:output_type -> types.StringList + 20, // 51: v1.Backrest.GetSummaryDashboard:output_type -> v1.SummaryDashboardResponse 31, // [31:52] is the sub-list for method output_type 10, // [10:31] is the sub-list for method input_type 10, // [10:10] is the sub-list for extension type_name @@ -1762,15 +1818,15 @@ func file_v1_service_proto_init() { file_v1_config_proto_init() file_v1_restic_proto_init() file_v1_operations_proto_init() - file_v1_service_proto_msgTypes[0].OneofWrappers = []any{} file_v1_service_proto_msgTypes[1].OneofWrappers = []any{} + file_v1_service_proto_msgTypes[2].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_v1_service_proto_rawDesc), len(file_v1_service_proto_rawDesc)), NumEnums: 1, - NumMessages: 21, + NumMessages: 22, NumExtensions: 0, NumServices: 1, }, diff --git a/gen/go/v1/service_grpc.pb.go b/gen/go/v1/service_grpc.pb.go index 28afdce4..27884e16 100644 --- a/gen/go/v1/service_grpc.pb.go +++ b/gen/go/v1/service_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 +// - protoc-gen-go-grpc v1.6.0 // - protoc (unknown) // source: v1/service.proto @@ -59,7 +59,7 @@ type BackrestClient interface { ListSnapshots(ctx context.Context, in *ListSnapshotsRequest, opts ...grpc.CallOption) (*ResticSnapshotList, error) ListSnapshotFiles(ctx context.Context, in *ListSnapshotFilesRequest, opts ...grpc.CallOption) (*ListSnapshotFilesResponse, error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. - Backup(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + Backup(ctx context.Context, in *BackupRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. DoRepoTask(ctx context.Context, in *DoRepoTaskRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. @@ -199,7 +199,7 @@ func (c *backrestClient) ListSnapshotFiles(ctx context.Context, in *ListSnapshot return out, nil } -func (c *backrestClient) Backup(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *backrestClient) Backup(ctx context.Context, in *BackupRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) err := c.cc.Invoke(ctx, Backrest_Backup_FullMethodName, in, out, cOpts...) @@ -333,7 +333,7 @@ type BackrestServer interface { ListSnapshots(context.Context, *ListSnapshotsRequest) (*ResticSnapshotList, error) ListSnapshotFiles(context.Context, *ListSnapshotFilesRequest) (*ListSnapshotFilesResponse, error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. - Backup(context.Context, *types.StringValue) (*emptypb.Empty, error) + Backup(context.Context, *BackupRequest) (*emptypb.Empty, error) // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. DoRepoTask(context.Context, *DoRepoTaskRequest) (*emptypb.Empty, error) // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. @@ -365,67 +365,67 @@ type BackrestServer interface { type UnimplementedBackrestServer struct{} func (UnimplementedBackrestServer) GetConfig(context.Context, *emptypb.Empty) (*Config, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetConfig not implemented") + return nil, status.Error(codes.Unimplemented, "method GetConfig not implemented") } func (UnimplementedBackrestServer) SetConfig(context.Context, *Config) (*Config, error) { - return nil, status.Errorf(codes.Unimplemented, "method SetConfig not implemented") + return nil, status.Error(codes.Unimplemented, "method SetConfig not implemented") } func (UnimplementedBackrestServer) SetupSftp(context.Context, *SetupSftpRequest) (*SetupSftpResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SetupSftp not implemented") + return nil, status.Error(codes.Unimplemented, "method SetupSftp not implemented") } func (UnimplementedBackrestServer) CheckRepoExists(context.Context, *CheckRepoExistsRequest) (*CheckRepoExistsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CheckRepoExists not implemented") + return nil, status.Error(codes.Unimplemented, "method CheckRepoExists not implemented") } func (UnimplementedBackrestServer) AddRepo(context.Context, *AddRepoRequest) (*Config, error) { - return nil, status.Errorf(codes.Unimplemented, "method AddRepo not implemented") + return nil, status.Error(codes.Unimplemented, "method AddRepo not implemented") } func (UnimplementedBackrestServer) RemoveRepo(context.Context, *types.StringValue) (*Config, error) { - return nil, status.Errorf(codes.Unimplemented, "method RemoveRepo not implemented") + return nil, status.Error(codes.Unimplemented, "method RemoveRepo not implemented") } func (UnimplementedBackrestServer) GetOperationEvents(*emptypb.Empty, grpc.ServerStreamingServer[OperationEvent]) error { - return status.Errorf(codes.Unimplemented, "method GetOperationEvents not implemented") + return status.Error(codes.Unimplemented, "method GetOperationEvents not implemented") } func (UnimplementedBackrestServer) GetOperations(context.Context, *GetOperationsRequest) (*OperationList, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetOperations not implemented") + return nil, status.Error(codes.Unimplemented, "method GetOperations not implemented") } func (UnimplementedBackrestServer) ListSnapshots(context.Context, *ListSnapshotsRequest) (*ResticSnapshotList, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListSnapshots not implemented") + return nil, status.Error(codes.Unimplemented, "method ListSnapshots not implemented") } func (UnimplementedBackrestServer) ListSnapshotFiles(context.Context, *ListSnapshotFilesRequest) (*ListSnapshotFilesResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListSnapshotFiles not implemented") + return nil, status.Error(codes.Unimplemented, "method ListSnapshotFiles not implemented") } -func (UnimplementedBackrestServer) Backup(context.Context, *types.StringValue) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Backup not implemented") +func (UnimplementedBackrestServer) Backup(context.Context, *BackupRequest) (*emptypb.Empty, error) { + return nil, status.Error(codes.Unimplemented, "method Backup not implemented") } func (UnimplementedBackrestServer) DoRepoTask(context.Context, *DoRepoTaskRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method DoRepoTask not implemented") + return nil, status.Error(codes.Unimplemented, "method DoRepoTask not implemented") } func (UnimplementedBackrestServer) Forget(context.Context, *ForgetRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Forget not implemented") + return nil, status.Error(codes.Unimplemented, "method Forget not implemented") } func (UnimplementedBackrestServer) Restore(context.Context, *RestoreSnapshotRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Restore not implemented") + return nil, status.Error(codes.Unimplemented, "method Restore not implemented") } func (UnimplementedBackrestServer) Cancel(context.Context, *types.Int64Value) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Cancel not implemented") + return nil, status.Error(codes.Unimplemented, "method Cancel not implemented") } func (UnimplementedBackrestServer) GetLogs(*LogDataRequest, grpc.ServerStreamingServer[types.BytesValue]) error { - return status.Errorf(codes.Unimplemented, "method GetLogs not implemented") + return status.Error(codes.Unimplemented, "method GetLogs not implemented") } func (UnimplementedBackrestServer) RunCommand(context.Context, *RunCommandRequest) (*types.Int64Value, error) { - return nil, status.Errorf(codes.Unimplemented, "method RunCommand not implemented") + return nil, status.Error(codes.Unimplemented, "method RunCommand not implemented") } func (UnimplementedBackrestServer) GetDownloadURL(context.Context, *GetDownloadURLRequest) (*types.StringValue, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetDownloadURL not implemented") + return nil, status.Error(codes.Unimplemented, "method GetDownloadURL not implemented") } func (UnimplementedBackrestServer) ClearHistory(context.Context, *ClearHistoryRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method ClearHistory not implemented") + return nil, status.Error(codes.Unimplemented, "method ClearHistory not implemented") } func (UnimplementedBackrestServer) PathAutocomplete(context.Context, *types.StringValue) (*types.StringList, error) { - return nil, status.Errorf(codes.Unimplemented, "method PathAutocomplete not implemented") + return nil, status.Error(codes.Unimplemented, "method PathAutocomplete not implemented") } func (UnimplementedBackrestServer) GetSummaryDashboard(context.Context, *emptypb.Empty) (*SummaryDashboardResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetSummaryDashboard not implemented") + return nil, status.Error(codes.Unimplemented, "method GetSummaryDashboard not implemented") } func (UnimplementedBackrestServer) mustEmbedUnimplementedBackrestServer() {} func (UnimplementedBackrestServer) testEmbeddedByValue() {} @@ -438,7 +438,7 @@ type UnsafeBackrestServer interface { } func RegisterBackrestServer(s grpc.ServiceRegistrar, srv BackrestServer) { - // If the following call pancis, it indicates UnimplementedBackrestServer was + // If the following call panics, it indicates UnimplementedBackrestServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. @@ -622,7 +622,7 @@ func _Backrest_ListSnapshotFiles_Handler(srv interface{}, ctx context.Context, d } func _Backrest_Backup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(types.StringValue) + in := new(BackupRequest) if err := dec(in); err != nil { return nil, err } @@ -634,7 +634,7 @@ func _Backrest_Backup_Handler(srv interface{}, ctx context.Context, dec func(int FullMethod: Backrest_Backup_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BackrestServer).Backup(ctx, req.(*types.StringValue)) + return srv.(BackrestServer).Backup(ctx, req.(*BackupRequest)) } return interceptor(ctx, in, info, handler) } diff --git a/gen/go/v1/v1connect/service.connect.go b/gen/go/v1/v1connect/service.connect.go index 861db9a4..34efcc24 100644 --- a/gen/go/v1/v1connect/service.connect.go +++ b/gen/go/v1/v1connect/service.connect.go @@ -97,7 +97,7 @@ type BackrestClient interface { ListSnapshots(context.Context, *connect.Request[v1.ListSnapshotsRequest]) (*connect.Response[v1.ResticSnapshotList], error) ListSnapshotFiles(context.Context, *connect.Request[v1.ListSnapshotFilesRequest]) (*connect.Response[v1.ListSnapshotFilesResponse], error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. - Backup(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) + Backup(context.Context, *connect.Request[v1.BackupRequest]) (*connect.Response[emptypb.Empty], error) // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. DoRepoTask(context.Context, *connect.Request[v1.DoRepoTaskRequest]) (*connect.Response[emptypb.Empty], error) // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. @@ -191,7 +191,7 @@ func NewBackrestClient(httpClient connect.HTTPClient, baseURL string, opts ...co connect.WithSchema(backrestMethods.ByName("ListSnapshotFiles")), connect.WithClientOptions(opts...), ), - backup: connect.NewClient[types.StringValue, emptypb.Empty]( + backup: connect.NewClient[v1.BackupRequest, emptypb.Empty]( httpClient, baseURL+BackrestBackupProcedure, connect.WithSchema(backrestMethods.ByName("Backup")), @@ -272,7 +272,7 @@ type backrestClient struct { getOperations *connect.Client[v1.GetOperationsRequest, v1.OperationList] listSnapshots *connect.Client[v1.ListSnapshotsRequest, v1.ResticSnapshotList] listSnapshotFiles *connect.Client[v1.ListSnapshotFilesRequest, v1.ListSnapshotFilesResponse] - backup *connect.Client[types.StringValue, emptypb.Empty] + backup *connect.Client[v1.BackupRequest, emptypb.Empty] doRepoTask *connect.Client[v1.DoRepoTaskRequest, emptypb.Empty] forget *connect.Client[v1.ForgetRequest, emptypb.Empty] restore *connect.Client[v1.RestoreSnapshotRequest, emptypb.Empty] @@ -336,7 +336,7 @@ func (c *backrestClient) ListSnapshotFiles(ctx context.Context, req *connect.Req } // Backup calls v1.Backrest.Backup. -func (c *backrestClient) Backup(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { +func (c *backrestClient) Backup(ctx context.Context, req *connect.Request[v1.BackupRequest]) (*connect.Response[emptypb.Empty], error) { return c.backup.CallUnary(ctx, req) } @@ -403,7 +403,7 @@ type BackrestHandler interface { ListSnapshots(context.Context, *connect.Request[v1.ListSnapshotsRequest]) (*connect.Response[v1.ResticSnapshotList], error) ListSnapshotFiles(context.Context, *connect.Request[v1.ListSnapshotFilesRequest]) (*connect.Response[v1.ListSnapshotFilesResponse], error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. - Backup(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) + Backup(context.Context, *connect.Request[v1.BackupRequest]) (*connect.Response[emptypb.Empty], error) // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. DoRepoTask(context.Context, *connect.Request[v1.DoRepoTaskRequest]) (*connect.Response[emptypb.Empty], error) // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. @@ -652,7 +652,7 @@ func (UnimplementedBackrestHandler) ListSnapshotFiles(context.Context, *connect. return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.ListSnapshotFiles is not implemented")) } -func (UnimplementedBackrestHandler) Backup(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { +func (UnimplementedBackrestHandler) Backup(context.Context, *connect.Request[v1.BackupRequest]) (*connect.Response[emptypb.Empty], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.Backup is not implemented")) } diff --git a/gen/go/v1sync/syncservice.pb.go b/gen/go/v1sync/syncservice.pb.go index 33251c06..59041e8a 100644 --- a/gen/go/v1sync/syncservice.pb.go +++ b/gen/go/v1sync/syncservice.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc (unknown) // source: v1sync/syncservice.proto diff --git a/gen/go/v1sync/syncservice_grpc.pb.go b/gen/go/v1sync/syncservice_grpc.pb.go index b445c78f..c2f1d94b 100644 --- a/gen/go/v1sync/syncservice_grpc.pb.go +++ b/gen/go/v1sync/syncservice_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.5.1 +// - protoc-gen-go-grpc v1.6.0 // - protoc (unknown) // source: v1sync/syncservice.proto @@ -72,7 +72,7 @@ type BackrestSyncServiceServer interface { type UnimplementedBackrestSyncServiceServer struct{} func (UnimplementedBackrestSyncServiceServer) Sync(grpc.BidiStreamingServer[SyncStreamItem, SyncStreamItem]) error { - return status.Errorf(codes.Unimplemented, "method Sync not implemented") + return status.Error(codes.Unimplemented, "method Sync not implemented") } func (UnimplementedBackrestSyncServiceServer) mustEmbedUnimplementedBackrestSyncServiceServer() {} func (UnimplementedBackrestSyncServiceServer) testEmbeddedByValue() {} @@ -85,7 +85,7 @@ type UnsafeBackrestSyncServiceServer interface { } func RegisterBackrestSyncServiceServer(s grpc.ServiceRegistrar, srv BackrestSyncServiceServer) { - // If the following call pancis, it indicates UnimplementedBackrestSyncServiceServer was + // If the following call panics, it indicates UnimplementedBackrestSyncServiceServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. @@ -180,7 +180,7 @@ type BackrestSyncStateServiceServer interface { type UnimplementedBackrestSyncStateServiceServer struct{} func (UnimplementedBackrestSyncStateServiceServer) GetPeerSyncStatesStream(*SyncStateStreamRequest, grpc.ServerStreamingServer[PeerState]) error { - return status.Errorf(codes.Unimplemented, "method GetPeerSyncStatesStream not implemented") + return status.Error(codes.Unimplemented, "method GetPeerSyncStatesStream not implemented") } func (UnimplementedBackrestSyncStateServiceServer) mustEmbedUnimplementedBackrestSyncStateServiceServer() { } @@ -194,7 +194,7 @@ type UnsafeBackrestSyncStateServiceServer interface { } func RegisterBackrestSyncStateServiceServer(s grpc.ServiceRegistrar, srv BackrestSyncStateServiceServer) { - // If the following call pancis, it indicates UnimplementedBackrestSyncStateServiceServer was + // If the following call panics, it indicates UnimplementedBackrestSyncStateServiceServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. diff --git a/internal/api/backresthandler.go b/internal/api/backresthandler.go index e4f6c87d..28d39893 100644 --- a/internal/api/backresthandler.go +++ b/internal/api/backresthandler.go @@ -640,7 +640,7 @@ func (s *BackrestHandler) IndexSnapshots(ctx context.Context, req *connect.Reque return connect.NewResponse(&emptypb.Empty{}), nil } -func (s *BackrestHandler) Backup(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { +func (s *BackrestHandler) Backup(ctx context.Context, req *connect.Request[v1.BackupRequest]) (*connect.Response[emptypb.Empty], error) { plan, err := s.orchestrator.GetPlan(req.Msg.Value) if err != nil { return nil, err @@ -650,7 +650,7 @@ func (s *BackrestHandler) Backup(ctx context.Context, req *connect.Request[types return nil, err } wait := make(chan struct{}) - if err := s.orchestrator.ScheduleTask(tasks.NewOneoffBackupTask(repo, plan, time.Now()), tasks.TaskPriorityInteractive, func(e error) { + if err := s.orchestrator.ScheduleTask(tasks.NewOneoffBackupTask(repo, plan, time.Now(), req.Msg.DryRun), tasks.TaskPriorityInteractive, func(e error) { err = e close(wait) }); err != nil { diff --git a/internal/api/backresthandler_test.go b/internal/api/backresthandler_test.go index 07df9560..78e42cae 100644 --- a/internal/api/backresthandler_test.go +++ b/internal/api/backresthandler_test.go @@ -190,7 +190,7 @@ func TestBackup(t *testing.T) { sut.orch.Run(ctx) }() - _, err := sut.handler.Backup(ctx, connect.NewRequest(&types.StringValue{Value: "test"})) + _, err := sut.handler.Backup(ctx, connect.NewRequest(&v1.BackupRequest{Value: "test"})) if err != nil { t.Fatalf("Backup() error = %v", err) } @@ -291,7 +291,7 @@ func TestMultipleBackup(t *testing.T) { }() for i := 0; i < 2; i++ { - _, err := sut.handler.Backup(ctx, connect.NewRequest(&types.StringValue{Value: "test"})) + _, err := sut.handler.Backup(ctx, connect.NewRequest(&v1.BackupRequest{Value: "test"})) if err != nil { t.Fatalf("Backup() error = %v", err) } @@ -382,7 +382,7 @@ func TestHookExecution(t *testing.T) { sut.orch.Run(ctx) }() - _, err := sut.handler.Backup(ctx, connect.NewRequest(&types.StringValue{Value: "test"})) + _, err := sut.handler.Backup(ctx, connect.NewRequest(&v1.BackupRequest{Value: "test"})) if err != nil { t.Fatalf("Backup() error = %v", err) } @@ -580,7 +580,7 @@ func TestHookOnErrorHandling(t *testing.T) { var errgroup errgroup.Group errgroup.Go(func() error { - _, err := sut.handler.Backup(context.Background(), connect.NewRequest(&types.StringValue{Value: tc.plan})) + _, err := sut.handler.Backup(context.Background(), connect.NewRequest(&v1.BackupRequest{Value: tc.plan})) if (err != nil) != tc.wantBackupError { return fmt.Errorf("Backup() error = %v, wantErr %v", err, tc.wantBackupError) } @@ -689,7 +689,7 @@ func TestCancelBackup(t *testing.T) { }() go func() { - backupReq := &types.StringValue{Value: "test"} + backupReq := &v1.BackupRequest{Value: "test"} _, err := sut.handler.Backup(ctx, connect.NewRequest(backupReq)) if err != nil { t.Logf("Backup() error = %v", err) @@ -772,7 +772,7 @@ func TestRestore(t *testing.T) { sut.orch.Run(ctx) }() - _, err := sut.handler.Backup(ctx, connect.NewRequest(&types.StringValue{Value: "test"})) + _, err := sut.handler.Backup(ctx, connect.NewRequest(&v1.BackupRequest{Value: "test"})) if err != nil { t.Fatalf("Backup() error = %v", err) } @@ -985,8 +985,8 @@ func TestMultihostIndexSnapshots(t *testing.T) { host2.orch.Run(ctx) }() - host1.handler.Backup(context.Background(), connect.NewRequest(&types.StringValue{Value: "test1"})) - host2.handler.Backup(context.Background(), connect.NewRequest(&types.StringValue{Value: "test2"})) + host1.handler.Backup(context.Background(), connect.NewRequest(&v1.BackupRequest{Value: "test1"})) + host2.handler.Backup(context.Background(), connect.NewRequest(&v1.BackupRequest{Value: "test2"})) for i := 0; i < 1; i++ { if _, err := host1.handler.IndexSnapshots(context.Background(), connect.NewRequest(&types.StringValue{Value: "local1"})); err != nil { diff --git a/internal/orchestrator/repo/repo.go b/internal/orchestrator/repo/repo.go index 2ecba5df..fbc303c5 100644 --- a/internal/orchestrator/repo/repo.go +++ b/internal/orchestrator/repo/repo.go @@ -126,7 +126,7 @@ func (r *RepoOrchestrator) SnapshotsForPlan(ctx context.Context, plan *v1.Plan) return snapshots, nil } -func (r *RepoOrchestrator) Backup(ctx context.Context, plan *v1.Plan, progressCallback func(event *restic.BackupProgressEntry)) (*restic.BackupProgressEntry, error) { +func (r *RepoOrchestrator) Backup(ctx context.Context, plan *v1.Plan, dryRun bool, progressCallback func(event *restic.BackupProgressEntry)) (*restic.BackupProgressEntry, error) { l := r.logger(ctx) l.Debug("repo orchestrator starting backup", zap.String("repo", r.repoConfig.Id)) @@ -172,6 +172,10 @@ func (r *RepoOrchestrator) Backup(ctx context.Context, plan *v1.Plan, progressCa opts = append(opts, restic.WithFlags(args...)) } + if dryRun { + opts = append(opts, restic.WithFlags("--dry-run", "-vv")) + } + ctx, flush := forwardResticLogs(ctx) defer flush() l.Debug("starting backup", zap.String("plan", plan.Id)) diff --git a/internal/orchestrator/repo/repo_test.go b/internal/orchestrator/repo/repo_test.go index ab1c85f9..35b03bab 100644 --- a/internal/orchestrator/repo/repo_test.go +++ b/internal/orchestrator/repo/repo_test.go @@ -78,7 +78,7 @@ func TestBackup(t *testing.T) { orchestrator := initRepoHelper(t, configForTest, tc.repo) - summary, err := orchestrator.Backup(context.Background(), tc.plan, nil) + summary, err := orchestrator.Backup(context.Background(), tc.plan, false, nil) if err != nil { t.Fatalf("backup error: %v", err) } @@ -124,7 +124,7 @@ func TestRestore(t *testing.T) { orchestrator := initRepoHelper(t, configForTest, r) // Create a backup of the single file - summary, err := orchestrator.Backup(context.Background(), plan, nil) + summary, err := orchestrator.Backup(context.Background(), plan, false, nil) if err != nil { t.Fatalf("backup error: %v", err) } @@ -202,7 +202,7 @@ func TestSnapshotParenting(t *testing.T) { for _, plan := range plans { eg.Go(func() error { for i := 0; i < 2; i++ { - summary, err := orchestrator.Backup(context.Background(), plan, nil) + summary, err := orchestrator.Backup(context.Background(), plan, false, nil) if err != nil { return fmt.Errorf("failed to backup plan %s: %v", plan.Id, err) } @@ -407,7 +407,7 @@ func TestRestoreAmbiguity(t *testing.T) { orchestrator := initRepoHelper(t, configForTest, r) - summary, err := orchestrator.Backup(context.Background(), plan, nil) + summary, err := orchestrator.Backup(context.Background(), plan, false, nil) if err != nil { t.Fatalf("backup error: %v", err) } diff --git a/internal/orchestrator/tasks/taskbackup.go b/internal/orchestrator/tasks/taskbackup.go index 8951eae6..1de1c03f 100644 --- a/internal/orchestrator/tasks/taskbackup.go +++ b/internal/orchestrator/tasks/taskbackup.go @@ -22,6 +22,7 @@ var maxBackupErrorHistoryLength = 20 // arbitrary limit on the number of file re type BackupTask struct { BaseTask force bool + dryRun bool didRun bool } @@ -38,7 +39,7 @@ func NewScheduledBackupTask(repo *v1.Repo, plan *v1.Plan) *BackupTask { } } -func NewOneoffBackupTask(repo *v1.Repo, plan *v1.Plan, at time.Time) *BackupTask { +func NewOneoffBackupTask(repo *v1.Repo, plan *v1.Plan, at time.Time, dryRun bool) *BackupTask { return &BackupTask{ BaseTask: BaseTask{ TaskType: "backup", @@ -46,7 +47,8 @@ func NewOneoffBackupTask(repo *v1.Repo, plan *v1.Plan, at time.Time) *BackupTask TaskRepo: repo, TaskPlanID: plan.Id, }, - force: true, + force: true, + dryRun: dryRun, } } @@ -60,7 +62,11 @@ func (t *BackupTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, erro Task: t, RunAt: now, Op: &v1.Operation{ - Op: &v1.Operation_OperationBackup{}, + Op: &v1.Operation_OperationBackup{ + OperationBackup: &v1.OperationBackup{ + DryRun: t.dryRun, + }, + }, }, }, nil } @@ -83,7 +89,7 @@ func (t *BackupTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, erro if op.Status == v1.OperationStatus_STATUS_PENDING || op.Status == v1.OperationStatus_STATUS_SYSTEM_CANCELLED { return nil } - if _, ok := op.Op.(*v1.Operation_OperationBackup); ok && op.UnixTimeEndMs != 0 { + if backup, ok := op.Op.(*v1.Operation_OperationBackup); ok && op.UnixTimeEndMs != 0 && !backup.OperationBackup.DryRun { lastRan = time.Unix(0, op.UnixTimeEndMs*int64(time.Millisecond)) return oplog.ErrStopIteration } @@ -105,7 +111,11 @@ func (t *BackupTask) Next(now time.Time, runner TaskRunner) (ScheduledTask, erro Task: t, RunAt: nextRun, Op: &v1.Operation{ - Op: &v1.Operation_OperationBackup{}, + Op: &v1.Operation_OperationBackup{ + OperationBackup: &v1.OperationBackup{ + DryRun: t.dryRun, + }, + }, }, }, nil } @@ -116,7 +126,9 @@ func (t *BackupTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunne startTime := time.Now() op := st.Op backupOp := &v1.Operation_OperationBackup{ - OperationBackup: &v1.OperationBackup{}, + OperationBackup: &v1.OperationBackup{ + DryRun: t.dryRun, + }, } op.Op = backupOp @@ -149,7 +161,7 @@ func (t *BackupTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunne lastSent := time.Now() // debounce progress updates, these can endup being very frequent. var lastFiles []string fileErrorCount := 0 - summary, err := repo.Backup(ctx, plan, func(entry *restic.BackupProgressEntry) { + summary, err := repo.Backup(ctx, plan, t.dryRun, func(entry *restic.BackupProgressEntry) { sendWg.Wait() if entry.MessageType == "status" { // prevents flickering output when a status entry omits the CurrentFiles property. Largely cosmetic. @@ -198,8 +210,6 @@ func (t *BackupTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunne summary = &restic.BackupProgressEntry{} } - metric.GetRegistry().RecordBackupSummary(t.RepoID(), t.PlanID(), summary.TotalBytesProcessed, summary.DataAdded, int64(fileErrorCount)) - vars := HookVars{ Task: t.Name(), SnapshotStats: summary, @@ -232,11 +242,27 @@ func (t *BackupTask) Run(ctx context.Context, st ScheduledTask, runner TaskRunne l.Info("backup complete", zap.String("plan", plan.Id), zap.Duration("duration", time.Since(startTime)), zap.Any("summary", backupOp.OperationBackup.LastStatus)) - if summary.SnapshotId == "" { // support --skip-if-unchanged which returns an operation with an empty snapshot ID - op.DisplayMessage = "No snapshot added, possibly due to no changes in the source data." + // Handle dry run - set display message and clear snapshot ID to prevent GC + if t.dryRun { + op.DisplayMessage = "Dry run backup, not saved in repo" + op.SnapshotId = "" + } + // Skip metrics for dry runs - no real data backed up + if !t.dryRun { + metric.GetRegistry().RecordBackupSummary(t.RepoID(), t.PlanID(), summary.TotalBytesProcessed, summary.DataAdded, int64(fileErrorCount)) + } + + // Determine if we should skip follow-up tasks + skipFollowUpTasks := summary.SnapshotId == "" || t.dryRun + + if summary.SnapshotId == "" && !t.dryRun { + // --skip-if-unchanged case: no changes in source data + op.DisplayMessage = "No snapshot added, possibly due to no changes in the source data." conditions = append(conditions, v1.Hook_CONDITION_SNAPSHOT_SKIPPED) - } else { + } + + if !skipFollowUpTasks { // schedule followup tasks if a snapshot was added at := time.Now() if _, ok := plan.Retention.GetPolicy().(*v1.RetentionPolicy_PolicyKeepAll); plan.Retention != nil && !ok { diff --git a/proto/v1/operations.proto b/proto/v1/operations.proto index 4fc00ec7..0932b848 100644 --- a/proto/v1/operations.proto +++ b/proto/v1/operations.proto @@ -89,6 +89,7 @@ enum OperationStatus { message OperationBackup { BackupProgressEntry last_status = 3; repeated BackupProgressError errors = 4; + bool dry_run = 5; // indicates this was a dry run backup (no snapshot created) } // OperationIndexSnapshot tracks that a snapshot was detected by backrest. diff --git a/proto/v1/service.proto b/proto/v1/service.proto index dc0f08d4..3a7f6af5 100644 --- a/proto/v1/service.proto +++ b/proto/v1/service.proto @@ -11,6 +11,11 @@ import "types/value.proto"; import "google/protobuf/empty.proto"; import "google/api/annotations.proto"; +message BackupRequest { + string value = 1; // plan_id - named 'value' for curl script backwards compatibility + bool dry_run = 2; // optional, simulate backup without creating snapshot +} + service Backrest { rpc GetConfig (google.protobuf.Empty) returns (Config) {} @@ -33,7 +38,7 @@ service Backrest { rpc ListSnapshotFiles(ListSnapshotFilesRequest) returns (ListSnapshotFilesResponse) {} // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. - rpc Backup(types.StringValue) returns (google.protobuf.Empty) {} + rpc Backup(BackupRequest) returns (google.protobuf.Empty) {} // DoRepoTask schedules a repo task. It accepts a repo id and a task type and returns empty if the task is enqueued. rpc DoRepoTask(DoRepoTaskRequest) returns (google.protobuf.Empty) {} diff --git a/test/e2e/first_run_test.go b/test/e2e/first_run_test.go index 5d547462..1e19ad34 100644 --- a/test/e2e/first_run_test.go +++ b/test/e2e/first_run_test.go @@ -12,7 +12,6 @@ import ( "time" "connectrpc.com/connect" - "github.com/garethgeorge/backrest/gen/go/types" v1 "github.com/garethgeorge/backrest/gen/go/v1" "github.com/garethgeorge/backrest/gen/go/v1/v1connect" "github.com/garethgeorge/backrest/internal/testutil" @@ -159,7 +158,7 @@ func TestFirstRun(t *testing.T) { http.DefaultClient, fmt.Sprintf("http://%s", addr), ) - _, err := client.Backup(context.Background(), connect.NewRequest(&types.StringValue{ + _, err := client.Backup(context.Background(), connect.NewRequest(&v1.BackupRequest{ Value: "test-plan", })) if err != nil { diff --git a/webui/gen/ts/google/api/annotations_pb.ts b/webui/gen/ts/google/api/annotations_pb.ts index 405b7c1a..0735d598 100644 --- a/webui/gen/ts/google/api/annotations_pb.ts +++ b/webui/gen/ts/google/api/annotations_pb.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file google/api/annotations.proto (package google.api, syntax proto3) /* eslint-disable */ diff --git a/webui/gen/ts/google/api/http_pb.ts b/webui/gen/ts/google/api/http_pb.ts index 78cc0ed4..20b7bad4 100644 --- a/webui/gen/ts/google/api/http_pb.ts +++ b/webui/gen/ts/google/api/http_pb.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file google/api/http.proto (package google.api, syntax proto3) /* eslint-disable */ diff --git a/webui/gen/ts/types/value_pb.ts b/webui/gen/ts/types/value_pb.ts index 8912a97c..8c70bea9 100644 --- a/webui/gen/ts/types/value_pb.ts +++ b/webui/gen/ts/types/value_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file types/value.proto (package types, syntax proto3) /* eslint-disable */ diff --git a/webui/gen/ts/v1/authentication_pb.ts b/webui/gen/ts/v1/authentication_pb.ts index bba495cd..7a77afee 100644 --- a/webui/gen/ts/v1/authentication_pb.ts +++ b/webui/gen/ts/v1/authentication_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file v1/authentication.proto (package v1, syntax proto3) /* eslint-disable */ diff --git a/webui/gen/ts/v1/config_pb.ts b/webui/gen/ts/v1/config_pb.ts index 832b997f..c2666df3 100644 --- a/webui/gen/ts/v1/config_pb.ts +++ b/webui/gen/ts/v1/config_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file v1/config.proto (package v1, syntax proto3) /* eslint-disable */ diff --git a/webui/gen/ts/v1/crypto_pb.ts b/webui/gen/ts/v1/crypto_pb.ts index 087ccf40..6158f025 100644 --- a/webui/gen/ts/v1/crypto_pb.ts +++ b/webui/gen/ts/v1/crypto_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file v1/crypto.proto (package v1, syntax proto3) /* eslint-disable */ diff --git a/webui/gen/ts/v1/operations_pb.ts b/webui/gen/ts/v1/operations_pb.ts index 6446a83d..981f096d 100644 --- a/webui/gen/ts/v1/operations_pb.ts +++ b/webui/gen/ts/v1/operations_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file v1/operations.proto (package v1, syntax proto3) /* eslint-disable */ @@ -16,7 +16,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file v1/operations.proto. */ export const file_v1_operations: GenFile = /*@__PURE__*/ - fileDesc("ChN2MS9vcGVyYXRpb25zLnByb3RvEgJ2MSIyCg1PcGVyYXRpb25MaXN0EiEKCm9wZXJhdGlvbnMYASADKAsyDS52MS5PcGVyYXRpb24iwAYKCU9wZXJhdGlvbhIKCgJpZBgBIAEoAxITCgtvcmlnaW5hbF9pZBgNIAEoAxINCgVtb2RubxgMIAEoAxIPCgdmbG93X2lkGAogASgDEhgKEG9yaWdpbmFsX2Zsb3dfaWQYDiABKAMSDwoHcmVwb19pZBgCIAEoCRIRCglyZXBvX2d1aWQYDyABKAkSDwoHcGxhbl9pZBgDIAEoCRITCgtpbnN0YW5jZV9pZBgLIAEoCRIfChdvcmlnaW5hbF9pbnN0YW5jZV9rZXlpZBgQIAEoCRITCgtzbmFwc2hvdF9pZBgIIAEoCRIjCgZzdGF0dXMYBCABKA4yEy52MS5PcGVyYXRpb25TdGF0dXMSGgoSdW5peF90aW1lX3N0YXJ0X21zGAUgASgDEhgKEHVuaXhfdGltZV9lbmRfbXMYBiABKAMSFwoPZGlzcGxheV9tZXNzYWdlGAcgASgJEg4KBmxvZ3JlZhgJIAEoCRIvChBvcGVyYXRpb25fYmFja3VwGGQgASgLMhMudjEuT3BlcmF0aW9uQmFja3VwSAASPgoYb3BlcmF0aW9uX2luZGV4X3NuYXBzaG90GGUgASgLMhoudjEuT3BlcmF0aW9uSW5kZXhTbmFwc2hvdEgAEi8KEG9wZXJhdGlvbl9mb3JnZXQYZiABKAsyEy52MS5PcGVyYXRpb25Gb3JnZXRIABItCg9vcGVyYXRpb25fcHJ1bmUYZyABKAsyEi52MS5PcGVyYXRpb25QcnVuZUgAEjEKEW9wZXJhdGlvbl9yZXN0b3JlGGggASgLMhQudjEuT3BlcmF0aW9uUmVzdG9yZUgAEi0KD29wZXJhdGlvbl9zdGF0cxhpIAEoCzISLnYxLk9wZXJhdGlvblN0YXRzSAASMgoSb3BlcmF0aW9uX3J1bl9ob29rGGogASgLMhQudjEuT3BlcmF0aW9uUnVuSG9va0gAEi0KD29wZXJhdGlvbl9jaGVjaxhrIAEoCzISLnYxLk9wZXJhdGlvbkNoZWNrSAASOAoVb3BlcmF0aW9uX3J1bl9jb21tYW5kGGwgASgLMhcudjEuT3BlcmF0aW9uUnVuQ29tbWFuZEgAQgQKAm9wIs8BCg5PcGVyYXRpb25FdmVudBIiCgprZWVwX2FsaXZlGAEgASgLMgwudHlwZXMuRW1wdHlIABIvChJjcmVhdGVkX29wZXJhdGlvbnMYAiABKAsyES52MS5PcGVyYXRpb25MaXN0SAASLwoSdXBkYXRlZF9vcGVyYXRpb25zGAMgASgLMhEudjEuT3BlcmF0aW9uTGlzdEgAEi4KEmRlbGV0ZWRfb3BlcmF0aW9ucxgEIAEoCzIQLnR5cGVzLkludDY0TGlzdEgAQgcKBWV2ZW50ImgKD09wZXJhdGlvbkJhY2t1cBIsCgtsYXN0X3N0YXR1cxgDIAEoCzIXLnYxLkJhY2t1cFByb2dyZXNzRW50cnkSJwoGZXJyb3JzGAQgAygLMhcudjEuQmFja3VwUHJvZ3Jlc3NFcnJvciJOChZPcGVyYXRpb25JbmRleFNuYXBzaG90EiQKCHNuYXBzaG90GAIgASgLMhIudjEuUmVzdGljU25hcHNob3QSDgoGZm9yZ290GAMgASgIIloKD09wZXJhdGlvbkZvcmdldBIiCgZmb3JnZXQYASADKAsyEi52MS5SZXN0aWNTbmFwc2hvdBIjCgZwb2xpY3kYAiABKAsyEy52MS5SZXRlbnRpb25Qb2xpY3kiOwoOT3BlcmF0aW9uUHJ1bmUSEgoGb3V0cHV0GAEgASgJQgIYARIVCg1vdXRwdXRfbG9ncmVmGAIgASgJIjsKDk9wZXJhdGlvbkNoZWNrEhIKBm91dHB1dBgBIAEoCUICGAESFQoNb3V0cHV0X2xvZ3JlZhgCIAEoCSJYChNPcGVyYXRpb25SdW5Db21tYW5kEg8KB2NvbW1hbmQYASABKAkSFQoNb3V0cHV0X2xvZ3JlZhgCIAEoCRIZChFvdXRwdXRfc2l6ZV9ieXRlcxgDIAEoAyJfChBPcGVyYXRpb25SZXN0b3JlEgwKBHBhdGgYASABKAkSDgoGdGFyZ2V0GAIgASgJEi0KC2xhc3Rfc3RhdHVzGAMgASgLMhgudjEuUmVzdG9yZVByb2dyZXNzRW50cnkiLgoOT3BlcmF0aW9uU3RhdHMSHAoFc3RhdHMYASABKAsyDS52MS5SZXBvU3RhdHMicQoQT3BlcmF0aW9uUnVuSG9vaxIRCglwYXJlbnRfb3AYBCABKAMSDAoEbmFtZRgBIAEoCRIVCg1vdXRwdXRfbG9ncmVmGAIgASgJEiUKCWNvbmRpdGlvbhgDIAEoDjISLnYxLkhvb2suQ29uZGl0aW9uKmAKEk9wZXJhdGlvbkV2ZW50VHlwZRIRCg1FVkVOVF9VTktOT1dOEAASEQoNRVZFTlRfQ1JFQVRFRBABEhEKDUVWRU5UX1VQREFURUQQAhIRCg1FVkVOVF9ERUxFVEVEEAMqwgEKD09wZXJhdGlvblN0YXR1cxISCg5TVEFUVVNfVU5LTk9XThAAEhIKDlNUQVRVU19QRU5ESU5HEAESFQoRU1RBVFVTX0lOUFJPR1JFU1MQAhISCg5TVEFUVVNfU1VDQ0VTUxADEhIKDlNUQVRVU19XQVJOSU5HEAcSEAoMU1RBVFVTX0VSUk9SEAQSGwoXU1RBVFVTX1NZU1RFTV9DQU5DRUxMRUQQBRIZChVTVEFUVVNfVVNFUl9DQU5DRUxMRUQQBkIsWipnaXRodWIuY29tL2dhcmV0aGdlb3JnZS9iYWNrcmVzdC9nZW4vZ28vdjFiBnByb3RvMw", [file_v1_restic, file_v1_config, file_types_value]); + fileDesc("ChN2MS9vcGVyYXRpb25zLnByb3RvEgJ2MSIyCg1PcGVyYXRpb25MaXN0EiEKCm9wZXJhdGlvbnMYASADKAsyDS52MS5PcGVyYXRpb24iwAYKCU9wZXJhdGlvbhIKCgJpZBgBIAEoAxITCgtvcmlnaW5hbF9pZBgNIAEoAxINCgVtb2RubxgMIAEoAxIPCgdmbG93X2lkGAogASgDEhgKEG9yaWdpbmFsX2Zsb3dfaWQYDiABKAMSDwoHcmVwb19pZBgCIAEoCRIRCglyZXBvX2d1aWQYDyABKAkSDwoHcGxhbl9pZBgDIAEoCRITCgtpbnN0YW5jZV9pZBgLIAEoCRIfChdvcmlnaW5hbF9pbnN0YW5jZV9rZXlpZBgQIAEoCRITCgtzbmFwc2hvdF9pZBgIIAEoCRIjCgZzdGF0dXMYBCABKA4yEy52MS5PcGVyYXRpb25TdGF0dXMSGgoSdW5peF90aW1lX3N0YXJ0X21zGAUgASgDEhgKEHVuaXhfdGltZV9lbmRfbXMYBiABKAMSFwoPZGlzcGxheV9tZXNzYWdlGAcgASgJEg4KBmxvZ3JlZhgJIAEoCRIvChBvcGVyYXRpb25fYmFja3VwGGQgASgLMhMudjEuT3BlcmF0aW9uQmFja3VwSAASPgoYb3BlcmF0aW9uX2luZGV4X3NuYXBzaG90GGUgASgLMhoudjEuT3BlcmF0aW9uSW5kZXhTbmFwc2hvdEgAEi8KEG9wZXJhdGlvbl9mb3JnZXQYZiABKAsyEy52MS5PcGVyYXRpb25Gb3JnZXRIABItCg9vcGVyYXRpb25fcHJ1bmUYZyABKAsyEi52MS5PcGVyYXRpb25QcnVuZUgAEjEKEW9wZXJhdGlvbl9yZXN0b3JlGGggASgLMhQudjEuT3BlcmF0aW9uUmVzdG9yZUgAEi0KD29wZXJhdGlvbl9zdGF0cxhpIAEoCzISLnYxLk9wZXJhdGlvblN0YXRzSAASMgoSb3BlcmF0aW9uX3J1bl9ob29rGGogASgLMhQudjEuT3BlcmF0aW9uUnVuSG9va0gAEi0KD29wZXJhdGlvbl9jaGVjaxhrIAEoCzISLnYxLk9wZXJhdGlvbkNoZWNrSAASOAoVb3BlcmF0aW9uX3J1bl9jb21tYW5kGGwgASgLMhcudjEuT3BlcmF0aW9uUnVuQ29tbWFuZEgAQgQKAm9wIs8BCg5PcGVyYXRpb25FdmVudBIiCgprZWVwX2FsaXZlGAEgASgLMgwudHlwZXMuRW1wdHlIABIvChJjcmVhdGVkX29wZXJhdGlvbnMYAiABKAsyES52MS5PcGVyYXRpb25MaXN0SAASLwoSdXBkYXRlZF9vcGVyYXRpb25zGAMgASgLMhEudjEuT3BlcmF0aW9uTGlzdEgAEi4KEmRlbGV0ZWRfb3BlcmF0aW9ucxgEIAEoCzIQLnR5cGVzLkludDY0TGlzdEgAQgcKBWV2ZW50InkKD09wZXJhdGlvbkJhY2t1cBIsCgtsYXN0X3N0YXR1cxgDIAEoCzIXLnYxLkJhY2t1cFByb2dyZXNzRW50cnkSJwoGZXJyb3JzGAQgAygLMhcudjEuQmFja3VwUHJvZ3Jlc3NFcnJvchIPCgdkcnlfcnVuGAUgASgIIk4KFk9wZXJhdGlvbkluZGV4U25hcHNob3QSJAoIc25hcHNob3QYAiABKAsyEi52MS5SZXN0aWNTbmFwc2hvdBIOCgZmb3Jnb3QYAyABKAgiWgoPT3BlcmF0aW9uRm9yZ2V0EiIKBmZvcmdldBgBIAMoCzISLnYxLlJlc3RpY1NuYXBzaG90EiMKBnBvbGljeRgCIAEoCzITLnYxLlJldGVudGlvblBvbGljeSI7Cg5PcGVyYXRpb25QcnVuZRISCgZvdXRwdXQYASABKAlCAhgBEhUKDW91dHB1dF9sb2dyZWYYAiABKAkiOwoOT3BlcmF0aW9uQ2hlY2sSEgoGb3V0cHV0GAEgASgJQgIYARIVCg1vdXRwdXRfbG9ncmVmGAIgASgJIlgKE09wZXJhdGlvblJ1bkNvbW1hbmQSDwoHY29tbWFuZBgBIAEoCRIVCg1vdXRwdXRfbG9ncmVmGAIgASgJEhkKEW91dHB1dF9zaXplX2J5dGVzGAMgASgDIl8KEE9wZXJhdGlvblJlc3RvcmUSDAoEcGF0aBgBIAEoCRIOCgZ0YXJnZXQYAiABKAkSLQoLbGFzdF9zdGF0dXMYAyABKAsyGC52MS5SZXN0b3JlUHJvZ3Jlc3NFbnRyeSIuCg5PcGVyYXRpb25TdGF0cxIcCgVzdGF0cxgBIAEoCzINLnYxLlJlcG9TdGF0cyJxChBPcGVyYXRpb25SdW5Ib29rEhEKCXBhcmVudF9vcBgEIAEoAxIMCgRuYW1lGAEgASgJEhUKDW91dHB1dF9sb2dyZWYYAiABKAkSJQoJY29uZGl0aW9uGAMgASgOMhIudjEuSG9vay5Db25kaXRpb24qYAoST3BlcmF0aW9uRXZlbnRUeXBlEhEKDUVWRU5UX1VOS05PV04QABIRCg1FVkVOVF9DUkVBVEVEEAESEQoNRVZFTlRfVVBEQVRFRBACEhEKDUVWRU5UX0RFTEVURUQQAyrCAQoPT3BlcmF0aW9uU3RhdHVzEhIKDlNUQVRVU19VTktOT1dOEAASEgoOU1RBVFVTX1BFTkRJTkcQARIVChFTVEFUVVNfSU5QUk9HUkVTUxACEhIKDlNUQVRVU19TVUNDRVNTEAMSEgoOU1RBVFVTX1dBUk5JTkcQBxIQCgxTVEFUVVNfRVJST1IQBBIbChdTVEFUVVNfU1lTVEVNX0NBTkNFTExFRBAFEhkKFVNUQVRVU19VU0VSX0NBTkNFTExFRBAGQixaKmdpdGh1Yi5jb20vZ2FyZXRoZ2VvcmdlL2JhY2tyZXN0L2dlbi9nby92MWIGcHJvdG8z", [file_v1_restic, file_v1_config, file_types_value]); /** * @generated from message v1.OperationList @@ -269,6 +269,13 @@ export type OperationBackup = Message<"v1.OperationBackup"> & { * @generated from field: repeated v1.BackupProgressError errors = 4; */ errors: BackupProgressError[]; + + /** + * indicates this was a dry run backup (no snapshot created) + * + * @generated from field: bool dry_run = 5; + */ + dryRun: boolean; }; /** diff --git a/webui/gen/ts/v1/restic_pb.ts b/webui/gen/ts/v1/restic_pb.ts index 90133e65..6053ccbf 100644 --- a/webui/gen/ts/v1/restic_pb.ts +++ b/webui/gen/ts/v1/restic_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file v1/restic.proto (package v1, syntax proto3) /* eslint-disable */ diff --git a/webui/gen/ts/v1/service_pb.ts b/webui/gen/ts/v1/service_pb.ts index 38bc07ed..c517e5c6 100644 --- a/webui/gen/ts/v1/service_pb.ts +++ b/webui/gen/ts/v1/service_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file v1/service.proto (package v1, syntax proto3) /* eslint-disable */ @@ -21,7 +21,33 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file v1/service.proto. */ export const file_v1_service: GenFile = /*@__PURE__*/ - fileDesc("ChB2MS9zZXJ2aWNlLnByb3RvEgJ2MSK/AgoKT3BTZWxlY3RvchILCgNpZHMYASADKAMSGAoLaW5zdGFuY2VfaWQYBiABKAlIAIgBARIkChdvcmlnaW5hbF9pbnN0YW5jZV9rZXlpZBgIIAEoCUgBiAEBEhYKCXJlcG9fZ3VpZBgHIAEoCUgCiAEBEhQKB3BsYW5faWQYAyABKAlIA4gBARIYCgtzbmFwc2hvdF9pZBgEIAEoCUgEiAEBEhQKB2Zsb3dfaWQYBSABKANIBYgBARIWCgltb2Rub19ndGUYCSABKANIBogBAUIOCgxfaW5zdGFuY2VfaWRCGgoYX29yaWdpbmFsX2luc3RhbmNlX2tleWlkQgwKCl9yZXBvX2d1aWRCCgoIX3BsYW5faWRCDgoMX3NuYXBzaG90X2lkQgoKCF9mbG93X2lkQgwKCl9tb2Rub19ndGUiZAoQU2V0dXBTZnRwUmVxdWVzdBIMCgRob3N0GAEgASgJEgwKBHBvcnQYAiABKAkSEAoIdXNlcm5hbWUYAyABKAkSFQoIcGFzc3dvcmQYBCABKAlIAIgBAUILCglfcGFzc3dvcmQiYgoRU2V0dXBTZnRwUmVzcG9uc2USEgoKcHVibGljX2tleRgBIAEoCRIQCghrZXlfcGF0aBgCIAEoCRIYChBrbm93bl9ob3N0c19wYXRoGAMgASgJEg0KBWVycm9yGAQgASgJIk0KFkNoZWNrUmVwb0V4aXN0c1JlcXVlc3QSFgoEcmVwbxgBIAEoCzIILnYxLlJlcG8SGwoTdHJ1c3Rfc2Z0cF9ob3N0X2tleRgCIAEoCCJUChdDaGVja1JlcG9FeGlzdHNSZXNwb25zZRIOCgZleGlzdHMYASABKAgSDQoFZXJyb3IYAiABKAkSGgoSaG9zdF9rZXlfdW50cnVzdGVkGAUgASgIIkUKDkFkZFJlcG9SZXF1ZXN0EhYKBHJlcG8YASABKAsyCC52MS5SZXBvEhsKE3RydXN0X3NmdHBfaG9zdF9rZXkYAiABKAgiwAEKEURvUmVwb1Rhc2tSZXF1ZXN0Eg8KB3JlcG9faWQYASABKAkSKAoEdGFzaxgCIAEoDjIaLnYxLkRvUmVwb1Rhc2tSZXF1ZXN0LlRhc2sicAoEVGFzaxINCglUQVNLX05PTkUQABIYChRUQVNLX0lOREVYX1NOQVBTSE9UUxABEg4KClRBU0tfUFJVTkUQAhIOCgpUQVNLX0NIRUNLEAMSDgoKVEFTS19TVEFUUxAEEg8KC1RBU0tfVU5MT0NLEAUiTAoTQ2xlYXJIaXN0b3J5UmVxdWVzdBIgCghzZWxlY3RvchgBIAEoCzIOLnYxLk9wU2VsZWN0b3ISEwoLb25seV9mYWlsZWQYAiABKAgiRgoNRm9yZ2V0UmVxdWVzdBIPCgdyZXBvX2lkGAEgASgJEg8KB3BsYW5faWQYAiABKAkSEwoLc25hcHNob3RfaWQYAyABKAkiOAoUTGlzdFNuYXBzaG90c1JlcXVlc3QSDwoHcmVwb19pZBgBIAEoCRIPCgdwbGFuX2lkGAIgASgJIkgKFEdldE9wZXJhdGlvbnNSZXF1ZXN0EiAKCHNlbGVjdG9yGAEgASgLMg4udjEuT3BTZWxlY3RvchIOCgZsYXN0X24YAiABKAMibQoWUmVzdG9yZVNuYXBzaG90UmVxdWVzdBIPCgdwbGFuX2lkGAEgASgJEg8KB3JlcG9faWQYBSABKAkSEwoLc25hcHNob3RfaWQYAiABKAkSDAoEcGF0aBgDIAEoCRIOCgZ0YXJnZXQYBCABKAkiUAoYTGlzdFNuYXBzaG90RmlsZXNSZXF1ZXN0EhEKCXJlcG9fZ3VpZBgBIAEoCRITCgtzbmFwc2hvdF9pZBgCIAEoCRIMCgRwYXRoGAMgASgJIkcKGUxpc3RTbmFwc2hvdEZpbGVzUmVzcG9uc2USDAoEcGF0aBgBIAEoCRIcCgdlbnRyaWVzGAIgAygLMgsudjEuTHNFbnRyeSIdCg5Mb2dEYXRhUmVxdWVzdBILCgNyZWYYASABKAkiOQoVR2V0RG93bmxvYWRVUkxSZXF1ZXN0Eg0KBW9wX2lkGAEgASgDEhEKCWZpbGVfcGF0aBgCIAEoCSKWAQoHTHNFbnRyeRIMCgRuYW1lGAEgASgJEgwKBHR5cGUYAiABKAkSDAoEcGF0aBgDIAEoCRILCgN1aWQYBCABKAMSCwoDZ2lkGAUgASgDEgwKBHNpemUYBiABKAMSDAoEbW9kZRgHIAEoAxINCgVtdGltZRgIIAEoCRINCgVhdGltZRgJIAEoCRINCgVjdGltZRgKIAEoCSI1ChFSdW5Db21tYW5kUmVxdWVzdBIPCgdyZXBvX2lkGAEgASgJEg8KB2NvbW1hbmQYAiABKAkitQUKGFN1bW1hcnlEYXNoYm9hcmRSZXNwb25zZRI8Cg5yZXBvX3N1bW1hcmllcxgBIAMoCzIkLnYxLlN1bW1hcnlEYXNoYm9hcmRSZXNwb25zZS5TdW1tYXJ5EjwKDnBsYW5fc3VtbWFyaWVzGAIgAygLMiQudjEuU3VtbWFyeURhc2hib2FyZFJlc3BvbnNlLlN1bW1hcnkSEwoLY29uZmlnX3BhdGgYCiABKAkSEQoJZGF0YV9wYXRoGAsgASgJGu4CCgdTdW1tYXJ5EgoKAmlkGAEgASgJEh0KFWJhY2t1cHNfZmFpbGVkXzMwZGF5cxgCIAEoAxIjChtiYWNrdXBzX3dhcm5pbmdfbGFzdF8zMGRheXMYAyABKAMSIwobYmFja3Vwc19zdWNjZXNzX2xhc3RfMzBkYXlzGAQgASgDEiEKGWJ5dGVzX3NjYW5uZWRfbGFzdF8zMGRheXMYBSABKAMSHwoXYnl0ZXNfYWRkZWRfbGFzdF8zMGRheXMYBiABKAMSFwoPdG90YWxfc25hcHNob3RzGAcgASgDEhkKEWJ5dGVzX3NjYW5uZWRfYXZnGAggASgDEhcKD2J5dGVzX2FkZGVkX2F2ZxgJIAEoAxIbChNuZXh0X2JhY2t1cF90aW1lX21zGAogASgDEkAKDnJlY2VudF9iYWNrdXBzGAsgASgLMigudjEuU3VtbWFyeURhc2hib2FyZFJlc3BvbnNlLkJhY2t1cENoYXJ0GoMBCgtCYWNrdXBDaGFydBIPCgdmbG93X2lkGAEgAygDEhQKDHRpbWVzdGFtcF9tcxgCIAMoAxITCgtkdXJhdGlvbl9tcxgDIAMoAxIjCgZzdGF0dXMYBCADKA4yEy52MS5PcGVyYXRpb25TdGF0dXMSEwoLYnl0ZXNfYWRkZWQYBSADKAMykgoKCEJhY2tyZXN0EjEKCUdldENvbmZpZxIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eRoKLnYxLkNvbmZpZyIAEiUKCVNldENvbmZpZxIKLnYxLkNvbmZpZxoKLnYxLkNvbmZpZyIAEjoKCVNldHVwU2Z0cBIULnYxLlNldHVwU2Z0cFJlcXVlc3QaFS52MS5TZXR1cFNmdHBSZXNwb25zZSIAEkwKD0NoZWNrUmVwb0V4aXN0cxIaLnYxLkNoZWNrUmVwb0V4aXN0c1JlcXVlc3QaGy52MS5DaGVja1JlcG9FeGlzdHNSZXNwb25zZSIAEisKB0FkZFJlcG8SEi52MS5BZGRSZXBvUmVxdWVzdBoKLnYxLkNvbmZpZyIAEi4KClJlbW92ZVJlcG8SEi50eXBlcy5TdHJpbmdWYWx1ZRoKLnYxLkNvbmZpZyIAEkQKEkdldE9wZXJhdGlvbkV2ZW50cxIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eRoSLnYxLk9wZXJhdGlvbkV2ZW50IgAwARI+Cg1HZXRPcGVyYXRpb25zEhgudjEuR2V0T3BlcmF0aW9uc1JlcXVlc3QaES52MS5PcGVyYXRpb25MaXN0IgASQwoNTGlzdFNuYXBzaG90cxIYLnYxLkxpc3RTbmFwc2hvdHNSZXF1ZXN0GhYudjEuUmVzdGljU25hcHNob3RMaXN0IgASUgoRTGlzdFNuYXBzaG90RmlsZXMSHC52MS5MaXN0U25hcHNob3RGaWxlc1JlcXVlc3QaHS52MS5MaXN0U25hcHNob3RGaWxlc1Jlc3BvbnNlIgASNgoGQmFja3VwEhIudHlwZXMuU3RyaW5nVmFsdWUaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABI9CgpEb1JlcG9UYXNrEhUudjEuRG9SZXBvVGFza1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABI1CgZGb3JnZXQSES52MS5Gb3JnZXRSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IgASPwoHUmVzdG9yZRIaLnYxLlJlc3RvcmVTbmFwc2hvdFJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABI1CgZDYW5jZWwSES50eXBlcy5JbnQ2NFZhbHVlGhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IgASNAoHR2V0TG9ncxISLnYxLkxvZ0RhdGFSZXF1ZXN0GhEudHlwZXMuQnl0ZXNWYWx1ZSIAMAESOAoKUnVuQ29tbWFuZBIVLnYxLlJ1bkNvbW1hbmRSZXF1ZXN0GhEudHlwZXMuSW50NjRWYWx1ZSIAEkEKDkdldERvd25sb2FkVVJMEhkudjEuR2V0RG93bmxvYWRVUkxSZXF1ZXN0GhIudHlwZXMuU3RyaW5nVmFsdWUiABJBCgxDbGVhckhpc3RvcnkSFy52MS5DbGVhckhpc3RvcnlSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IgASOwoQUGF0aEF1dG9jb21wbGV0ZRISLnR5cGVzLlN0cmluZ1ZhbHVlGhEudHlwZXMuU3RyaW5nTGlzdCIAEk0KE0dldFN1bW1hcnlEYXNoYm9hcmQSFi5nb29nbGUucHJvdG9idWYuRW1wdHkaHC52MS5TdW1tYXJ5RGFzaGJvYXJkUmVzcG9uc2UiAEIsWipnaXRodWIuY29tL2dhcmV0aGdlb3JnZS9iYWNrcmVzdC9nZW4vZ28vdjFiBnByb3RvMw", [file_v1_config, file_v1_restic, file_v1_operations, file_types_value, file_google_protobuf_empty, file_google_api_annotations]); + fileDesc("ChB2MS9zZXJ2aWNlLnByb3RvEgJ2MSIvCg1CYWNrdXBSZXF1ZXN0Eg0KBXZhbHVlGAEgASgJEg8KB2RyeV9ydW4YAiABKAgivwIKCk9wU2VsZWN0b3ISCwoDaWRzGAEgAygDEhgKC2luc3RhbmNlX2lkGAYgASgJSACIAQESJAoXb3JpZ2luYWxfaW5zdGFuY2Vfa2V5aWQYCCABKAlIAYgBARIWCglyZXBvX2d1aWQYByABKAlIAogBARIUCgdwbGFuX2lkGAMgASgJSAOIAQESGAoLc25hcHNob3RfaWQYBCABKAlIBIgBARIUCgdmbG93X2lkGAUgASgDSAWIAQESFgoJbW9kbm9fZ3RlGAkgASgDSAaIAQFCDgoMX2luc3RhbmNlX2lkQhoKGF9vcmlnaW5hbF9pbnN0YW5jZV9rZXlpZEIMCgpfcmVwb19ndWlkQgoKCF9wbGFuX2lkQg4KDF9zbmFwc2hvdF9pZEIKCghfZmxvd19pZEIMCgpfbW9kbm9fZ3RlImQKEFNldHVwU2Z0cFJlcXVlc3QSDAoEaG9zdBgBIAEoCRIMCgRwb3J0GAIgASgJEhAKCHVzZXJuYW1lGAMgASgJEhUKCHBhc3N3b3JkGAQgASgJSACIAQFCCwoJX3Bhc3N3b3JkImIKEVNldHVwU2Z0cFJlc3BvbnNlEhIKCnB1YmxpY19rZXkYASABKAkSEAoIa2V5X3BhdGgYAiABKAkSGAoQa25vd25faG9zdHNfcGF0aBgDIAEoCRINCgVlcnJvchgEIAEoCSJNChZDaGVja1JlcG9FeGlzdHNSZXF1ZXN0EhYKBHJlcG8YASABKAsyCC52MS5SZXBvEhsKE3RydXN0X3NmdHBfaG9zdF9rZXkYAiABKAgiVAoXQ2hlY2tSZXBvRXhpc3RzUmVzcG9uc2USDgoGZXhpc3RzGAEgASgIEg0KBWVycm9yGAIgASgJEhoKEmhvc3Rfa2V5X3VudHJ1c3RlZBgFIAEoCCJFCg5BZGRSZXBvUmVxdWVzdBIWCgRyZXBvGAEgASgLMggudjEuUmVwbxIbChN0cnVzdF9zZnRwX2hvc3Rfa2V5GAIgASgIIsABChFEb1JlcG9UYXNrUmVxdWVzdBIPCgdyZXBvX2lkGAEgASgJEigKBHRhc2sYAiABKA4yGi52MS5Eb1JlcG9UYXNrUmVxdWVzdC5UYXNrInAKBFRhc2sSDQoJVEFTS19OT05FEAASGAoUVEFTS19JTkRFWF9TTkFQU0hPVFMQARIOCgpUQVNLX1BSVU5FEAISDgoKVEFTS19DSEVDSxADEg4KClRBU0tfU1RBVFMQBBIPCgtUQVNLX1VOTE9DSxAFIkwKE0NsZWFySGlzdG9yeVJlcXVlc3QSIAoIc2VsZWN0b3IYASABKAsyDi52MS5PcFNlbGVjdG9yEhMKC29ubHlfZmFpbGVkGAIgASgIIkYKDUZvcmdldFJlcXVlc3QSDwoHcmVwb19pZBgBIAEoCRIPCgdwbGFuX2lkGAIgASgJEhMKC3NuYXBzaG90X2lkGAMgASgJIjgKFExpc3RTbmFwc2hvdHNSZXF1ZXN0Eg8KB3JlcG9faWQYASABKAkSDwoHcGxhbl9pZBgCIAEoCSJIChRHZXRPcGVyYXRpb25zUmVxdWVzdBIgCghzZWxlY3RvchgBIAEoCzIOLnYxLk9wU2VsZWN0b3ISDgoGbGFzdF9uGAIgASgDIm0KFlJlc3RvcmVTbmFwc2hvdFJlcXVlc3QSDwoHcGxhbl9pZBgBIAEoCRIPCgdyZXBvX2lkGAUgASgJEhMKC3NuYXBzaG90X2lkGAIgASgJEgwKBHBhdGgYAyABKAkSDgoGdGFyZ2V0GAQgASgJIlAKGExpc3RTbmFwc2hvdEZpbGVzUmVxdWVzdBIRCglyZXBvX2d1aWQYASABKAkSEwoLc25hcHNob3RfaWQYAiABKAkSDAoEcGF0aBgDIAEoCSJHChlMaXN0U25hcHNob3RGaWxlc1Jlc3BvbnNlEgwKBHBhdGgYASABKAkSHAoHZW50cmllcxgCIAMoCzILLnYxLkxzRW50cnkiHQoOTG9nRGF0YVJlcXVlc3QSCwoDcmVmGAEgASgJIjkKFUdldERvd25sb2FkVVJMUmVxdWVzdBINCgVvcF9pZBgBIAEoAxIRCglmaWxlX3BhdGgYAiABKAkilgEKB0xzRW50cnkSDAoEbmFtZRgBIAEoCRIMCgR0eXBlGAIgASgJEgwKBHBhdGgYAyABKAkSCwoDdWlkGAQgASgDEgsKA2dpZBgFIAEoAxIMCgRzaXplGAYgASgDEgwKBG1vZGUYByABKAMSDQoFbXRpbWUYCCABKAkSDQoFYXRpbWUYCSABKAkSDQoFY3RpbWUYCiABKAkiNQoRUnVuQ29tbWFuZFJlcXVlc3QSDwoHcmVwb19pZBgBIAEoCRIPCgdjb21tYW5kGAIgASgJIrUFChhTdW1tYXJ5RGFzaGJvYXJkUmVzcG9uc2USPAoOcmVwb19zdW1tYXJpZXMYASADKAsyJC52MS5TdW1tYXJ5RGFzaGJvYXJkUmVzcG9uc2UuU3VtbWFyeRI8Cg5wbGFuX3N1bW1hcmllcxgCIAMoCzIkLnYxLlN1bW1hcnlEYXNoYm9hcmRSZXNwb25zZS5TdW1tYXJ5EhMKC2NvbmZpZ19wYXRoGAogASgJEhEKCWRhdGFfcGF0aBgLIAEoCRruAgoHU3VtbWFyeRIKCgJpZBgBIAEoCRIdChViYWNrdXBzX2ZhaWxlZF8zMGRheXMYAiABKAMSIwobYmFja3Vwc193YXJuaW5nX2xhc3RfMzBkYXlzGAMgASgDEiMKG2JhY2t1cHNfc3VjY2Vzc19sYXN0XzMwZGF5cxgEIAEoAxIhChlieXRlc19zY2FubmVkX2xhc3RfMzBkYXlzGAUgASgDEh8KF2J5dGVzX2FkZGVkX2xhc3RfMzBkYXlzGAYgASgDEhcKD3RvdGFsX3NuYXBzaG90cxgHIAEoAxIZChFieXRlc19zY2FubmVkX2F2ZxgIIAEoAxIXCg9ieXRlc19hZGRlZF9hdmcYCSABKAMSGwoTbmV4dF9iYWNrdXBfdGltZV9tcxgKIAEoAxJACg5yZWNlbnRfYmFja3VwcxgLIAEoCzIoLnYxLlN1bW1hcnlEYXNoYm9hcmRSZXNwb25zZS5CYWNrdXBDaGFydBqDAQoLQmFja3VwQ2hhcnQSDwoHZmxvd19pZBgBIAMoAxIUCgx0aW1lc3RhbXBfbXMYAiADKAMSEwoLZHVyYXRpb25fbXMYAyADKAMSIwoGc3RhdHVzGAQgAygOMhMudjEuT3BlcmF0aW9uU3RhdHVzEhMKC2J5dGVzX2FkZGVkGAUgAygDMpEKCghCYWNrcmVzdBIxCglHZXRDb25maWcSFi5nb29nbGUucHJvdG9idWYuRW1wdHkaCi52MS5Db25maWciABIlCglTZXRDb25maWcSCi52MS5Db25maWcaCi52MS5Db25maWciABI6CglTZXR1cFNmdHASFC52MS5TZXR1cFNmdHBSZXF1ZXN0GhUudjEuU2V0dXBTZnRwUmVzcG9uc2UiABJMCg9DaGVja1JlcG9FeGlzdHMSGi52MS5DaGVja1JlcG9FeGlzdHNSZXF1ZXN0GhsudjEuQ2hlY2tSZXBvRXhpc3RzUmVzcG9uc2UiABIrCgdBZGRSZXBvEhIudjEuQWRkUmVwb1JlcXVlc3QaCi52MS5Db25maWciABIuCgpSZW1vdmVSZXBvEhIudHlwZXMuU3RyaW5nVmFsdWUaCi52MS5Db25maWciABJEChJHZXRPcGVyYXRpb25FdmVudHMSFi5nb29nbGUucHJvdG9idWYuRW1wdHkaEi52MS5PcGVyYXRpb25FdmVudCIAMAESPgoNR2V0T3BlcmF0aW9ucxIYLnYxLkdldE9wZXJhdGlvbnNSZXF1ZXN0GhEudjEuT3BlcmF0aW9uTGlzdCIAEkMKDUxpc3RTbmFwc2hvdHMSGC52MS5MaXN0U25hcHNob3RzUmVxdWVzdBoWLnYxLlJlc3RpY1NuYXBzaG90TGlzdCIAElIKEUxpc3RTbmFwc2hvdEZpbGVzEhwudjEuTGlzdFNuYXBzaG90RmlsZXNSZXF1ZXN0Gh0udjEuTGlzdFNuYXBzaG90RmlsZXNSZXNwb25zZSIAEjUKBkJhY2t1cBIRLnYxLkJhY2t1cFJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABI9CgpEb1JlcG9UYXNrEhUudjEuRG9SZXBvVGFza1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABI1CgZGb3JnZXQSES52MS5Gb3JnZXRSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IgASPwoHUmVzdG9yZRIaLnYxLlJlc3RvcmVTbmFwc2hvdFJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiABI1CgZDYW5jZWwSES50eXBlcy5JbnQ2NFZhbHVlGhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IgASNAoHR2V0TG9ncxISLnYxLkxvZ0RhdGFSZXF1ZXN0GhEudHlwZXMuQnl0ZXNWYWx1ZSIAMAESOAoKUnVuQ29tbWFuZBIVLnYxLlJ1bkNvbW1hbmRSZXF1ZXN0GhEudHlwZXMuSW50NjRWYWx1ZSIAEkEKDkdldERvd25sb2FkVVJMEhkudjEuR2V0RG93bmxvYWRVUkxSZXF1ZXN0GhIudHlwZXMuU3RyaW5nVmFsdWUiABJBCgxDbGVhckhpc3RvcnkSFy52MS5DbGVhckhpc3RvcnlSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IgASOwoQUGF0aEF1dG9jb21wbGV0ZRISLnR5cGVzLlN0cmluZ1ZhbHVlGhEudHlwZXMuU3RyaW5nTGlzdCIAEk0KE0dldFN1bW1hcnlEYXNoYm9hcmQSFi5nb29nbGUucHJvdG9idWYuRW1wdHkaHC52MS5TdW1tYXJ5RGFzaGJvYXJkUmVzcG9uc2UiAEIsWipnaXRodWIuY29tL2dhcmV0aGdlb3JnZS9iYWNrcmVzdC9nZW4vZ28vdjFiBnByb3RvMw", [file_v1_config, file_v1_restic, file_v1_operations, file_types_value, file_google_protobuf_empty, file_google_api_annotations]); + +/** + * @generated from message v1.BackupRequest + */ +export type BackupRequest = Message<"v1.BackupRequest"> & { + /** + * plan_id - named 'value' for curl script backwards compatibility + * + * @generated from field: string value = 1; + */ + value: string; + + /** + * optional, simulate backup without creating snapshot + * + * @generated from field: bool dry_run = 2; + */ + dryRun: boolean; +}; + +/** + * Describes the message v1.BackupRequest. + * Use `create(BackupRequestSchema)` to create a new message. + */ +export const BackupRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_v1_service, 0); /** * OpSelector is a message that can be used to select operations e.g. by query. @@ -75,7 +101,7 @@ export type OpSelector = Message<"v1.OpSelector"> & { * Use `create(OpSelectorSchema)` to create a new message. */ export const OpSelectorSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 0); + messageDesc(file_v1_service, 1); /** * @generated from message v1.SetupSftpRequest @@ -109,7 +135,7 @@ export type SetupSftpRequest = Message<"v1.SetupSftpRequest"> & { * Use `create(SetupSftpRequestSchema)` to create a new message. */ export const SetupSftpRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 1); + messageDesc(file_v1_service, 2); /** * @generated from message v1.SetupSftpResponse @@ -141,7 +167,7 @@ export type SetupSftpResponse = Message<"v1.SetupSftpResponse"> & { * Use `create(SetupSftpResponseSchema)` to create a new message. */ export const SetupSftpResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 2); + messageDesc(file_v1_service, 3); /** * @generated from message v1.CheckRepoExistsRequest @@ -163,7 +189,7 @@ export type CheckRepoExistsRequest = Message<"v1.CheckRepoExistsRequest"> & { * Use `create(CheckRepoExistsRequestSchema)` to create a new message. */ export const CheckRepoExistsRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 3); + messageDesc(file_v1_service, 4); /** * @generated from message v1.CheckRepoExistsResponse @@ -190,7 +216,7 @@ export type CheckRepoExistsResponse = Message<"v1.CheckRepoExistsResponse"> & { * Use `create(CheckRepoExistsResponseSchema)` to create a new message. */ export const CheckRepoExistsResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 4); + messageDesc(file_v1_service, 5); /** * @generated from message v1.AddRepoRequest @@ -212,7 +238,7 @@ export type AddRepoRequest = Message<"v1.AddRepoRequest"> & { * Use `create(AddRepoRequestSchema)` to create a new message. */ export const AddRepoRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 5); + messageDesc(file_v1_service, 6); /** * @generated from message v1.DoRepoTaskRequest @@ -234,7 +260,7 @@ export type DoRepoTaskRequest = Message<"v1.DoRepoTaskRequest"> & { * Use `create(DoRepoTaskRequestSchema)` to create a new message. */ export const DoRepoTaskRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 6); + messageDesc(file_v1_service, 7); /** * @generated from enum v1.DoRepoTaskRequest.Task @@ -275,7 +301,7 @@ export enum DoRepoTaskRequest_Task { * Describes the enum v1.DoRepoTaskRequest.Task. */ export const DoRepoTaskRequest_TaskSchema: GenEnum = /*@__PURE__*/ - enumDesc(file_v1_service, 6, 0); + enumDesc(file_v1_service, 7, 0); /** * @generated from message v1.ClearHistoryRequest @@ -297,7 +323,7 @@ export type ClearHistoryRequest = Message<"v1.ClearHistoryRequest"> & { * Use `create(ClearHistoryRequestSchema)` to create a new message. */ export const ClearHistoryRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 7); + messageDesc(file_v1_service, 8); /** * @generated from message v1.ForgetRequest @@ -324,7 +350,7 @@ export type ForgetRequest = Message<"v1.ForgetRequest"> & { * Use `create(ForgetRequestSchema)` to create a new message. */ export const ForgetRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 8); + messageDesc(file_v1_service, 9); /** * @generated from message v1.ListSnapshotsRequest @@ -346,7 +372,7 @@ export type ListSnapshotsRequest = Message<"v1.ListSnapshotsRequest"> & { * Use `create(ListSnapshotsRequestSchema)` to create a new message. */ export const ListSnapshotsRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 9); + messageDesc(file_v1_service, 10); /** * @generated from message v1.GetOperationsRequest @@ -370,7 +396,7 @@ export type GetOperationsRequest = Message<"v1.GetOperationsRequest"> & { * Use `create(GetOperationsRequestSchema)` to create a new message. */ export const GetOperationsRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 10); + messageDesc(file_v1_service, 11); /** * @generated from message v1.RestoreSnapshotRequest @@ -407,7 +433,7 @@ export type RestoreSnapshotRequest = Message<"v1.RestoreSnapshotRequest"> & { * Use `create(RestoreSnapshotRequestSchema)` to create a new message. */ export const RestoreSnapshotRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 11); + messageDesc(file_v1_service, 12); /** * @generated from message v1.ListSnapshotFilesRequest @@ -434,7 +460,7 @@ export type ListSnapshotFilesRequest = Message<"v1.ListSnapshotFilesRequest"> & * Use `create(ListSnapshotFilesRequestSchema)` to create a new message. */ export const ListSnapshotFilesRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 12); + messageDesc(file_v1_service, 13); /** * @generated from message v1.ListSnapshotFilesResponse @@ -456,7 +482,7 @@ export type ListSnapshotFilesResponse = Message<"v1.ListSnapshotFilesResponse"> * Use `create(ListSnapshotFilesResponseSchema)` to create a new message. */ export const ListSnapshotFilesResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 13); + messageDesc(file_v1_service, 14); /** * @generated from message v1.LogDataRequest @@ -473,7 +499,7 @@ export type LogDataRequest = Message<"v1.LogDataRequest"> & { * Use `create(LogDataRequestSchema)` to create a new message. */ export const LogDataRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 14); + messageDesc(file_v1_service, 15); /** * @generated from message v1.GetDownloadURLRequest @@ -495,7 +521,7 @@ export type GetDownloadURLRequest = Message<"v1.GetDownloadURLRequest"> & { * Use `create(GetDownloadURLRequestSchema)` to create a new message. */ export const GetDownloadURLRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 15); + messageDesc(file_v1_service, 16); /** * @generated from message v1.LsEntry @@ -557,7 +583,7 @@ export type LsEntry = Message<"v1.LsEntry"> & { * Use `create(LsEntrySchema)` to create a new message. */ export const LsEntrySchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 16); + messageDesc(file_v1_service, 17); /** * @generated from message v1.RunCommandRequest @@ -579,7 +605,7 @@ export type RunCommandRequest = Message<"v1.RunCommandRequest"> & { * Use `create(RunCommandRequestSchema)` to create a new message. */ export const RunCommandRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 17); + messageDesc(file_v1_service, 18); /** * @generated from message v1.SummaryDashboardResponse @@ -611,7 +637,7 @@ export type SummaryDashboardResponse = Message<"v1.SummaryDashboardResponse"> & * Use `create(SummaryDashboardResponseSchema)` to create a new message. */ export const SummaryDashboardResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 18); + messageDesc(file_v1_service, 19); /** * @generated from message v1.SummaryDashboardResponse.Summary @@ -682,7 +708,7 @@ export type SummaryDashboardResponse_Summary = Message<"v1.SummaryDashboardRespo * Use `create(SummaryDashboardResponse_SummarySchema)` to create a new message. */ export const SummaryDashboardResponse_SummarySchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 18, 0); + messageDesc(file_v1_service, 19, 0); /** * @generated from message v1.SummaryDashboardResponse.BackupChart @@ -719,7 +745,7 @@ export type SummaryDashboardResponse_BackupChart = Message<"v1.SummaryDashboardR * Use `create(SummaryDashboardResponse_BackupChartSchema)` to create a new message. */ export const SummaryDashboardResponse_BackupChartSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_v1_service, 18, 1); + messageDesc(file_v1_service, 19, 1); /** * @generated from service v1.Backrest @@ -812,7 +838,7 @@ export const Backrest: GenService<{ */ backup: { methodKind: "unary"; - input: typeof StringValueSchema; + input: typeof BackupRequestSchema; output: typeof EmptySchema; }, /** diff --git a/webui/gen/ts/v1sync/syncservice_pb.ts b/webui/gen/ts/v1sync/syncservice_pb.ts index 532d75f8..73ebe050 100644 --- a/webui/gen/ts/v1sync/syncservice_pb.ts +++ b/webui/gen/ts/v1sync/syncservice_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.10.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" // @generated from file v1sync/syncservice.proto (package v1sync, syntax proto3) /* eslint-disable */ diff --git a/webui/messages/en.json b/webui/messages/en.json index 1f991ee1..9d7e49f4 100644 --- a/webui/messages/en.json +++ b/webui/messages/en.json @@ -251,6 +251,9 @@ "op_type_stats": "Stats", "op_type_run_hook": "Run Hook", "op_type_run_command": "Run Command", + "op_type_dry_run_backup": "Dry Run Backup", + "plan_dry_run_scheduled": "Dry run backup scheduled", + "plan_dry_run_error": "Dry run failed: ", "op_type_unknown": "Unknown", "op_status_pending": "pending", "op_status_in_progress": "in progress", diff --git a/webui/src/api/flowDisplayAggregator.ts b/webui/src/api/flowDisplayAggregator.ts index 2966b659..13f8e764 100644 --- a/webui/src/api/flowDisplayAggregator.ts +++ b/webui/src/api/flowDisplayAggregator.ts @@ -9,6 +9,7 @@ import * as m from "../paraglide/messages"; export enum DisplayType { UNKNOWN, BACKUP, + BACKUP_DRYRUN, SNAPSHOT, FORGET, PRUNE, @@ -62,7 +63,8 @@ export const displayInfoForFlow = (ops: Operation[]): FlowDisplayInfo => { { const lastStatus = firstOp.op.value.lastStatus; if (lastStatus) { - if (lastStatus.entry.case === "summary") { + // Show snapshot ID in subtitle, but not for dry runs (fake ID) + if (lastStatus.entry.case === "summary" && !firstOp.op.value.dryRun) { info.subtitleComponents.push( m.op_subtitle_id({ id: normalizeSnapshotId(lastStatus.entry.value.snapshotId), @@ -207,6 +209,7 @@ export const shouldHideStatus = (status: OperationStatus) => { export const getTypeForDisplay = (op: Operation) => { switch (op.op.case) { case "operationBackup": + if (op.op.value.dryRun) return DisplayType.BACKUP_DRYRUN; return DisplayType.BACKUP; case "operationIndexSnapshot": return DisplayType.SNAPSHOT; @@ -233,6 +236,8 @@ export const displayTypeToString = (type: DisplayType) => { switch (type) { case DisplayType.BACKUP: return m.op_type_backup(); + case DisplayType.BACKUP_DRYRUN: + return m.op_type_dry_run_backup(); case DisplayType.SNAPSHOT: return m.op_type_snapshot(); case DisplayType.FORGET: diff --git a/webui/src/api/oplog.ts b/webui/src/api/oplog.ts index 116a3fc6..0cdedcb4 100644 --- a/webui/src/api/oplog.ts +++ b/webui/src/api/oplog.ts @@ -70,11 +70,17 @@ export const unsubscribeFromOperations = ( }; export const shouldHideOperation = (operation: Operation) => { + // Hide successful backups with no snapshot ID (e.g., --skip-if-unchanged) + // but NOT dry run backups which intentionally have no snapshot + const isSkippedBackup = + operation.status === OperationStatus.STATUS_SUCCESS && + operation.op.case === "operationBackup" && + !operation.snapshotId && + !operation.op.value.dryRun; + return ( operation.op.case === "operationStats" || - (operation.status === OperationStatus.STATUS_SUCCESS && - operation.op.case === "operationBackup" && - !operation.snapshotId) || + isSkippedBackup || shouldHideStatus(operation.status) ); }; diff --git a/webui/src/features/operations/OperationIcon.tsx b/webui/src/features/operations/OperationIcon.tsx index 83feed8b..004b1be5 100644 --- a/webui/src/features/operations/OperationIcon.tsx +++ b/webui/src/features/operations/OperationIcon.tsx @@ -25,6 +25,7 @@ export const OperationIcon = ({ let avatar: React.ReactNode; switch (type) { case DisplayType.BACKUP: + case DisplayType.BACKUP_DRYRUN: avatar = ; break; case DisplayType.FORGET: diff --git a/webui/src/features/operations/OperationRow.tsx b/webui/src/features/operations/OperationRow.tsx index 636e4d54..6d062d04 100644 --- a/webui/src/features/operations/OperationRow.tsx +++ b/webui/src/features/operations/OperationRow.tsx @@ -239,7 +239,7 @@ export const OperationRow = ({ bodyItems.push({ key: "details", label: m.op_row_backup_details(), - children: , + children: , }); if (backupOp.errors.length > 0) { @@ -615,8 +615,10 @@ const RestoreOperationStatus = ({ operation }: { operation: Operation }) => { const BackupOperationStatus = ({ status, + dryRun, }: { status?: BackupProgressEntry; + dryRun?: boolean; }) => { if (!status) { return <>{m.op_row_no_status()}; @@ -674,7 +676,7 @@ const BackupOperationStatus = ({ {m.op_row_snapshot_id()} - {sum.snapshotId !== "" + {sum.snapshotId !== "" && !dryRun ? normalizeSnapshotId(sum.snapshotId!) : m.op_row_no_snapshot()} diff --git a/webui/src/features/plans/PlanView.tsx b/webui/src/features/plans/PlanView.tsx index 992f3889..956edff1 100644 --- a/webui/src/features/plans/PlanView.tsx +++ b/webui/src/features/plans/PlanView.tsx @@ -25,6 +25,7 @@ import { DoRepoTaskRequest_Task, DoRepoTaskRequestSchema, GetOperationsRequestSchema, + BackupRequestSchema, } from "../../../gen/ts/v1/service_pb"; import { SpinButton } from "../../components/common/SpinButton"; import { useShowModal } from "../../components/common/ModalManager"; @@ -41,13 +42,26 @@ export const PlanView = ({ plan }: React.PropsWithChildren<{ plan: Plan }>) => { const handleBackupNow = async () => { try { - await backrestService.backup({ value: plan.id }); + await backrestService.backup( + create(BackupRequestSchema, { value: plan.id }) + ); alerts.success(m.plan_backup_scheduled()); } catch (e: any) { alerts.error(m.plan_error_backup() + e.message); } }; + const handleDryRunBackup = async () => { + try { + await backrestService.backup( + create(BackupRequestSchema, { value: plan.id, dryRun: true }) + ); + alerts.success(m.plan_dry_run_scheduled()); + } catch (e: any) { + alerts.error(m.plan_dry_run_error() + e.message); + } + }; + const handleUnlockNow = async () => { try { alerts.info(m.repo_info_unlocking()); @@ -111,6 +125,9 @@ export const PlanView = ({ plan }: React.PropsWithChildren<{ plan: Plan }>) => { + + {m.op_type_dry_run_backup()} + {