Compare commits

...

2 Commits

Author SHA1 Message Date
Ashlie Martinez
653a79bde9 Add hidden CLI flag to open repo at point in time
Wire up the CLI side of passing in a point in time. Mostly this is so
that we can test this functionality.
2023-06-20 15:56:14 -07:00
Ashlie Martinez
a0ebe13565 Allow opening S3 repo at a specific point-in-time
Thread the PointInTime argument through corso to kopia so that S3 repos
can be opened at a specific point if they're using versioning and object
locking.
2023-06-20 15:54:44 -07:00
11 changed files with 52 additions and 14 deletions

View File

@ -95,7 +95,7 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command {
c, fs = utils.AddCommand(cmd, exchangeListCmd()) c, fs = utils.AddCommand(cmd, exchangeListCmd())
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, false) utils.AddDetailsAndRestoreFlags(c, false)
addFailedItemsFN(c) addFailedItemsFN(c)
addSkippedItemsFN(c) addSkippedItemsFN(c)
addRecoveredErrorsFN(c) addRecoveredErrorsFN(c)
@ -111,7 +111,7 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command {
// Flags addition ordering should follow the order we want them to appear in help and docs: // Flags addition ordering should follow the order we want them to appear in help and docs:
// More generic (ex: --user) and more frequently used flags take precedence. // More generic (ex: --user) and more frequently used flags take precedence.
utils.AddBackupIDFlag(c, true) utils.AddDetailsAndRestoreFlags(c, true)
utils.AddExchangeDetailsAndRestoreFlags(c) utils.AddExchangeDetailsAndRestoreFlags(c)
case deleteCommand: case deleteCommand:

View File

@ -78,7 +78,7 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
c, fs = utils.AddCommand(cmd, oneDriveListCmd()) c, fs = utils.AddCommand(cmd, oneDriveListCmd())
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, false) utils.AddDetailsAndRestoreFlags(c, false)
addFailedItemsFN(c) addFailedItemsFN(c)
addSkippedItemsFN(c) addSkippedItemsFN(c)
addRecoveredErrorsFN(c) addRecoveredErrorsFN(c)
@ -91,7 +91,7 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
c.Example = oneDriveServiceCommandDetailsExamples c.Example = oneDriveServiceCommandDetailsExamples
options.AddSkipReduceFlag(c) options.AddSkipReduceFlag(c)
utils.AddBackupIDFlag(c, true) utils.AddDetailsAndRestoreFlags(c, true)
utils.AddOneDriveDetailsAndRestoreFlags(c) utils.AddOneDriveDetailsAndRestoreFlags(c)
case deleteCommand: case deleteCommand:

View File

@ -94,7 +94,7 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
c, fs = utils.AddCommand(cmd, sharePointListCmd()) c, fs = utils.AddCommand(cmd, sharePointListCmd())
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, false) utils.AddDetailsAndRestoreFlags(c, false)
addFailedItemsFN(c) addFailedItemsFN(c)
addSkippedItemsFN(c) addSkippedItemsFN(c)
addRecoveredErrorsFN(c) addRecoveredErrorsFN(c)
@ -107,7 +107,7 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
c.Example = sharePointServiceCommandDetailsExamples c.Example = sharePointServiceCommandDetailsExamples
options.AddSkipReduceFlag(c) options.AddSkipReduceFlag(c)
utils.AddBackupIDFlag(c, true) utils.AddDetailsAndRestoreFlags(c, true)
utils.AddSharePointDetailsAndRestoreFlags(c) utils.AddSharePointDetailsAndRestoreFlags(c)
case deleteCommand: case deleteCommand:

View File

@ -23,6 +23,8 @@ func Control() control.Options {
opt.ToggleFeatures.DisableConcurrencyLimiter = disableConcurrencyLimiterFV opt.ToggleFeatures.DisableConcurrencyLimiter = disableConcurrencyLimiterFV
opt.Parallelism.ItemFetch = fetchParallelismFV opt.Parallelism.ItemFetch = fetchParallelismFV
opt.Repo.ViewTimestamp = viewTimestampFV.Get()
return opt return opt
} }
@ -40,6 +42,7 @@ const (
DisableIncrementalsFN = "disable-incrementals" DisableIncrementalsFN = "disable-incrementals"
EnableImmutableIDFN = "enable-immutable-id" EnableImmutableIDFN = "enable-immutable-id"
DisableConcurrencyLimiterFN = "disable-concurrency-limiter" DisableConcurrencyLimiterFN = "disable-concurrency-limiter"
ViewTimestampFN = "point-in-time"
) )
var ( var (
@ -48,6 +51,7 @@ var (
noStatsFV bool noStatsFV bool
restorePermissionsFV bool restorePermissionsFV bool
skipReduceFV bool skipReduceFV bool
viewTimestampFV timestamp
) )
// AddGlobalOperationFlags adds the global operations flag set. // AddGlobalOperationFlags adds the global operations flag set.
@ -90,6 +94,17 @@ func AddFetchParallelismFlag(cmd *cobra.Command) {
cobra.CheckErr(fs.MarkHidden(FetchParallelismFN)) cobra.CheckErr(fs.MarkHidden(FetchParallelismFN))
} }
// AddViewTimestampFlag adds a hidden flag that allows callers to pass a
// timestamp to view the corso repo at if immutable backups are enabled.
func AddViewTimestampFlag(cmd *cobra.Command) {
fs := cmd.Flags()
fs.Var(
&viewTimestampFV,
ViewTimestampFN,
"View the repository at a previous datetime by passing an RFC3339 timestamp")
cobra.CheckErr(fs.MarkHidden(ViewTimestampFN))
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Feature Flags // Feature Flags
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -32,7 +32,7 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command {
// general flags // general flags
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, true) utils.AddDetailsAndRestoreFlags(c, true)
utils.AddExchangeDetailsAndRestoreFlags(c) utils.AddExchangeDetailsAndRestoreFlags(c)
options.AddFailFastFlag(c) options.AddFailFastFlag(c)
} }

View File

@ -31,7 +31,7 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
// More generic (ex: --user) and more frequently used flags take precedence. // More generic (ex: --user) and more frequently used flags take precedence.
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, true) utils.AddDetailsAndRestoreFlags(c, true)
utils.AddOneDriveDetailsAndRestoreFlags(c) utils.AddOneDriveDetailsAndRestoreFlags(c)
// restore permissions // restore permissions

View File

@ -31,7 +31,7 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
// More generic (ex: --site) and more frequently used flags take precedence. // More generic (ex: --site) and more frequently used flags take precedence.
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, true) utils.AddDetailsAndRestoreFlags(c, true)
utils.AddSharePointDetailsAndRestoreFlags(c) utils.AddSharePointDetailsAndRestoreFlags(c)
options.AddRestorePermissionsFlag(c) options.AddRestorePermissionsFlag(c)

View File

@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/alcionai/corso/src/cli/options"
"github.com/alcionai/corso/src/internal/common/dttm" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/control/repository" "github.com/alcionai/corso/src/pkg/control/repository"
"github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/path"
@ -84,6 +85,11 @@ func AddBackupIDFlag(cmd *cobra.Command, require bool) {
} }
} }
func AddDetailsAndRestoreFlags(cmd *cobra.Command, require bool) {
AddBackupIDFlag(cmd, require)
options.AddViewTimestampFlag(cmd)
}
func AddDataFlag(cmd *cobra.Command, allowed []string, hide bool) { func AddDataFlag(cmd *cobra.Command, allowed []string, hide bool) {
var ( var (
allowedMsg string allowedMsg string

View File

@ -71,7 +71,7 @@ func NewConn(s storage.Storage) *conn {
} }
func (w *conn) Initialize(ctx context.Context, opts repository.Options) error { func (w *conn) Initialize(ctx context.Context, opts repository.Options) error {
bst, err := blobStoreByProvider(ctx, w.storage) bst, err := blobStoreByProvider(ctx, opts, w.storage)
if err != nil { if err != nil {
return clues.Wrap(err, "initializing storage") return clues.Wrap(err, "initializing storage")
} }
@ -111,7 +111,7 @@ func (w *conn) Initialize(ctx context.Context, opts repository.Options) error {
} }
func (w *conn) Connect(ctx context.Context, opts repository.Options) error { func (w *conn) Connect(ctx context.Context, opts repository.Options) error {
bst, err := blobStoreByProvider(ctx, w.storage) bst, err := blobStoreByProvider(ctx, opts, w.storage)
if err != nil { if err != nil {
return clues.Wrap(err, "initializing storage") return clues.Wrap(err, "initializing storage")
} }
@ -174,10 +174,14 @@ func (w *conn) commonConnect(
return nil return nil
} }
func blobStoreByProvider(ctx context.Context, s storage.Storage) (blob.Storage, error) { func blobStoreByProvider(
ctx context.Context,
opts repository.Options,
s storage.Storage,
) (blob.Storage, error) {
switch s.Provider { switch s.Provider {
case storage.ProviderS3: case storage.ProviderS3:
return s3BlobStorage(ctx, s) return s3BlobStorage(ctx, opts, s)
default: default:
return nil, clues.New("storage provider details are required").WithClues(ctx) return nil, clues.New("storage provider details are required").WithClues(ctx)
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/kopia/kopia/repo/blob" "github.com/kopia/kopia/repo/blob"
"github.com/kopia/kopia/repo/blob/s3" "github.com/kopia/kopia/repo/blob/s3"
"github.com/alcionai/corso/src/pkg/control/repository"
"github.com/alcionai/corso/src/pkg/storage" "github.com/alcionai/corso/src/pkg/storage"
) )
@ -14,7 +15,11 @@ const (
defaultS3Endpoint = "s3.amazonaws.com" // matches kopia's default value defaultS3Endpoint = "s3.amazonaws.com" // matches kopia's default value
) )
func s3BlobStorage(ctx context.Context, s storage.Storage) (blob.Storage, error) { func s3BlobStorage(
ctx context.Context,
repoOpts repository.Options,
s storage.Storage,
) (blob.Storage, error) {
cfg, err := s.S3Config() cfg, err := s.S3Config()
if err != nil { if err != nil {
return nil, clues.Stack(err).WithClues(ctx) return nil, clues.Stack(err).WithClues(ctx)
@ -36,6 +41,7 @@ func s3BlobStorage(ctx context.Context, s storage.Storage) (blob.Storage, error)
RoleARN: s.Role, RoleARN: s.Role,
RoleDuration: s.SessionDuration, RoleDuration: s.SessionDuration,
TLSHandshakeTimeout: 60, TLSHandshakeTimeout: 60,
PointInTime: repoOpts.ViewTimestamp,
} }
store, err := s3.New(ctx, &opts, false) store, err := s3.New(ctx, &opts, false)

View File

@ -1,9 +1,16 @@
package repository package repository
import (
"time"
)
// Repo represents options that are specific to the repo storing backed up data. // Repo represents options that are specific to the repo storing backed up data.
type Options struct { type Options struct {
User string `json:"user"` User string `json:"user"`
Host string `json:"host"` Host string `json:"host"`
// ViewTimestamp is the time at which the repo should be opened at if
// immutable backups are being used. If nil then the current time is used.
ViewTimestamp *time.Time `json:"viewTimestamp"`
} }
type Maintenance struct { type Maintenance struct {