mirror of
https://github.com/garethgeorge/backrest.git
synced 2026-07-08 11:10:43 +00:00
feat: index snapshots created outside of backrest
This commit is contained in:
+35
-29
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
|
||||
+15
-1
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user