mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-09 22:51:02 +00:00
move backup to subcommand
This commit is contained in:
parent
312a9a5334
commit
f20e6c193d
3 changed files with 114 additions and 89 deletions
42
cmd/backup.go
Normal file
42
cmd/backup.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/pilosa/pilosa/ctl"
|
||||
)
|
||||
|
||||
var backuper = ctl.NewBackupCommand(os.Stdin, os.Stdout, os.Stderr)
|
||||
|
||||
var backupCmd = &cobra.Command{
|
||||
Use: "backup",
|
||||
Short: "backup - backup data from pilosa",
|
||||
Long: `
|
||||
Backs up the database and frame from across the cluster into a single file.
|
||||
`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := backuper.Run(context.Background()); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
backupCmd.Flags().StringVarP(&backuper.Host, "host", "", "localhost:15000", "host:port of Pilosa.")
|
||||
backupCmd.Flags().StringVarP(&backuper.Database, "database", "d", "", "Pilosa database to backup into.")
|
||||
backupCmd.Flags().StringVarP(&backuper.Frame, "frame", "f", "", "Frame to backup into.")
|
||||
backupCmd.Flags().StringVarP(&backuper.Path, "output-file", "o", "", "File to write backup to - default stdout")
|
||||
|
||||
err := viper.BindPFlags(backupCmd.Flags())
|
||||
if err != nil {
|
||||
log.Fatalf("Error binding backup flags: %v", err)
|
||||
}
|
||||
|
||||
RootCmd.AddCommand(backupCmd)
|
||||
}
|
||||
|
|
@ -90,7 +90,6 @@ Usage:
|
|||
|
||||
The commands are:
|
||||
|
||||
backup backs up a frame to an archive file
|
||||
restore restores a frame from an archive file
|
||||
inspect inspects fragment data files
|
||||
check performs a consistency check of data files
|
||||
|
|
@ -116,8 +115,6 @@ func (m *Main) ParseFlags(args []string) error {
|
|||
fmt.Fprintln(m.Stderr, m.Usage())
|
||||
fmt.Fprintln(m.Stderr, "")
|
||||
return flag.ErrHelp
|
||||
case "backup":
|
||||
m.Cmd = NewBackupCommand(m.Stdin, m.Stdout, m.Stderr)
|
||||
case "restore":
|
||||
m.Cmd = NewRestoreCommand(m.Stdin, m.Stdout, m.Stderr)
|
||||
case "inspect":
|
||||
|
|
@ -149,92 +146,6 @@ type Command interface {
|
|||
Run(context.Context) error
|
||||
}
|
||||
|
||||
// BackupCommand represents a command for backing up a frame.
|
||||
type BackupCommand struct {
|
||||
// Destination host and port.
|
||||
Host string
|
||||
|
||||
// Name of the database & frame to backup.
|
||||
Database string
|
||||
Frame string
|
||||
|
||||
// Output file to write to.
|
||||
Path string
|
||||
|
||||
// Standard input/output
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
}
|
||||
|
||||
// NewBackupCommand returns a new instance of BackupCommand.
|
||||
func NewBackupCommand(stdin io.Reader, stdout, stderr io.Writer) *BackupCommand {
|
||||
return &BackupCommand{
|
||||
Stdin: stdin,
|
||||
Stdout: stdout,
|
||||
Stderr: stderr,
|
||||
}
|
||||
}
|
||||
|
||||
// ParseFlags parses command line flags from args.
|
||||
func (cmd *BackupCommand) ParseFlags(args []string) error {
|
||||
fs := flag.NewFlagSet("pilosactl", flag.ContinueOnError)
|
||||
fs.SetOutput(ioutil.Discard)
|
||||
fs.StringVar(&cmd.Host, "host", "localhost:15000", "host:port")
|
||||
fs.StringVar(&cmd.Database, "d", "", "database")
|
||||
fs.StringVar(&cmd.Frame, "f", "", "frame")
|
||||
fs.StringVar(&cmd.Path, "o", "", "output file")
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Usage returns the usage message to be printed.
|
||||
func (cmd *BackupCommand) Usage() string {
|
||||
return strings.TrimSpace(`
|
||||
usage: pilosactl backup -host HOST -d database -f frame -o PATH
|
||||
|
||||
Backs up the database and frame from across the cluster into a single file.
|
||||
`)
|
||||
}
|
||||
|
||||
// Run executes the main program execution.
|
||||
func (cmd *BackupCommand) Run(ctx context.Context) error {
|
||||
// Validate arguments.
|
||||
if cmd.Path == "" {
|
||||
return errors.New("output file required")
|
||||
}
|
||||
|
||||
// Create a client to the server.
|
||||
client, err := pilosa.NewClient(cmd.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Open output file.
|
||||
f, err := os.Create(cmd.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Begin streaming backup.
|
||||
if err := client.BackupTo(ctx, f, cmd.Database, cmd.Frame); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Sync & close file to ensure durability.
|
||||
if err := f.Sync(); err != nil {
|
||||
return err
|
||||
} else if err = f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RestoreCommand represents a command for restoring a frame from a backup.
|
||||
type RestoreCommand struct {
|
||||
// Destination host and port.
|
||||
|
|
|
|||
72
ctl/backup.go
Normal file
72
ctl/backup.go
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
package ctl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/pilosa/pilosa"
|
||||
)
|
||||
|
||||
// BackupCommand represents a command for backing up a frame.
|
||||
type BackupCommand struct {
|
||||
// Destination host and port.
|
||||
Host string
|
||||
|
||||
// Name of the database & frame to backup.
|
||||
Database string
|
||||
Frame string
|
||||
|
||||
// Output file to write to.
|
||||
Path string
|
||||
|
||||
// Standard input/output
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
}
|
||||
|
||||
// NewBackupCommand returns a new instance of BackupCommand.
|
||||
func NewBackupCommand(stdin io.Reader, stdout, stderr io.Writer) *BackupCommand {
|
||||
return &BackupCommand{
|
||||
Stdin: stdin,
|
||||
Stdout: stdout,
|
||||
Stderr: stderr,
|
||||
}
|
||||
}
|
||||
|
||||
// Run executes the main program execution.
|
||||
func (cmd *BackupCommand) Run(ctx context.Context) error {
|
||||
// Validate arguments.
|
||||
if cmd.Path == "" {
|
||||
return errors.New("output file required")
|
||||
}
|
||||
|
||||
// Create a client to the server.
|
||||
client, err := pilosa.NewClient(cmd.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Open output file.
|
||||
f, err := os.Create(cmd.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Begin streaming backup.
|
||||
if err := client.BackupTo(ctx, f, cmd.Database, cmd.Frame); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Sync & close file to ensure durability.
|
||||
if err := f.Sync(); err != nil {
|
||||
return err
|
||||
} else if err = f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue