Files
kopia/cli/storage_providers.go
Jarek Kowalski 505ab92e21 Support for repository sync (#522)
* blob: added DisplayName() method to blob.Storage

* cli: added 'kopia repo sync-to <provider>' which replicates BLOBs

Usage demo: https://asciinema.org/a/352299

Fixes #509

* implemented suggestion by Ciantic to fail sync if the destination repository is not compatible with the source

* cli: added 'kopia repo sync --must-exist'

This ensures that target repository is not empty, otherwise syncing to
an accidentally unmounted filesystem directory might copy everything
again.
2020-08-09 12:36:41 -07:00

84 lines
2.2 KiB
Go

package cli
import (
"context"
"github.com/pkg/errors"
kingpin "gopkg.in/alecthomas/kingpin.v2"
"github.com/kopia/kopia/repo"
"github.com/kopia/kopia/repo/blob"
)
// RegisterStorageConnectFlags registers repository subcommand to connect to a storage
// or create new repository in a given storage.
func RegisterStorageConnectFlags(
name, description string,
flags func(*kingpin.CmdClause),
connect func(ctx context.Context, isNew bool) (blob.Storage, error),
) {
if name != "from-config" {
// Set up 'create' subcommand
cc := createCommand.Command(name, "Create repository in "+description)
flags(cc)
cc.Action(func(_ *kingpin.ParseContext) error {
ctx := rootContext()
st, err := connect(ctx, true)
if err != nil {
return errors.Wrap(err, "can't connect to storage")
}
return runCreateCommandWithStorage(ctx, st)
})
}
// Set up 'connect' subcommand
cc := connectCommand.Command(name, "Connect to repository in "+description)
flags(cc)
cc.Action(func(_ *kingpin.ParseContext) error {
ctx := rootContext()
st, err := connect(ctx, false)
if err != nil {
return errors.Wrap(err, "can't connect to storage")
}
return runConnectCommandWithStorage(ctx, st)
})
// Set up 'repair' subcommand
cc = repairCommand.Command(name, "Repair repository in "+description)
flags(cc)
cc.Action(func(_ *kingpin.ParseContext) error {
ctx := rootContext()
st, err := connect(ctx, false)
if err != nil {
return errors.Wrap(err, "can't connect to storage")
}
return runRepairCommandWithStorage(ctx, st)
})
// Set up 'sync-to' subcommand
cc = repositorySyncCommand.Command(name, "Synchronize repository data to another repository in "+description)
flags(cc)
cc.Action(func(_ *kingpin.ParseContext) error {
ctx := rootContext()
st, err := connect(ctx, false)
if err != nil {
return errors.Wrap(err, "can't connect to storage")
}
rep, err := openRepository(ctx, nil, true)
if err != nil {
return errors.Wrap(err, "open repository")
}
dr, ok := rep.(*repo.DirectRepository)
if !ok {
return errors.Errorf("sync only supports directly-connected repositories")
}
return runSyncWithStorage(ctx, dr.BlobStorage(), st)
})
}