add --succeed-on-exists flag to make s3 repo init idempotent (#324)

* [Minor #323] add --success-on-exists flag to make  idempotent

Co-authored-by: ryanfkeepers <ryanfkeepers@gmail.com>
Co-authored-by: Keepers <104464746+ryanfkeepers@users.noreply.github.com>
This commit is contained in:
Sidhartha Mani 2022-07-25 11:42:24 -07:00 committed by GitHub
parent e4c7538531
commit 6a9ccf2a51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 4 deletions

View File

@ -9,6 +9,7 @@ import (
"github.com/alcionai/corso/cli/config"
"github.com/alcionai/corso/cli/utils"
"github.com/alcionai/corso/internal/kopia"
"github.com/alcionai/corso/pkg/account"
"github.com/alcionai/corso/pkg/credentials"
"github.com/alcionai/corso/pkg/logger"
@ -18,10 +19,11 @@ import (
// s3 bucket info from flags
var (
accessKey string
bucket string
endpoint string
prefix string
accessKey string
bucket string
endpoint string
prefix string
succeedIfExists bool
)
// called by repo.go to map parent subcommands to provider-specific handling.
@ -41,6 +43,10 @@ func addS3Commands(parent *cobra.Command) *cobra.Command {
cobra.CheckErr(c.MarkFlagRequired("bucket"))
fs.StringVar(&endpoint, "endpoint", "s3.amazonaws.com", "Server endpoint for S3 communication.")
fs.StringVar(&prefix, "prefix", "", "Prefix applied to objects in the bucket.")
fs.BoolVar(&succeedIfExists, "succeed-if-exists", false, "Exit with success if the repo has already been initialized.")
// In general, we don't want to expose this flag to users and have them mistake it
// for a broad-scale idempotency solution. We can un-hide it later the need arises.
cobra.CheckErr(fs.MarkHidden("succeed-if-exists"))
return c
}
@ -88,6 +94,9 @@ func initS3Cmd(cmd *cobra.Command, args []string) error {
r, err := repository.Initialize(ctx, a, s)
if err != nil {
if succeedIfExists && kopia.IsRepoAlreadyExistsError(err) {
return nil
}
return errors.Wrap(err, "Failed to initialize a new S3 repository")
}
defer utils.CloseRepo(ctx, r)

View File

@ -8,6 +8,7 @@ import (
"github.com/kopia/kopia/repo/blob"
"github.com/pkg/errors"
"github.com/alcionai/corso/internal/common"
"github.com/alcionai/corso/pkg/storage"
)
@ -20,6 +21,19 @@ var (
errConnect = errors.New("connecting repo")
)
type ErrorRepoAlreadyExists struct {
common.Err
}
func RepoAlreadyExistsError(e error) error {
return ErrorRepoAlreadyExists{*common.EncapsulateError(e)}
}
func IsRepoAlreadyExistsError(e error) bool {
var erae ErrorRepoAlreadyExists
return errors.As(e, &erae)
}
type conn struct {
storage storage.Storage
repo.Repository
@ -47,6 +61,9 @@ func (w *conn) Initialize(ctx context.Context) error {
// todo - issue #75: nil here should be a storage.NewRepoOptions()
if err = repo.Initialize(ctx, bst, nil, cfg.CorsoPassword); err != nil {
if errors.Is(err, repo.ErrAlreadyInitialized) {
return RepoAlreadyExistsError(err)
}
return errors.Wrap(err, errInit.Error())
}