Add 'vaultik remote nuke', rename Processing→Backing up, bits/sec rates
remote nuke: new subcommand that deletes every snapshot's metadata and every blob from remote storage, leaving the bucket prefix empty. Requires --force. User-facing 'Processing' is now 'Backing up' everywhere it referred to the chunking/upload phase. Files summary line says 'backed up' instead of 'processed'. ui.Speed now formats bytes/sec input as bits/sec output (bit/s, Kbit/s, Mbit/s, Gbit/s). Network transfer rates are conventionally expressed in bits — the per-blob heartbeat now matches the per-snapshot summary line which has always been bits/sec.
This commit is contained in:
@@ -2,6 +2,7 @@ package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@@ -20,6 +21,72 @@ func NewRemoteCommand() *cobra.Command {
|
||||
|
||||
// Add subcommands
|
||||
cmd.AddCommand(newRemoteInfoCommand())
|
||||
cmd.AddCommand(newRemoteNukeCommand())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// newRemoteNukeCommand creates the 'remote nuke' subcommand.
|
||||
func newRemoteNukeCommand() *cobra.Command {
|
||||
var force bool
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "nuke",
|
||||
Short: "Delete ALL snapshot metadata and blobs from the backup destination store",
|
||||
Long: `Removes every snapshot's metadata and every blob from remote
|
||||
storage. After this command completes successfully the bucket prefix is
|
||||
empty and the next backup starts from scratch.
|
||||
|
||||
This is destructive and irreversible. Requires --force.`,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !force {
|
||||
return fmt.Errorf("remote nuke requires --force (this deletes ALL remote snapshots and blobs)")
|
||||
}
|
||||
|
||||
configPath, err := ResolveConfigPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rootFlags := GetRootFlags()
|
||||
return RunWithApp(cmd.Context(), AppOptions{
|
||||
ConfigPath: configPath,
|
||||
LogOptions: log.LogOptions{
|
||||
Verbose: rootFlags.Verbose,
|
||||
Debug: rootFlags.Debug,
|
||||
Quiet: rootFlags.Quiet,
|
||||
},
|
||||
Modules: []fx.Option{},
|
||||
Invokes: []fx.Option{
|
||||
fx.Invoke(func(v *vaultik.Vaultik, lc fx.Lifecycle) {
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(ctx context.Context) error {
|
||||
go func() {
|
||||
if err := v.NukeRemote(true); err != nil {
|
||||
if err != context.Canceled {
|
||||
log.Error("Remote nuke failed", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if err := v.Shutdowner.Shutdown(); err != nil {
|
||||
log.Error("Failed to shutdown", "error", err)
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
},
|
||||
OnStop: func(ctx context.Context) error {
|
||||
v.Cancel()
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}),
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVar(&force, "force", false, "Required: confirm destruction of ALL remote data")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user