feat: support restic check operation (#303)

This commit is contained in:
Gareth
2024-05-27 10:26:18 -07:00
committed by GitHub
parent 5a51ae7c20
commit ce42f68d0d
43 changed files with 1807 additions and 989 deletions

View File

@@ -331,13 +331,42 @@ func (s *BackrestHandler) Forget(ctx context.Context, req *connect.Request[v1.Fo
return connect.NewResponse(&emptypb.Empty{}), nil
}
func (s *BackrestHandler) Prune(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) {
func (s BackrestHandler) DoRepoTask(ctx context.Context, req *connect.Request[v1.DoRepoTaskRequest]) (*connect.Response[emptypb.Empty], error) {
var task tasks.Task
priority := tasks.TaskPriorityInteractive
switch req.Msg.Task {
case v1.DoRepoTaskRequest_TASK_CHECK:
task = tasks.NewCheckTask(req.Msg.RepoId, tasks.PlanForSystemTasks, true)
case v1.DoRepoTaskRequest_TASK_PRUNE:
task = tasks.NewPruneTask(req.Msg.RepoId, tasks.PlanForSystemTasks, true)
priority |= tasks.TaskPriorityPrune
case v1.DoRepoTaskRequest_TASK_STATS:
task = tasks.NewStatsTask(req.Msg.RepoId, tasks.PlanForSystemTasks, true)
priority |= tasks.TaskPriorityStats
case v1.DoRepoTaskRequest_TASK_INDEX_SNAPSHOTS:
task = tasks.NewOneoffIndexSnapshotsTask(req.Msg.RepoId, time.Now())
priority |= tasks.TaskPriorityIndexSnapshots
case v1.DoRepoTaskRequest_TASK_UNLOCK:
repo, err := s.orchestrator.GetRepoOrchestrator(req.Msg.RepoId)
if err != nil {
return nil, fmt.Errorf("failed to get repo %q: %w", req.Msg.RepoId, err)
}
if err := repo.Unlock(ctx); err != nil {
return nil, fmt.Errorf("failed to unlock repo %q: %w", req.Msg.RepoId, err)
}
return connect.NewResponse(&emptypb.Empty{}), nil
default:
return nil, fmt.Errorf("unknown task %v", req.Msg.Task.String())
}
var err error
wait := make(chan struct{})
s.orchestrator.ScheduleTask(tasks.NewPruneTask(req.Msg.Value, tasks.PlanForSystemTasks, true), tasks.TaskPriorityInteractive+tasks.TaskPriorityPrune, func(e error) {
if err := s.orchestrator.ScheduleTask(task, priority, func(e error) {
err = e
close(wait)
})
}); err != nil {
return nil, err
}
<-wait
if err != nil {
return nil, err
@@ -370,32 +399,6 @@ func (s *BackrestHandler) Restore(ctx context.Context, req *connect.Request[v1.R
return connect.NewResponse(&emptypb.Empty{}), nil
}
func (s *BackrestHandler) Unlock(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) {
repo, err := s.orchestrator.GetRepoOrchestrator(req.Msg.Value)
if err != nil {
return nil, fmt.Errorf("failed to get repo %q: %w", req.Msg.Value, err)
}
if err := repo.Unlock(context.Background()); err != nil {
return nil, fmt.Errorf("failed to unlock repo %q: %w", req.Msg.Value, err)
}
return connect.NewResponse(&emptypb.Empty{}), nil
}
func (s *BackrestHandler) Stats(ctx context.Context, req *connect.Request[types.StringValue]) (*connect.Response[emptypb.Empty], error) {
var err error
wait := make(chan struct{})
if err := s.orchestrator.ScheduleTask(tasks.NewStatsTask(req.Msg.Value, tasks.PlanForSystemTasks, true), tasks.TaskPriorityInteractive+tasks.TaskPriorityStats, func(e error) {
err = e
close(wait)
}); err != nil {
return nil, err
}
<-wait
return connect.NewResponse(&emptypb.Empty{}), err
}
func (s *BackrestHandler) RunCommand(ctx context.Context, req *connect.Request[v1.RunCommandRequest], resp *connect.ServerStream[types.BytesValue]) error {
repo, err := s.orchestrator.GetRepoOrchestrator(req.Msg.RepoId)
if err != nil {

View File

@@ -179,8 +179,6 @@ func TestBackup(t *testing.T) {
}
func TestMultipleBackup(t *testing.T) {
t.Parallel()
sut := createSystemUnderTest(t, &config.MemoryStore{
Config: &v1.Config{
Modno: 1234,
@@ -218,7 +216,7 @@ func TestMultipleBackup(t *testing.T) {
sut.orch.Run(ctx)
}()
for i := 0; i < 2; i++ {
for i := 0; i < 3; i++ {
_, err := sut.handler.Backup(context.Background(), connect.NewRequest(&types.StringValue{Value: "test"}))
if err != nil {
t.Fatalf("Backup() error = %v", err)
@@ -230,7 +228,7 @@ func TestMultipleBackup(t *testing.T) {
operations := getOperations(t, sut.oplog)
if index := slices.IndexFunc(operations, func(op *v1.Operation) bool {
forget, ok := op.GetOp().(*v1.Operation_OperationForget)
return op.Status == v1.OperationStatus_STATUS_SUCCESS && ok && len(forget.OperationForget.Forget) == 1
return op.Status == v1.OperationStatus_STATUS_SUCCESS && ok && len(forget.OperationForget.Forget) > 0
}); index != -1 {
return nil
}
@@ -605,7 +603,7 @@ func retry(t *testing.T, times int, backoff time.Duration, f func() error) error
}
func getOperations(t *testing.T, oplog *oplog.OpLog) []*v1.Operation {
t.Logf("Reading oplog")
t.Logf("Reading oplog at time %v", time.Now())
operations := []*v1.Operation{}
if err := oplog.ForAll(func(op *v1.Operation) error {
operations = append(operations, op)