corso/src/internal/operations/maintenance.go
Keepers 5a78f478a1
add operations test for adv rest (#3783)
ads operations level tests for advanced restore
configuration on all three services.
Code is largely boilerplate between each service, but with just enough quirks that full consolidation would require excess jumping through hoops.

---

#### Does this PR need a docs update or release note?

- [x]  No

#### Type of change

- [x] 🤖 Supportability/Tests

#### Issue(s)

* #3562

#### Test Plan

- [x] 💚 E2E
2023-07-17 03:56:08 +00:00

96 lines
2.2 KiB
Go

package operations
import (
"context"
"time"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common/crash"
"github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/events"
"github.com/alcionai/corso/src/internal/kopia"
"github.com/alcionai/corso/src/internal/stats"
"github.com/alcionai/corso/src/pkg/control"
"github.com/alcionai/corso/src/pkg/control/repository"
"github.com/alcionai/corso/src/pkg/count"
)
// MaintenanceOperation wraps an operation with restore-specific props.
type MaintenanceOperation struct {
operation
Results MaintenanceResults
mOpts repository.Maintenance
}
// MaintenanceResults aggregate the details of the results of the operation.
type MaintenanceResults struct {
stats.StartAndEndTime
}
// NewMaintenanceOperation constructs and validates a maintenance operation.
func NewMaintenanceOperation(
ctx context.Context,
opts control.Options,
kw *kopia.Wrapper,
mOpts repository.Maintenance,
bus events.Eventer,
) (MaintenanceOperation, error) {
op := MaintenanceOperation{
operation: newOperation(opts, bus, count.New(), kw, nil),
mOpts: mOpts,
}
// Don't run validation because we don't populate the model store.
return op, nil
}
func (op *MaintenanceOperation) Run(ctx context.Context) (err error) {
defer func() {
if crErr := crash.Recovery(ctx, recover(), "maintenance"); crErr != nil {
err = crErr
}
}()
op.Results.StartedAt = time.Now()
op.bus.Event(
ctx,
events.MaintenanceStart,
map[string]any{
events.StartTime: op.Results.StartedAt,
})
defer func() {
op.bus.Event(
ctx,
events.MaintenanceEnd,
map[string]any{
events.StartTime: op.Results.StartedAt,
events.Duration: op.Results.CompletedAt.Sub(op.Results.StartedAt),
events.EndTime: dttm.Format(op.Results.CompletedAt),
events.Status: op.Status.String(),
events.Resources: op.mOpts.Type.String(),
})
}()
return op.do(ctx)
}
func (op *MaintenanceOperation) do(ctx context.Context) error {
defer func() {
op.Results.CompletedAt = time.Now()
}()
err := op.operation.kopia.RepoMaintenance(ctx, op.mOpts)
if err != nil {
op.Status = Failed
return clues.Wrap(err, "running maintenance operation")
}
op.Status = Completed
return nil
}