cli: ensure advanced commands are not accidentally used (#611)

* cli: ensure advanced commands are not accidentally used

This prints an error when a dangerous command is used without
first setting KOPIA_ADVANCED_COMMANDS=enabled environment variable.

Co-authored-by: Julio López <julio+gh@kasten.io>
This commit is contained in:
Jarek KowalskiandJulio López authored and GitHub committed 2020-09-12 20:31:25 -07:00
1 parent 5784d68766
commit 6a14ac8a2a
10 files changed
+38 -7

No files matched your search

+14
View File
@@ -184,6 +184,20 @@ func maybeRunMaintenance(ctx context.Context, rep repo.Repository) error {
return err
}
func advancedCommand() {
if os.Getenv("KOPIA_ADVANCED_COMMANDS") != "enabled" {
//nolint:errcheck
errorColor.Printf(`
This command could be dangerous or lead to repository corruption when used improperly.
Running this command is not needed for using Kopia. Instead, most users should rely on periodic repository maintenance. See https://kopia.io/docs/maintenance/ for more information.
To run this command despite the warning, set KOPIA_ADVANCED_COMMANDS=enabled
`)
os.Exit(1)
}
}
// App returns an instance of command-line application object.
func App() *kingpin.Application {
return app
+2
View File
@@ -15,6 +15,8 @@ var (
)
func runDeleteBlobs(ctx context.Context, rep *repo.DirectRepository) error {
advancedCommand()
for _, b := range *blobDeleteBlobIDs {
err := rep.Blobs.DeleteBlob(ctx, blob.ID(b))
if err != nil {
+2
View File
@@ -17,6 +17,8 @@ var (
)
func runBlobGarbageCollectCommand(ctx context.Context, rep *repo.DirectRepository) error {
advancedCommand()
opts := maintenance.DeleteUnreferencedBlobsOptions{
DryRun: *blobGarbageCollectCommandDelete != "yes",
MinAge: *blobGarbageCollectMinAge,
+2
View File
@@ -22,6 +22,8 @@ var (
)
func runContentRewriteCommand(ctx context.Context, rep *repo.DirectRepository) error {
advancedCommand()
return maintenance.RewriteContents(ctx, rep, &maintenance.RewriteContentsOptions{
ContentIDRange: contentIDRange(),
ContentIDs: toContentIDs(*contentRewriteIDs),
+2
View File
@@ -13,6 +13,8 @@ var (
)
func runContentRemoveCommand(ctx context.Context, rep *repo.DirectRepository) error {
advancedCommand()
for _, contentID := range toContentIDs(*contentRemoveIDs) {
if err := rep.Content.DeleteContent(ctx, contentID); err != nil {
return err
+2
View File
@@ -17,6 +17,8 @@ var (
)
func runOptimizeCommand(ctx context.Context, rep *repo.DirectRepository) error {
advancedCommand()
opt := content.CompactOptions{
MaxSmallBlobs: *optimizeMaxSmallBlobs,
AllIndexes: *optimizeAllIndexes,
+2
View File
@@ -17,6 +17,8 @@ var (
)
func runRecoverBlockIndexesAction(ctx context.Context, rep *repo.DirectRepository) error {
advancedCommand()
var totalCount int
defer func() {
+2
View File
@@ -12,6 +12,8 @@ var (
)
func runManifestRemoveCommand(ctx context.Context, rep repo.Repository) error {
advancedCommand()
for _, it := range toManifestIDs(*manifestRemoveItems) {
if err := rep.DeleteManifest(ctx, it); err != nil {
return err
+1 -1
View File
@@ -10,7 +10,7 @@ import (
)
var (
snapshotGCCommand = snapshotCommands.Command("gc", "Remove contents not used by any snapshot")
snapshotGCCommand = snapshotCommands.Command("gc", "Mark contents as deleted which are not used by any snapshot").Hidden()
snapshotGCMinContentAge = snapshotGCCommand.Flag("min-age", "Minimum content age to allow deletion").Default("24h").Duration()
snapshotGCDelete = snapshotGCCommand.Flag("delete", "Delete unreferenced contents").Bool()
)
+9 -6
View File
@@ -92,12 +92,15 @@ func NewCLITest(t *testing.T) *CLITest {
}
return &CLITest{
startTime: clock.Now(),
RepoDir: RepoDir,
ConfigDir: ConfigDir,
Exe: filepath.FromSlash(exe),
fixedArgs: fixedArgs,
Environment: []string{"KOPIA_PASSWORD=" + repoPassword},
startTime: clock.Now(),
RepoDir: RepoDir,
ConfigDir: ConfigDir,
Exe: filepath.FromSlash(exe),
fixedArgs: fixedArgs,
Environment: []string{
"KOPIA_PASSWORD=" + repoPassword,
"KOPIA_ADVANCED_COMMANDS=enabled",
},
}
}