diff --git a/src/cli/backup/backup.go b/src/cli/backup/backup.go index c95d5803d..badf4cfc7 100644 --- a/src/cli/backup/backup.go +++ b/src/cli/backup/backup.go @@ -63,6 +63,14 @@ func AddCommands(cmd *cobra.Command) { flags.AddAllStorageFlags(sc) } } + + // Add verify command separately. It's not bound to a single service. + verifyCommand := verifyCmd() + flags.AddAllProviderFlags(verifyCommand) + flags.AddAllStorageFlags(verifyCommand) + flags.AddReadOnlyFlag(verifyCommand) + + backupC.AddCommand(verifyCommand) } // --------------------------------------------------------------------------- @@ -163,6 +171,42 @@ func handleDeleteCmd(cmd *cobra.Command, args []string) error { return cmd.Help() } +// The backup verify subcommand. +// `corso backup verify` +var verifyCommand = "verify" + +func verifyCmd() *cobra.Command { + return &cobra.Command{ + Use: verifyCommand, + Short: "Verifies all backups have all their data", + RunE: handleVerifyCmd, + Args: cobra.NoArgs, + } +} + +// Handler for calls to `corso backup delete`. +// Produces the same output as `corso backup delete --help`. +func handleVerifyCmd(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + r, _, err := utils.AccountConnectAndWriteRepoConfig( + ctx, + cmd, + // Service doesn't really matter but we need to give it something valid. + path.OneDriveService) + if err != nil { + return Only(ctx, err) + } + + defer utils.CloseRepo(ctx, r) + + if err := r.VerifyBackups(ctx); err != nil { + return Only(ctx, err) + } + + return nil +} + // --------------------------------------------------------------------------- // common handlers // --------------------------------------------------------------------------- diff --git a/src/cli/flags/repo.go b/src/cli/flags/repo.go index ac84488b6..80cd8c0b3 100644 --- a/src/cli/flags/repo.go +++ b/src/cli/flags/repo.go @@ -14,6 +14,7 @@ const ( // Corso Flags PassphraseFN = "passphrase" NewPassphraseFN = "new-passphrase" + ReadOnlyFN = "readonly" SucceedIfExistsFN = "succeed-if-exists" ) @@ -25,6 +26,7 @@ var ( AWSSessionTokenFV string PassphraseFV string NewPhasephraseFV string + ReadOnlyFV bool SucceedIfExistsFV bool ) @@ -59,6 +61,13 @@ func AddAllStorageFlags(cmd *cobra.Command) { AddAWSCredsFlags(cmd) } +func AddReadOnlyFlag(cmd *cobra.Command) { + fs := cmd.Flags() + fs.BoolVar(&ReadOnlyFV, ReadOnlyFN, false, "open repository in read-only mode") + //nolint:errcheck + fs.MarkHidden(ReadOnlyFN) +} + func AddAWSCredsFlags(cmd *cobra.Command) { fs := cmd.Flags() fs.StringVar(&AWSAccessKeyFV, AWSAccessKeyFN, "", "S3 access key") diff --git a/src/cli/utils/options.go b/src/cli/utils/options.go index 8bb63452a..24c793e40 100644 --- a/src/cli/utils/options.go +++ b/src/cli/utils/options.go @@ -30,6 +30,7 @@ func Control() control.Options { opt.ToggleFeatures.ExchangeImmutableIDs = flags.EnableImmutableIDFV opt.ToggleFeatures.UseDeltaTree = flags.UseDeltaTreeFV opt.Parallelism.ItemFetch = flags.FetchParallelismFV + opt.Repo.ReadOnly = flags.ReadOnlyFV return opt }