Execute does the actual pruning: - remove unreferenced packs first - repack given pack files while keeping the given blobs - rebuild the index while ignoring all files that will be deleted - delete the files plan.removePacks and plan.ignorePacks are modified in this function.
(ctx context.Context, printer progress.Printer)
| 568 | // - delete the files |
| 569 | // plan.removePacks and plan.ignorePacks are modified in this function. |
| 570 | func (plan *PrunePlan) Execute(ctx context.Context, printer progress.Printer) error { |
| 571 | if plan.opts.DryRun { |
| 572 | printer.V("Repeated prune dry-runs can report slightly different amounts of data to keep or repack. This is expected behavior.\n\n") |
| 573 | if len(plan.removePacksFirst) > 0 { |
| 574 | printer.V("Would have removed the following unreferenced packs:\n%v\n\n", plan.removePacksFirst) |
| 575 | } |
| 576 | printer.V("Would have repacked and removed the following packs:\n%v\n\n", plan.repackPacks) |
| 577 | printer.V("Would have removed the following no longer used packs:\n%v\n\n", plan.removePacks) |
| 578 | // Always quit here if DryRun was set! |
| 579 | return nil |
| 580 | } |
| 581 | |
| 582 | repo := plan.repo |
| 583 | // make sure the plan can only be used once |
| 584 | plan.repo = nil |
| 585 | |
| 586 | // unreferenced packs can be safely deleted first |
| 587 | if len(plan.removePacksFirst) != 0 { |
| 588 | printer.P("deleting unreferenced packs\n") |
| 589 | _ = deleteFiles(ctx, true, &internalRepository{repo}, plan.removePacksFirst, restic.PackFile, printer) |
| 590 | // forget unused data |
| 591 | plan.removePacksFirst = nil |
| 592 | } |
| 593 | if ctx.Err() != nil { |
| 594 | return ctx.Err() |
| 595 | } |
| 596 | |
| 597 | if len(plan.repackPacks) != 0 { |
| 598 | printer.P("repacking packs\n") |
| 599 | bar := printer.NewCounter("packs repacked") |
| 600 | err := repo.WithBlobUploader(ctx, func(ctx context.Context, uploader restic.BlobSaverWithAsync) error { |
| 601 | return CopyBlobs(ctx, repo, repo, uploader, plan.repackPacks, plan.keepBlobs, bar, printer.P) |
| 602 | }) |
| 603 | if err != nil { |
| 604 | return errors.Fatalf("%s", err) |
| 605 | } |
| 606 | |
| 607 | // Also remove repacked packs |
| 608 | plan.removePacks.Merge(plan.repackPacks) |
| 609 | // forget unused data |
| 610 | plan.repackPacks = nil |
| 611 | |
| 612 | if plan.keepBlobs.Len() != 0 { |
| 613 | printer.E("%v was not repacked\n\n"+ |
| 614 | "Integrity check failed.\n"+ |
| 615 | "Please report this error (along with the output of the 'prune' run) at\n"+ |
| 616 | "https://github.com/restic/restic/issues/new/choose", plan.keepBlobs) |
| 617 | return errors.Fatal("internal error: blobs were not repacked") |
| 618 | } |
| 619 | |
| 620 | // allow GC of the blob set |
| 621 | plan.keepBlobs = nil |
| 622 | } |
| 623 | |
| 624 | if len(plan.ignorePacks) == 0 { |
| 625 | plan.ignorePacks = plan.removePacks |
| 626 | } else { |
| 627 | plan.ignorePacks.Merge(plan.removePacks) |