mirror of
https://github.com/octoleo/restic.git
synced 2024-11-11 07:41:03 +00:00
prune: clean up internal interface
This commit is contained in:
parent
8d507c1372
commit
d8622c86eb
@ -191,7 +191,7 @@ func runPruneWithRepo(ctx context.Context, opts PruneOptions, gopts GlobalOption
|
|||||||
RepackUncompressed: opts.RepackUncompressed,
|
RepackUncompressed: opts.RepackUncompressed,
|
||||||
}
|
}
|
||||||
|
|
||||||
plan, stats, err := repository.PlanPrune(ctx, popts, repo, func(ctx context.Context, repo restic.Repository) (usedBlobs restic.CountedBlobSet, err error) {
|
plan, err := repository.PlanPrune(ctx, popts, repo, func(ctx context.Context, repo restic.Repository) (usedBlobs restic.CountedBlobSet, err error) {
|
||||||
return getUsedBlobs(ctx, repo, ignoreSnapshots, printer)
|
return getUsedBlobs(ctx, repo, ignoreSnapshots, printer)
|
||||||
}, printer)
|
}, printer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -202,7 +202,7 @@ func runPruneWithRepo(ctx context.Context, opts PruneOptions, gopts GlobalOption
|
|||||||
printer.P("\nWould have made the following changes:")
|
printer.P("\nWould have made the following changes:")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = printPruneStats(printer, stats)
|
err = printPruneStats(printer, plan.Stats())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ func runPruneWithRepo(ctx context.Context, opts PruneOptions, gopts GlobalOption
|
|||||||
// Trigger GC to reset garbage collection threshold
|
// Trigger GC to reset garbage collection threshold
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
|
|
||||||
return repository.DoPrune(ctx, popts, repo, plan, printer)
|
return plan.Execute(ctx, printer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// printPruneStats prints out the statistics
|
// printPruneStats prints out the statistics
|
||||||
|
@ -66,6 +66,10 @@ type PrunePlan struct {
|
|||||||
keepBlobs restic.CountedBlobSet // blobs to keep during repacking
|
keepBlobs restic.CountedBlobSet // blobs to keep during repacking
|
||||||
removePacks restic.IDSet // packs to remove
|
removePacks restic.IDSet // packs to remove
|
||||||
ignorePacks restic.IDSet // packs to ignore when rebuilding the index
|
ignorePacks restic.IDSet // packs to ignore when rebuilding the index
|
||||||
|
|
||||||
|
repo restic.Repository
|
||||||
|
stats PruneStats
|
||||||
|
opts PruneOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
type packInfo struct {
|
type packInfo struct {
|
||||||
@ -85,7 +89,7 @@ type packInfoWithID struct {
|
|||||||
|
|
||||||
// PlanPrune selects which files to rewrite and which to delete and which blobs to keep.
|
// PlanPrune selects which files to rewrite and which to delete and which blobs to keep.
|
||||||
// Also some summary statistics are returned.
|
// Also some summary statistics are returned.
|
||||||
func PlanPrune(ctx context.Context, opts PruneOptions, repo restic.Repository, getUsedBlobs func(ctx context.Context, repo restic.Repository) (usedBlobs restic.CountedBlobSet, err error), printer progress.Printer) (PrunePlan, PruneStats, error) {
|
func PlanPrune(ctx context.Context, opts PruneOptions, repo restic.Repository, getUsedBlobs func(ctx context.Context, repo restic.Repository) (usedBlobs restic.CountedBlobSet, err error), printer progress.Printer) (*PrunePlan, error) {
|
||||||
var stats PruneStats
|
var stats PruneStats
|
||||||
|
|
||||||
if opts.UnsafeRecovery {
|
if opts.UnsafeRecovery {
|
||||||
@ -93,27 +97,27 @@ func PlanPrune(ctx context.Context, opts PruneOptions, repo restic.Repository, g
|
|||||||
opts.MaxRepackBytes = 0
|
opts.MaxRepackBytes = 0
|
||||||
}
|
}
|
||||||
if repo.Connections() < 2 {
|
if repo.Connections() < 2 {
|
||||||
return PrunePlan{}, stats, fmt.Errorf("prune requires a backend connection limit of at least two")
|
return nil, fmt.Errorf("prune requires a backend connection limit of at least two")
|
||||||
}
|
}
|
||||||
if repo.Config().Version < 2 && opts.RepackUncompressed {
|
if repo.Config().Version < 2 && opts.RepackUncompressed {
|
||||||
return PrunePlan{}, stats, fmt.Errorf("compression requires at least repository format version 2")
|
return nil, fmt.Errorf("compression requires at least repository format version 2")
|
||||||
}
|
}
|
||||||
|
|
||||||
usedBlobs, err := getUsedBlobs(ctx, repo)
|
usedBlobs, err := getUsedBlobs(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PrunePlan{}, stats, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
printer.P("searching used packs...\n")
|
printer.P("searching used packs...\n")
|
||||||
keepBlobs, indexPack, err := packInfoFromIndex(ctx, repo.Index(), usedBlobs, &stats, printer)
|
keepBlobs, indexPack, err := packInfoFromIndex(ctx, repo.Index(), usedBlobs, &stats, printer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PrunePlan{}, stats, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
printer.P("collecting packs for deletion and repacking\n")
|
printer.P("collecting packs for deletion and repacking\n")
|
||||||
plan, err := decidePackAction(ctx, opts, repo, indexPack, &stats, printer)
|
plan, err := decidePackAction(ctx, opts, repo, indexPack, &stats, printer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PrunePlan{}, stats, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(plan.repackPacks) != 0 {
|
if len(plan.repackPacks) != 0 {
|
||||||
@ -137,7 +141,11 @@ func PlanPrune(ctx context.Context, opts PruneOptions, repo restic.Repository, g
|
|||||||
}
|
}
|
||||||
plan.keepBlobs = keepBlobs
|
plan.keepBlobs = keepBlobs
|
||||||
|
|
||||||
return plan, stats, nil
|
plan.repo = repo
|
||||||
|
plan.stats = stats
|
||||||
|
plan.opts = opts
|
||||||
|
|
||||||
|
return &plan, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func packInfoFromIndex(ctx context.Context, idx restic.MasterIndex, usedBlobs restic.CountedBlobSet, stats *PruneStats, printer progress.Printer) (restic.CountedBlobSet, map[restic.ID]packInfo, error) {
|
func packInfoFromIndex(ctx context.Context, idx restic.MasterIndex, usedBlobs restic.CountedBlobSet, stats *PruneStats, printer progress.Printer) (restic.CountedBlobSet, map[restic.ID]packInfo, error) {
|
||||||
@ -489,14 +497,18 @@ func decidePackAction(ctx context.Context, opts PruneOptions, repo restic.Reposi
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoPrune does the actual pruning:
|
func (plan *PrunePlan) Stats() PruneStats {
|
||||||
|
return plan.stats
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute does the actual pruning:
|
||||||
// - remove unreferenced packs first
|
// - remove unreferenced packs first
|
||||||
// - repack given pack files while keeping the given blobs
|
// - repack given pack files while keeping the given blobs
|
||||||
// - rebuild the index while ignoring all files that will be deleted
|
// - rebuild the index while ignoring all files that will be deleted
|
||||||
// - delete the files
|
// - delete the files
|
||||||
// plan.removePacks and plan.ignorePacks are modified in this function.
|
// plan.removePacks and plan.ignorePacks are modified in this function.
|
||||||
func DoPrune(ctx context.Context, opts PruneOptions, repo restic.Repository, plan PrunePlan, printer progress.Printer) (err error) {
|
func (plan *PrunePlan) Execute(ctx context.Context, printer progress.Printer) (err error) {
|
||||||
if opts.DryRun {
|
if plan.opts.DryRun {
|
||||||
printer.V("Repeated prune dry-runs can report slightly different amounts of data to keep or repack. This is expected behavior.\n\n")
|
printer.V("Repeated prune dry-runs can report slightly different amounts of data to keep or repack. This is expected behavior.\n\n")
|
||||||
if len(plan.removePacksFirst) > 0 {
|
if len(plan.removePacksFirst) > 0 {
|
||||||
printer.V("Would have removed the following unreferenced packs:\n%v\n\n", plan.removePacksFirst)
|
printer.V("Would have removed the following unreferenced packs:\n%v\n\n", plan.removePacksFirst)
|
||||||
@ -507,6 +519,10 @@ func DoPrune(ctx context.Context, opts PruneOptions, repo restic.Repository, pla
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repo := plan.repo
|
||||||
|
// make sure the plan can only be used once
|
||||||
|
plan.repo = nil
|
||||||
|
|
||||||
// unreferenced packs can be safely deleted first
|
// unreferenced packs can be safely deleted first
|
||||||
if len(plan.removePacksFirst) != 0 {
|
if len(plan.removePacksFirst) != 0 {
|
||||||
printer.P("deleting unreferenced packs\n")
|
printer.P("deleting unreferenced packs\n")
|
||||||
@ -544,7 +560,7 @@ func DoPrune(ctx context.Context, opts PruneOptions, repo restic.Repository, pla
|
|||||||
plan.ignorePacks.Merge(plan.removePacks)
|
plan.ignorePacks.Merge(plan.removePacks)
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.UnsafeRecovery {
|
if plan.opts.UnsafeRecovery {
|
||||||
printer.P("deleting index files\n")
|
printer.P("deleting index files\n")
|
||||||
indexFiles := repo.Index().(*index.MasterIndex).IDs()
|
indexFiles := repo.Index().(*index.MasterIndex).IDs()
|
||||||
err = deleteFiles(ctx, false, repo, indexFiles, restic.IndexFile, printer)
|
err = deleteFiles(ctx, false, repo, indexFiles, restic.IndexFile, printer)
|
||||||
@ -563,7 +579,7 @@ func DoPrune(ctx context.Context, opts PruneOptions, repo restic.Repository, pla
|
|||||||
_ = deleteFiles(ctx, true, repo, plan.removePacks, restic.PackFile, printer)
|
_ = deleteFiles(ctx, true, repo, plan.removePacks, restic.PackFile, printer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.UnsafeRecovery {
|
if plan.opts.UnsafeRecovery {
|
||||||
err = rebuildIndexFiles(ctx, repo, plan.ignorePacks, nil, true, printer)
|
err = rebuildIndexFiles(ctx, repo, plan.ignorePacks, nil, true, printer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("%s", err)
|
return errors.Fatalf("%s", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user