corso/src/internal/operations/maintenance.go
ashmrtn 089a96d437
Create CLI command for maintenance (#3226)
Creates hidden CLI command to run
maintenance.

Flag names and descriptions can be
updated if something else would fit
better

---

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

- [ ]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [ ]  No

#### Type of change

- [x] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup

#### Issue(s)

* #3077

#### Test Plan

- [x] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
2023-05-16 21:03:06 +00:00

95 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"
)
// 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, 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
}