diff --git a/gen/go/v1/service.pb.go b/gen/go/v1/service.pb.go index 64101297..9419402b 100644 --- a/gen/go/v1/service.pb.go +++ b/gen/go/v1/service.pb.go @@ -594,7 +594,7 @@ var file_v1_service_proto_rawDesc = []byte{ 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x32, 0xb4, 0x07, 0x0a, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x32, 0xf4, 0x07, 0x0a, 0x08, 0x42, 0x61, 0x63, 0x6b, 0x72, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0a, @@ -621,7 +621,11 @@ var file_v1_service_proto_rawDesc = []byte{ 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x06, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x06, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, @@ -700,33 +704,35 @@ var file_v1_service_proto_depIdxs = []int32{ 2, // 5: v1.Backrest.GetOperations:input_type -> v1.GetOperationsRequest 1, // 6: v1.Backrest.ListSnapshots:input_type -> v1.ListSnapshotsRequest 4, // 7: v1.Backrest.ListSnapshotFiles:input_type -> v1.ListSnapshotFilesRequest - 10, // 8: v1.Backrest.Backup:input_type -> types.StringValue - 10, // 9: v1.Backrest.Prune:input_type -> types.StringValue - 10, // 10: v1.Backrest.Forget:input_type -> types.StringValue - 3, // 11: v1.Backrest.Restore:input_type -> v1.RestoreSnapshotRequest - 10, // 12: v1.Backrest.Unlock:input_type -> types.StringValue - 10, // 13: v1.Backrest.Stats:input_type -> types.StringValue - 11, // 14: v1.Backrest.Cancel:input_type -> types.Int64Value - 0, // 15: v1.Backrest.ClearHistory:input_type -> v1.ClearHistoryRequest - 10, // 16: v1.Backrest.PathAutocomplete:input_type -> types.StringValue - 8, // 17: v1.Backrest.GetConfig:output_type -> v1.Config - 8, // 18: v1.Backrest.SetConfig:output_type -> v1.Config - 8, // 19: v1.Backrest.AddRepo:output_type -> v1.Config - 12, // 20: v1.Backrest.GetOperationEvents:output_type -> v1.OperationEvent - 13, // 21: v1.Backrest.GetOperations:output_type -> v1.OperationList - 14, // 22: v1.Backrest.ListSnapshots:output_type -> v1.ResticSnapshotList - 5, // 23: v1.Backrest.ListSnapshotFiles:output_type -> v1.ListSnapshotFilesResponse - 7, // 24: v1.Backrest.Backup:output_type -> google.protobuf.Empty - 7, // 25: v1.Backrest.Prune:output_type -> google.protobuf.Empty - 7, // 26: v1.Backrest.Forget:output_type -> google.protobuf.Empty - 7, // 27: v1.Backrest.Restore:output_type -> google.protobuf.Empty - 7, // 28: v1.Backrest.Unlock:output_type -> google.protobuf.Empty - 7, // 29: v1.Backrest.Stats:output_type -> google.protobuf.Empty - 7, // 30: v1.Backrest.Cancel:output_type -> google.protobuf.Empty - 7, // 31: v1.Backrest.ClearHistory:output_type -> google.protobuf.Empty - 15, // 32: v1.Backrest.PathAutocomplete:output_type -> types.StringList - 17, // [17:33] is the sub-list for method output_type - 1, // [1:17] is the sub-list for method input_type + 10, // 8: v1.Backrest.IndexSnapshots:input_type -> types.StringValue + 10, // 9: v1.Backrest.Backup:input_type -> types.StringValue + 10, // 10: v1.Backrest.Prune:input_type -> types.StringValue + 10, // 11: v1.Backrest.Forget:input_type -> types.StringValue + 3, // 12: v1.Backrest.Restore:input_type -> v1.RestoreSnapshotRequest + 10, // 13: v1.Backrest.Unlock:input_type -> types.StringValue + 10, // 14: v1.Backrest.Stats:input_type -> types.StringValue + 11, // 15: v1.Backrest.Cancel:input_type -> types.Int64Value + 0, // 16: v1.Backrest.ClearHistory:input_type -> v1.ClearHistoryRequest + 10, // 17: v1.Backrest.PathAutocomplete:input_type -> types.StringValue + 8, // 18: v1.Backrest.GetConfig:output_type -> v1.Config + 8, // 19: v1.Backrest.SetConfig:output_type -> v1.Config + 8, // 20: v1.Backrest.AddRepo:output_type -> v1.Config + 12, // 21: v1.Backrest.GetOperationEvents:output_type -> v1.OperationEvent + 13, // 22: v1.Backrest.GetOperations:output_type -> v1.OperationList + 14, // 23: v1.Backrest.ListSnapshots:output_type -> v1.ResticSnapshotList + 5, // 24: v1.Backrest.ListSnapshotFiles:output_type -> v1.ListSnapshotFilesResponse + 7, // 25: v1.Backrest.IndexSnapshots:output_type -> google.protobuf.Empty + 7, // 26: v1.Backrest.Backup:output_type -> google.protobuf.Empty + 7, // 27: v1.Backrest.Prune:output_type -> google.protobuf.Empty + 7, // 28: v1.Backrest.Forget:output_type -> google.protobuf.Empty + 7, // 29: v1.Backrest.Restore:output_type -> google.protobuf.Empty + 7, // 30: v1.Backrest.Unlock:output_type -> google.protobuf.Empty + 7, // 31: v1.Backrest.Stats:output_type -> google.protobuf.Empty + 7, // 32: v1.Backrest.Cancel:output_type -> google.protobuf.Empty + 7, // 33: v1.Backrest.ClearHistory:output_type -> google.protobuf.Empty + 15, // 34: v1.Backrest.PathAutocomplete:output_type -> types.StringList + 18, // [18:35] is the sub-list for method output_type + 1, // [1:18] is the sub-list for method input_type 1, // [1:1] is the sub-list for extension type_name 1, // [1:1] is the sub-list for extension extendee 0, // [0:1] is the sub-list for field type_name diff --git a/gen/go/v1/service_grpc.pb.go b/gen/go/v1/service_grpc.pb.go index 0e37654c..cde04127 100644 --- a/gen/go/v1/service_grpc.pb.go +++ b/gen/go/v1/service_grpc.pb.go @@ -28,6 +28,7 @@ const ( Backrest_GetOperations_FullMethodName = "/v1.Backrest/GetOperations" Backrest_ListSnapshots_FullMethodName = "/v1.Backrest/ListSnapshots" Backrest_ListSnapshotFiles_FullMethodName = "/v1.Backrest/ListSnapshotFiles" + Backrest_IndexSnapshots_FullMethodName = "/v1.Backrest/IndexSnapshots" Backrest_Backup_FullMethodName = "/v1.Backrest/Backup" Backrest_Prune_FullMethodName = "/v1.Backrest/Prune" Backrest_Forget_FullMethodName = "/v1.Backrest/Forget" @@ -50,11 +51,13 @@ type BackrestClient interface { GetOperations(ctx context.Context, in *GetOperationsRequest, opts ...grpc.CallOption) (*OperationList, error) ListSnapshots(ctx context.Context, in *ListSnapshotsRequest, opts ...grpc.CallOption) (*ResticSnapshotList, error) ListSnapshotFiles(ctx context.Context, in *ListSnapshotFilesRequest, opts ...grpc.CallOption) (*ListSnapshotFilesResponse, error) + // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. + IndexSnapshots(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. Backup(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) - // Prune schedules a prune operation. + // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. Prune(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) - // Forget schedules a forget operation. + // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. Forget(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) // Restore schedules a restore operation. Restore(ctx context.Context, in *RestoreSnapshotRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) @@ -164,6 +167,15 @@ func (c *backrestClient) ListSnapshotFiles(ctx context.Context, in *ListSnapshot return out, nil } +func (c *backrestClient) IndexSnapshots(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, Backrest_IndexSnapshots_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *backrestClient) Backup(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, Backrest_Backup_FullMethodName, in, out, opts...) @@ -256,11 +268,13 @@ type BackrestServer interface { GetOperations(context.Context, *GetOperationsRequest) (*OperationList, error) ListSnapshots(context.Context, *ListSnapshotsRequest) (*ResticSnapshotList, error) ListSnapshotFiles(context.Context, *ListSnapshotFilesRequest) (*ListSnapshotFilesResponse, error) + // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. + IndexSnapshots(context.Context, *types.StringValue) (*emptypb.Empty, error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. Backup(context.Context, *types.StringValue) (*emptypb.Empty, error) - // Prune schedules a prune operation. + // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. Prune(context.Context, *types.StringValue) (*emptypb.Empty, error) - // Forget schedules a forget operation. + // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. Forget(context.Context, *types.StringValue) (*emptypb.Empty, error) // Restore schedules a restore operation. Restore(context.Context, *RestoreSnapshotRequest) (*emptypb.Empty, error) @@ -302,6 +316,9 @@ func (UnimplementedBackrestServer) ListSnapshots(context.Context, *ListSnapshots func (UnimplementedBackrestServer) ListSnapshotFiles(context.Context, *ListSnapshotFilesRequest) (*ListSnapshotFilesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListSnapshotFiles not implemented") } +func (UnimplementedBackrestServer) IndexSnapshots(context.Context, *types.StringValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method IndexSnapshots not implemented") +} func (UnimplementedBackrestServer) Backup(context.Context, *types.StringValue) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method Backup not implemented") } @@ -471,6 +488,24 @@ func _Backrest_ListSnapshotFiles_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _Backrest_IndexSnapshots_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(types.StringValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackrestServer).IndexSnapshots(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Backrest_IndexSnapshots_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackrestServer).IndexSnapshots(ctx, req.(*types.StringValue)) + } + return interceptor(ctx, in, info, handler) +} + func _Backrest_Backup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(types.StringValue) if err := dec(in); err != nil { @@ -664,6 +699,10 @@ var Backrest_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListSnapshotFiles", Handler: _Backrest_ListSnapshotFiles_Handler, }, + { + MethodName: "IndexSnapshots", + Handler: _Backrest_IndexSnapshots_Handler, + }, { MethodName: "Backup", Handler: _Backrest_Backup_Handler, diff --git a/gen/go/v1/v1connect/service.connect.go b/gen/go/v1/v1connect/service.connect.go index 63a7570b..711c5a32 100644 --- a/gen/go/v1/v1connect/service.connect.go +++ b/gen/go/v1/v1connect/service.connect.go @@ -51,6 +51,8 @@ const ( // BackrestListSnapshotFilesProcedure is the fully-qualified name of the Backrest's // ListSnapshotFiles RPC. BackrestListSnapshotFilesProcedure = "/v1.Backrest/ListSnapshotFiles" + // BackrestIndexSnapshotsProcedure is the fully-qualified name of the Backrest's IndexSnapshots RPC. + BackrestIndexSnapshotsProcedure = "/v1.Backrest/IndexSnapshots" // BackrestBackupProcedure is the fully-qualified name of the Backrest's Backup RPC. BackrestBackupProcedure = "/v1.Backrest/Backup" // BackrestPruneProcedure is the fully-qualified name of the Backrest's Prune RPC. @@ -82,6 +84,7 @@ var ( backrestGetOperationsMethodDescriptor = backrestServiceDescriptor.Methods().ByName("GetOperations") backrestListSnapshotsMethodDescriptor = backrestServiceDescriptor.Methods().ByName("ListSnapshots") backrestListSnapshotFilesMethodDescriptor = backrestServiceDescriptor.Methods().ByName("ListSnapshotFiles") + backrestIndexSnapshotsMethodDescriptor = backrestServiceDescriptor.Methods().ByName("IndexSnapshots") backrestBackupMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Backup") backrestPruneMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Prune") backrestForgetMethodDescriptor = backrestServiceDescriptor.Methods().ByName("Forget") @@ -102,11 +105,13 @@ type BackrestClient interface { GetOperations(context.Context, *connect.Request[v1.GetOperationsRequest]) (*connect.Response[v1.OperationList], error) ListSnapshots(context.Context, *connect.Request[v1.ListSnapshotsRequest]) (*connect.Response[v1.ResticSnapshotList], error) ListSnapshotFiles(context.Context, *connect.Request[v1.ListSnapshotFilesRequest]) (*connect.Response[v1.ListSnapshotFilesResponse], error) + // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. + IndexSnapshots(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. Backup(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) - // Prune schedules a prune operation. + // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. Prune(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) - // Forget schedules a forget operation. + // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. Forget(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) // Restore schedules a restore operation. Restore(context.Context, *connect.Request[v1.RestoreSnapshotRequest]) (*connect.Response[emptypb.Empty], error) @@ -174,6 +179,12 @@ func NewBackrestClient(httpClient connect.HTTPClient, baseURL string, opts ...co connect.WithSchema(backrestListSnapshotFilesMethodDescriptor), connect.WithClientOptions(opts...), ), + indexSnapshots: connect.NewClient[types.StringValue, emptypb.Empty]( + httpClient, + baseURL+BackrestIndexSnapshotsProcedure, + connect.WithSchema(backrestIndexSnapshotsMethodDescriptor), + connect.WithClientOptions(opts...), + ), backup: connect.NewClient[types.StringValue, emptypb.Empty]( httpClient, baseURL+BackrestBackupProcedure, @@ -240,6 +251,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] + indexSnapshots *connect.Client[types.StringValue, emptypb.Empty] backup *connect.Client[types.StringValue, emptypb.Empty] prune *connect.Client[types.StringValue, emptypb.Empty] forget *connect.Client[types.StringValue, emptypb.Empty] @@ -286,6 +298,11 @@ func (c *backrestClient) ListSnapshotFiles(ctx context.Context, req *connect.Req return c.listSnapshotFiles.CallUnary(ctx, req) } +// IndexSnapshots calls v1.Backrest.IndexSnapshots. +func (c *backrestClient) IndexSnapshots(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { + return c.indexSnapshots.CallUnary(ctx, req) +} + // Backup calls v1.Backrest.Backup. func (c *backrestClient) Backup(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { return c.backup.CallUnary(ctx, req) @@ -340,11 +357,13 @@ type BackrestHandler interface { GetOperations(context.Context, *connect.Request[v1.GetOperationsRequest]) (*connect.Response[v1.OperationList], error) ListSnapshots(context.Context, *connect.Request[v1.ListSnapshotsRequest]) (*connect.Response[v1.ResticSnapshotList], error) ListSnapshotFiles(context.Context, *connect.Request[v1.ListSnapshotFilesRequest]) (*connect.Response[v1.ListSnapshotFilesResponse], error) + // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. + IndexSnapshots(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. Backup(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) - // Prune schedules a prune operation. + // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. Prune(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) - // Forget schedules a forget operation. + // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. Forget(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) // Restore schedules a restore operation. Restore(context.Context, *connect.Request[v1.RestoreSnapshotRequest]) (*connect.Response[emptypb.Empty], error) @@ -408,6 +427,12 @@ func NewBackrestHandler(svc BackrestHandler, opts ...connect.HandlerOption) (str connect.WithSchema(backrestListSnapshotFilesMethodDescriptor), connect.WithHandlerOptions(opts...), ) + backrestIndexSnapshotsHandler := connect.NewUnaryHandler( + BackrestIndexSnapshotsProcedure, + svc.IndexSnapshots, + connect.WithSchema(backrestIndexSnapshotsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) backrestBackupHandler := connect.NewUnaryHandler( BackrestBackupProcedure, svc.Backup, @@ -478,6 +503,8 @@ func NewBackrestHandler(svc BackrestHandler, opts ...connect.HandlerOption) (str backrestListSnapshotsHandler.ServeHTTP(w, r) case BackrestListSnapshotFilesProcedure: backrestListSnapshotFilesHandler.ServeHTTP(w, r) + case BackrestIndexSnapshotsProcedure: + backrestIndexSnapshotsHandler.ServeHTTP(w, r) case BackrestBackupProcedure: backrestBackupHandler.ServeHTTP(w, r) case BackrestPruneProcedure: @@ -533,6 +560,10 @@ func (UnimplementedBackrestHandler) ListSnapshotFiles(context.Context, *connect. return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.ListSnapshotFiles is not implemented")) } +func (UnimplementedBackrestHandler) IndexSnapshots(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.IndexSnapshots is not implemented")) +} + func (UnimplementedBackrestHandler) Backup(context.Context, *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("v1.Backrest.Backup is not implemented")) } diff --git a/internal/api/server.go b/internal/api/server.go index b4028648..1e0f0537 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -111,6 +111,9 @@ func (s *Server) AddRepo(ctx context.Context, req *connect.Request[v1.Repo]) (*c s.orchestrator.ApplyConfig(c) + // index snapshots for the newly added repository. + s.orchestrator.ScheduleTask(orchestrator.NewOneoffIndexSnapshotsTask(s.orchestrator, req.Msg.Id, time.Now()), orchestrator.TaskPriorityInteractive+orchestrator.TaskPriorityIndexSnapshots) + return connect.NewResponse(c), nil } @@ -249,6 +252,17 @@ func (s *Server) GetOperations(ctx context.Context, req *connect.Request[v1.GetO }), nil } +func (s *Server) IndexSnapshots(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { + _, err := s.orchestrator.GetRepo(req.Msg.Value) + if err != nil { + return nil, fmt.Errorf("failed to get repo %q: %w", req.Msg.Value, err) + } + + s.orchestrator.ScheduleTask(orchestrator.NewOneoffIndexSnapshotsTask(s.orchestrator, req.Msg.Value, time.Now()), orchestrator.TaskPriorityInteractive+orchestrator.TaskPriorityIndexSnapshots) + + return connect.NewResponse(&emptypb.Empty{}), nil +} + func (s *Server) Backup(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) { plan, err := s.orchestrator.GetPlan(req.Msg.Value) if err != nil { @@ -267,7 +281,7 @@ func (s *Server) Forget(ctx context.Context, req *connect.Request[types.StringVa at := time.Now() s.orchestrator.ScheduleTask(orchestrator.NewOneoffForgetTask(s.orchestrator, plan, "", at), orchestrator.TaskPriorityInteractive+orchestrator.TaskPriorityForget) - s.orchestrator.ScheduleTask(orchestrator.NewOneoffIndexSnapshotsTask(s.orchestrator, plan, at), orchestrator.TaskPriorityInteractive+orchestrator.TaskPriorityIndexSnapshots) + s.orchestrator.ScheduleTask(orchestrator.NewOneoffIndexSnapshotsTask(s.orchestrator, plan.Repo, at), orchestrator.TaskPriorityInteractive+orchestrator.TaskPriorityIndexSnapshots) return connect.NewResponse(&emptypb.Empty{}), nil } diff --git a/internal/orchestrator/orchestrator.go b/internal/orchestrator/orchestrator.go index e6d63956..97a2884a 100644 --- a/internal/orchestrator/orchestrator.go +++ b/internal/orchestrator/orchestrator.go @@ -229,10 +229,11 @@ func (o *Orchestrator) Run(mainCtx context.Context) { zap.L().Fatal("failed to start task, another task is already running. Was Run() called twice?") } + start := time.Now() if err := t.task.Run(taskCtx); err != nil { zap.L().Error("task failed", zap.String("task", t.task.Name()), zap.Error(err)) } else { - zap.L().Info("task finished", zap.String("task", t.task.Name())) + zap.L().Info("task finished", zap.String("task", t.task.Name()), zap.Duration("duration", time.Since(start))) } o.runningTask.Store(nil) diff --git a/internal/orchestrator/taskbackup.go b/internal/orchestrator/taskbackup.go index dca7724a..1dcbe15a 100644 --- a/internal/orchestrator/taskbackup.go +++ b/internal/orchestrator/taskbackup.go @@ -145,7 +145,7 @@ func backupHelper(ctx context.Context, orchestrator *Orchestrator, plan *v1.Plan orchestrator.ScheduleTask(NewOneoffForgetTask(orchestrator, plan, op.SnapshotId, at), TaskPriorityForget) } - orchestrator.ScheduleTask(NewOneoffIndexSnapshotsTask(orchestrator, plan, at), TaskPriorityIndexSnapshots) + orchestrator.ScheduleTask(NewOneoffIndexSnapshotsTask(orchestrator, plan.Repo, at), TaskPriorityIndexSnapshots) orchestrator.ScheduleTask(NewOneoffStatsTask(orchestrator, plan, op.SnapshotId, at), TaskPriorityStats) return nil diff --git a/internal/orchestrator/taskindexsnapshots.go b/internal/orchestrator/taskindexsnapshots.go index 458d5bd3..aded8735 100644 --- a/internal/orchestrator/taskindexsnapshots.go +++ b/internal/orchestrator/taskindexsnapshots.go @@ -3,6 +3,7 @@ package orchestrator import ( "context" "fmt" + "strings" "time" v1 "github.com/garethgeorge/backrest/gen/go/v1" @@ -12,25 +13,27 @@ import ( "go.uber.org/zap" ) +const planForUntrackedSnapshots = "_unassociated_" + // IndexSnapshotsTask tracks a forget operation. type IndexSnapshotsTask struct { orchestrator *Orchestrator // owning orchestrator - plan *v1.Plan + repoId string at *time.Time } var _ Task = &IndexSnapshotsTask{} -func NewOneoffIndexSnapshotsTask(orchestrator *Orchestrator, plan *v1.Plan, at time.Time) *IndexSnapshotsTask { +func NewOneoffIndexSnapshotsTask(orchestrator *Orchestrator, repoId string, at time.Time) *IndexSnapshotsTask { return &IndexSnapshotsTask{ orchestrator: orchestrator, - plan: plan, + repoId: repoId, at: &at, } } func (t *IndexSnapshotsTask) Name() string { - return fmt.Sprintf("index snapshots for plan %q", t.plan.Id) + return fmt.Sprintf("index snapshots for plan %q", t.repoId) } func (t *IndexSnapshotsTask) Next(now time.Time) *time.Time { @@ -42,7 +45,7 @@ func (t *IndexSnapshotsTask) Next(now time.Time) *time.Time { } func (t *IndexSnapshotsTask) Run(ctx context.Context) error { - return indexSnapshotsHelper(ctx, t.orchestrator, t.plan) + return indexSnapshotsHelper(ctx, t.orchestrator, t.repoId) } func (t *IndexSnapshotsTask) Cancel(withStatus v1.OperationStatus) error { @@ -57,22 +60,22 @@ func (t *IndexSnapshotsTask) OperationId() int64 { // - If the snapshot is already indexed, it is skipped. // - If the snapshot is not indexed, an index snapshot operation with it's metadata is added. // - If an index snapshot operation is found for a snapshot that is not returned by the repo, it is marked as forgotten. -func indexSnapshotsHelper(ctx context.Context, orchestrator *Orchestrator, plan *v1.Plan) error { - repo, err := orchestrator.GetRepo(plan.Repo) +func indexSnapshotsHelper(ctx context.Context, orchestrator *Orchestrator, repoId string) error { + repo, err := orchestrator.GetRepo(repoId) if err != nil { - return fmt.Errorf("couldn't get repo %q: %w", plan.Repo, err) + return fmt.Errorf("couldn't get repo %q: %w", repoId, err) } // collect all tracked snapshots for the plan. - snapshots, err := repo.SnapshotsForPlan(ctx, plan) + snapshots, err := repo.Snapshots(ctx) if err != nil { - return fmt.Errorf("get snapshots for plan %q: %w", plan.Id, err) + return fmt.Errorf("get snapshots for repo %q: %w", repoId, err) } // collect all current snapshot IDs. - currentIds, err := indexCurrentSnapshotIdsForPlan(orchestrator.OpLog, plan.Id) + currentIds, err := indexCurrentSnapshotIdsForRepo(orchestrator.OpLog, repoId) if err != nil { - return fmt.Errorf("get known snapshot IDs for plan %q: %w", plan.Id, err) + return fmt.Errorf("get known snapshot IDs for repo %q: %w", repoId, err) } foundIds := make(map[string]bool) @@ -87,9 +90,10 @@ func indexSnapshotsHelper(ctx context.Context, orchestrator *Orchestrator, plan } snapshotProto := protoutil.SnapshotToProto(snapshot) + planId := planForSnapshot(snapshotProto) indexOps = append(indexOps, &v1.Operation{ - RepoId: plan.Repo, - PlanId: plan.Id, + RepoId: repoId, + PlanId: planId, UnixTimeStartMs: snapshotProto.UnixTimeMs, UnixTimeEndMs: snapshotProto.UnixTimeMs, Status: v1.OperationStatus_STATUS_SUCCESS, @@ -107,14 +111,13 @@ func indexSnapshotsHelper(ctx context.Context, orchestrator *Orchestrator, plan } // Mark missing operations as newly forgotten. - var forgetIds []int64 for id, opId := range currentIds { - if _, ok := foundIds[id]; !ok { - forgetIds = append(forgetIds, opId) + if _, ok := foundIds[id]; ok { + // skip snapshots that were found. + continue } - } - for _, opId := range forgetIds { + // mark snapshot forgotten. op, err := orchestrator.OpLog.Get(opId) if err != nil { // should only be possible in the case of a data race (e.g. operation was somehow deleted). @@ -134,7 +137,7 @@ func indexSnapshotsHelper(ctx context.Context, orchestrator *Orchestrator, plan // Print stats at the end of indexing. zap.L().Debug("Indexed snapshots", - zap.String("plan", plan.Id), + zap.String("repo", repoId), zap.Duration("duration", time.Since(startTime)), zap.Int("alreadyIndexed", len(foundIds)), zap.Int("newlyAdded", len(indexOps)), @@ -145,14 +148,14 @@ func indexSnapshotsHelper(ctx context.Context, orchestrator *Orchestrator, plan } // returns a map of current (e.g. not forgotten) snapshot IDs for the plan. -func indexCurrentSnapshotIdsForPlan(log *oplog.OpLog, planId string) (map[string]int64, error) { +func indexCurrentSnapshotIdsForRepo(log *oplog.OpLog, repoId string) (map[string]int64, error) { knownIds := make(map[string]int64) startTime := time.Now() - if err := log.ForEachByPlan(planId, indexutil.CollectAll(), func(op *v1.Operation) error { + if err := log.ForEachByRepo(repoId, indexutil.CollectAll(), func(op *v1.Operation) error { if snapshotOp, ok := op.Op.(*v1.Operation_OperationIndexSnapshot); ok { if snapshotOp.OperationIndexSnapshot == nil { - return fmt.Errorf("operation %q has nil OperationIndexSnapshot, this shouldn't be possible.", op.Id) + return fmt.Errorf("operation %q has nil OperationIndexSnapshot, this shouldn't be possible", op.Id) } if !snapshotOp.OperationIndexSnapshot.Forgot { knownIds[snapshotOp.OperationIndexSnapshot.Snapshot.Id] = op.Id @@ -162,6 +165,15 @@ func indexCurrentSnapshotIdsForPlan(log *oplog.OpLog, planId string) (map[string }); err != nil { return nil, err } - zap.S().Debugf("Indexed known (and not forgotten) snapshot IDs for plan %v in %v", planId, time.Since(startTime)) + zap.S().Debugf("Indexed known (and not forgotten) snapshot IDs for plan %v in %v", repoId, time.Since(startTime)) return knownIds, nil } + +func planForSnapshot(snapshot *v1.ResticSnapshot) string { + for _, tag := range snapshot.Tags { + if strings.HasPrefix(tag, "plan:") { + return tag[5:] + } + } + return planForUntrackedSnapshots +} diff --git a/internal/orchestrator/taskstats.go b/internal/orchestrator/taskstats.go index 7fbaeae8..c63530f3 100644 --- a/internal/orchestrator/taskstats.go +++ b/internal/orchestrator/taskstats.go @@ -54,7 +54,6 @@ func (t *StatsTask) shouldRun() (bool, error) { } zap.L().Debug("bytes since last stat", zap.Int64("bytes", bytesSinceLastStat), zap.String("repo", t.plan.Repo)) - if bytesSinceLastStat == -1 || bytesSinceLastStat > statBytesThreshold { zap.S().Debugf("bytes since last stat (%v) exceeds threshold (%v)", bytesSinceLastStat, statBytesThreshold) return true, nil diff --git a/proto/v1/service.proto b/proto/v1/service.proto index b5dd52c2..15610366 100644 --- a/proto/v1/service.proto +++ b/proto/v1/service.proto @@ -26,13 +26,16 @@ service Backrest { rpc ListSnapshotFiles(ListSnapshotFilesRequest) returns (ListSnapshotFilesResponse) {} + // IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. + rpc IndexSnapshots(types.StringValue) returns (google.protobuf.Empty) {} + // Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. rpc Backup(types.StringValue) returns (google.protobuf.Empty) {} - // Prune schedules a prune operation. + // Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. rpc Prune(types.StringValue) returns (google.protobuf.Empty) {} - // Forget schedules a forget operation. + // Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. rpc Forget(types.StringValue) returns (google.protobuf.Empty) {} // Restore schedules a restore operation. diff --git a/webui/gen/ts/v1/service_connect.ts b/webui/gen/ts/v1/service_connect.ts index fffbd6c6..dad69b09 100644 --- a/webui/gen/ts/v1/service_connect.ts +++ b/webui/gen/ts/v1/service_connect.ts @@ -79,6 +79,17 @@ export const Backrest = { O: ListSnapshotFilesResponse, kind: MethodKind.Unary, }, + /** + * IndexSnapshots triggers indexin. It accepts a repo id and returns empty if the task is enqueued. + * + * @generated from rpc v1.Backrest.IndexSnapshots + */ + indexSnapshots: { + name: "IndexSnapshots", + I: StringValue, + O: Empty, + kind: MethodKind.Unary, + }, /** * Backup schedules a backup operation. It accepts a plan id and returns empty if the task is enqueued. * @@ -91,7 +102,7 @@ export const Backrest = { kind: MethodKind.Unary, }, /** - * Prune schedules a prune operation. + * Prune schedules a prune operation. It accepts a plan id and returns empty if the task is enqueued. * * @generated from rpc v1.Backrest.Prune */ @@ -102,7 +113,7 @@ export const Backrest = { kind: MethodKind.Unary, }, /** - * Forget schedules a forget operation. + * Forget schedules a forget operation. It accepts a plan id and returns empty if the task is enqueued. * * @generated from rpc v1.Backrest.Forget */