mirror of
https://github.com/kopia/kopia.git
synced 2026-03-28 19:15:02 -04:00
The `dirRelativePath` variable is actually the path to the file being checked, but was treated as if it was the path to the parent directory, causing the filename to be duplicated in log messages.
67 lines
2.1 KiB
Go
67 lines
2.1 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/kopia/kopia/repo"
|
|
"github.com/kopia/kopia/repo/blob"
|
|
"github.com/kopia/kopia/snapshot"
|
|
"github.com/kopia/kopia/snapshot/snapshotfs"
|
|
)
|
|
|
|
type commandSnapshotFixInvalidFiles struct {
|
|
common commonRewriteSnapshots
|
|
|
|
verifyFilesPercent float64
|
|
verifier *snapshotfs.Verifier
|
|
|
|
invalidFileHandling string
|
|
|
|
failedFileCallback snapshotfs.RewriteFailedEntryCallback
|
|
}
|
|
|
|
func (c *commandSnapshotFixInvalidFiles) setup(svc appServices, parent commandParent) {
|
|
cmd := parent.Command("invalid-files", "Remove references to any invalid (unreadable) files from snapshots.")
|
|
c.common.setup(svc, cmd)
|
|
|
|
cmd.Flag("invalid-file-handling", "How to handle invalid files").Default(invalidEntryStub).EnumVar(&c.invalidFileHandling, invalidEntryFail, invalidEntryStub, invalidEntryKeep, invalidEntryRemove)
|
|
cmd.Flag("verify-files-percent", "Verify a percentage of files by fully downloading them [0.0 .. 100.0]").Default("0").Float64Var(&c.verifyFilesPercent)
|
|
|
|
cmd.Action(svc.repositoryWriterAction(c.run))
|
|
}
|
|
|
|
func (c *commandSnapshotFixInvalidFiles) rewriteEntry(ctx context.Context, pathFromRoot string, ent *snapshot.DirEntry) (*snapshot.DirEntry, error) {
|
|
if ent.Type != snapshot.EntryTypeDirectory {
|
|
if err := c.verifier.VerifyFile(ctx, ent.ObjectID, pathFromRoot); err != nil {
|
|
log(ctx).Warnf("removing invalid file %v due to: %v", pathFromRoot, err)
|
|
|
|
return c.failedFileCallback(ctx, pathFromRoot, ent, err)
|
|
}
|
|
}
|
|
|
|
return ent, nil
|
|
}
|
|
|
|
func (c *commandSnapshotFixInvalidFiles) run(ctx context.Context, rep repo.RepositoryWriter) error {
|
|
c.failedFileCallback = failedEntryCallback(rep, c.invalidFileHandling)
|
|
|
|
opts := snapshotfs.VerifierOptions{
|
|
VerifyFilesPercent: c.verifyFilesPercent,
|
|
}
|
|
|
|
if dr, ok := rep.(repo.DirectRepository); ok {
|
|
blobMap, err := blob.ReadBlobMap(ctx, dr.BlobReader())
|
|
if err != nil {
|
|
return errors.Wrap(err, "unable to read blob map")
|
|
}
|
|
|
|
opts.BlobMap = blobMap
|
|
}
|
|
|
|
c.verifier = snapshotfs.NewVerifier(ctx, rep, opts)
|
|
|
|
return c.common.rewriteMatchingSnapshots(ctx, rep, c.rewriteEntry)
|
|
}
|