Files
kopia/cli/command_cache_sync.go
T
John Costa b16302dca9 fix(cli): reject negative values for --parallel flags (#5484)
The --parallel flag was declared with kingpin .IntVar on 12 commands,
which accepted negative values and led to a panic at runtime (e.g.
`snapshot migrate --parallel=-1`).

Declare the --parallel family as uint so kingpin rejects negative input
at parse time.
The uint->int conversion the callee APIs need is done through a small
helper .

Add CLI test that asserts the rejection message (a bare failure check passed
even without the fix since the commands also fail with no repository connected).
Parse via ParseFloat like kingpin's built-in int flag so the only behavior
change is rejecting negatives.
2026-09-09 20:07:17 -07:00

55 lines
1.3 KiB
Go

package cli
import (
"context"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
"github.com/kopia/kopia/repo"
"github.com/kopia/kopia/repo/blob"
"github.com/kopia/kopia/repo/content"
)
type commandCacheSync struct {
parallel uint
}
func (c *commandCacheSync) setup(svc appServices, parent commandParent) {
cmd := parent.Command("sync", "Synchronizes the metadata cache with blobs in storage")
cmd.Flag("parallel", "Fetch parallelism").Default("16").UintVar(&c.parallel)
cmd.Action(svc.directRepositoryWriteAction(c.run))
}
func (c *commandCacheSync) run(ctx context.Context, rep repo.DirectRepositoryWriter) error {
eg, ctx := errgroup.WithContext(ctx)
ch := make(chan blob.ID, c.parallel)
// workers that will prefetch blobs.
for range c.parallel {
eg.Go(func() error {
for blobID := range ch {
if err := rep.ContentManager().MetadataCache().PrefetchBlob(ctx, blobID); err != nil {
return errors.Wrap(err, "error prefetching blob")
}
}
return nil
})
}
// populate channel with blob IDs.
eg.Go(func() error {
defer close(ch)
return rep.BlobReader().ListBlobs(ctx, content.PackBlobIDPrefixSpecial, func(bm blob.Metadata) error {
ch <- bm.BlobID
return nil
})
})
return errors.Wrap(eg.Wait(), "error synchronizing metadata cache")
}