mirror of
https://github.com/restic/restic.git
synced 2026-11-03 14:05:33 +00:00
Json prune (#5239)
Co-authored-by: Alexander Weiss <alex@weissfam.de> Co-authored-by: Michael Eischer <michael.eischer@fau.de>
This commit is contained in:
7 files changed
+192
-47
No files matched your search
@@ -348,7 +348,7 @@ func runForget(ctx context.Context, opts ForgetOptions, pruneOptions PruneOption
|
||||
printer.P("%d snapshots have been removed, running prune\n", len(removeSnIDs))
|
||||
}
|
||||
pruneOptions.DryRun = opts.DryRun
|
||||
return runPruneWithRepo(ctx, pruneOptions, repo, removeSnIDs, printer)
|
||||
return runPruneWithRepo(ctx, pruneOptions, gopts, repo, removeSnIDs, printer)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
+16
-17
@@ -175,7 +175,7 @@ func runPrune(ctx context.Context, opts PruneOptions, gopts global.Options, term
|
||||
return errors.Fatal("--no-lock is only applicable in combination with --dry-run for prune command")
|
||||
}
|
||||
|
||||
printer := ui.NewProgressPrinter(false, gopts.Verbosity, term)
|
||||
printer := ui.NewProgressPrinter(gopts.JSON, gopts.Verbosity, term)
|
||||
ctx, repo, unlock, err := openWithExclusiveLock(ctx, gopts, opts.DryRun && gopts.NoLock, printer)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -190,11 +190,11 @@ func runPrune(ctx context.Context, opts PruneOptions, gopts global.Options, term
|
||||
opts.unsafeRecovery = true
|
||||
}
|
||||
|
||||
return runPruneWithRepo(ctx, opts, repo, restic.NewIDSet(), printer)
|
||||
return runPruneWithRepo(ctx, opts, gopts, repo, restic.NewIDSet(), printer)
|
||||
}
|
||||
|
||||
func runPruneWithRepo(ctx context.Context, opts PruneOptions, repo *repository.Repository, ignoreSnapshots restic.IDSet, printer progress.Printer) error {
|
||||
if repo.Cache() == nil {
|
||||
func runPruneWithRepo(ctx context.Context, opts PruneOptions, gopts global.Options, repo *repository.Repository, ignoreSnapshots restic.IDSet, printer progress.Printer) error {
|
||||
if repo.Cache() == nil && !gopts.JSON {
|
||||
printer.S("warning: running prune without a cache, this may be very slow!")
|
||||
}
|
||||
|
||||
@@ -230,9 +230,13 @@ func runPruneWithRepo(ctx context.Context, opts PruneOptions, repo *repository.R
|
||||
printer.P("\nWould have made the following changes:")
|
||||
}
|
||||
|
||||
err = printPruneStats(printer, plan.Stats())
|
||||
if err != nil {
|
||||
return err
|
||||
if !gopts.JSON {
|
||||
err = printPruneStats(printer, plan.Stats())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
gopts.Term.Print(ui.ToJSONString(plan.Stats()))
|
||||
}
|
||||
|
||||
// Trigger GC to reset garbage collection threshold
|
||||
@@ -251,24 +255,19 @@ func printPruneStats(printer progress.Printer, stats repository.PruneStats) erro
|
||||
if stats.Size.Unref > 0 {
|
||||
printer.V("unreferenced: %s", ui.FormatBytes(stats.Size.Unref))
|
||||
}
|
||||
totalBlobs := stats.Blobs.Used + stats.Blobs.Unused + stats.Blobs.Duplicate
|
||||
totalSize := stats.Size.Used + stats.Size.Duplicate + stats.Size.Unused + stats.Size.Unref
|
||||
unusedSize := stats.Size.Duplicate + stats.Size.Unused
|
||||
printer.V("total: %10d blobs / %s", totalBlobs, ui.FormatBytes(totalSize))
|
||||
printer.V("unused size: %s of total size", ui.FormatPercent(unusedSize, totalSize))
|
||||
printer.V("total: %10d blobs / %s", stats.Blobs.Total, ui.FormatBytes(stats.Size.Total))
|
||||
printer.V("unused size: %s of total size", ui.FormatPercent(stats.Size.Duplicate+stats.Size.Unused, stats.Size.Total))
|
||||
|
||||
printer.P("\nto repack: %10d blobs / %s", stats.Blobs.Repack, ui.FormatBytes(stats.Size.Repack))
|
||||
printer.P("this removes: %10d blobs / %s", stats.Blobs.Repackrm, ui.FormatBytes(stats.Size.Repackrm))
|
||||
printer.P("to delete: %10d blobs / %s", stats.Blobs.Remove, ui.FormatBytes(stats.Size.Remove+stats.Size.Unref))
|
||||
totalPruneSize := stats.Size.Remove + stats.Size.Repackrm + stats.Size.Unref
|
||||
printer.P("total prune: %10d blobs / %s", stats.Blobs.Remove+stats.Blobs.Repackrm, ui.FormatBytes(totalPruneSize))
|
||||
printer.P("total prune: %10d blobs / %s", stats.Blobs.RemoveTotal, ui.FormatBytes(stats.Size.RemoveTotal))
|
||||
if stats.Size.Uncompressed > 0 {
|
||||
printer.P("not yet compressed: %s", ui.FormatBytes(stats.Size.Uncompressed))
|
||||
}
|
||||
printer.P("remaining: %10d blobs / %s", totalBlobs-(stats.Blobs.Remove+stats.Blobs.Repackrm), ui.FormatBytes(totalSize-totalPruneSize))
|
||||
unusedAfter := unusedSize - stats.Size.Remove - stats.Size.Repackrm
|
||||
printer.P("remaining: %10d blobs / %s", stats.Blobs.Remain, ui.FormatBytes(stats.Size.Remain))
|
||||
printer.P("unused size after prune: %s (%s of remaining size)",
|
||||
ui.FormatBytes(unusedAfter), ui.FormatPercent(unusedAfter, totalSize-totalPruneSize))
|
||||
ui.FormatBytes(stats.Size.RemainUnused), ui.FormatPercent(stats.Size.RemainUnused, stats.Size.Remain))
|
||||
printer.P("")
|
||||
printer.V("totally used packs: %10d", stats.Packs.Used)
|
||||
printer.V("partly used packs: %10d", stats.Packs.PartlyUsed)
|
||||
|
||||
@@ -258,3 +258,28 @@ func TestPruneRepackSmallerThanSmoke(t *testing.T) {
|
||||
MaxUnused: "5%",
|
||||
})
|
||||
}
|
||||
|
||||
func TestPruneJSON(t *testing.T) {
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
createPrunableRepo(t, env)
|
||||
|
||||
buf, err := withCaptureStdout(t, env.gopts, func(ctx context.Context, gopts global.Options) error {
|
||||
gopts.JSON = true
|
||||
oldHook := gopts.BackendTestHook
|
||||
gopts.BackendTestHook = func(r backend.Backend) (backend.Backend, error) { return newListOnceBackend(r), nil }
|
||||
defer func() {
|
||||
gopts.BackendTestHook = oldHook
|
||||
}()
|
||||
return runPrune(ctx, pruneDefaultOptions, gopts, gopts.Term)
|
||||
})
|
||||
rtest.OK(t, err)
|
||||
|
||||
var stats repository.PruneStats
|
||||
rtest.OK(t, json.Unmarshal(buf.Bytes(), &stats))
|
||||
|
||||
rtest.Equals(t, "summary", stats.MessageType)
|
||||
rtest.Assert(t, stats.Blobs.Total > 0, "expected non-zero total blobs, got %v", stats.Blobs.Total)
|
||||
rtest.Assert(t, stats.Packs.Total > 0, "expected non-zero total packs, got %v", stats.Packs.Total)
|
||||
}
|
||||
Reference in new issue
Block a user