Merge pull request #94 from benbjohnson/prevent-config-and-replica-url
Prevent user from specifying replica URL & config flag
This commit is contained in:
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@@ -15,9 +14,8 @@ type DatabasesCommand struct{}
|
|||||||
|
|
||||||
// Run executes the command.
|
// Run executes the command.
|
||||||
func (c *DatabasesCommand) Run(ctx context.Context, args []string) (err error) {
|
func (c *DatabasesCommand) Run(ctx context.Context, args []string) (err error) {
|
||||||
var configPath string
|
|
||||||
fs := flag.NewFlagSet("litestream-databases", flag.ContinueOnError)
|
fs := flag.NewFlagSet("litestream-databases", flag.ContinueOnError)
|
||||||
registerConfigFlag(fs, &configPath)
|
configPath := registerConfigFlag(fs)
|
||||||
fs.Usage = c.Usage
|
fs.Usage = c.Usage
|
||||||
if err := fs.Parse(args); err != nil {
|
if err := fs.Parse(args); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -26,10 +24,10 @@ func (c *DatabasesCommand) Run(ctx context.Context, args []string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load configuration.
|
// Load configuration.
|
||||||
if configPath == "" {
|
if *configPath == "" {
|
||||||
return errors.New("-config required")
|
*configPath = DefaultConfigPath()
|
||||||
}
|
}
|
||||||
config, err := ReadConfigFile(configPath)
|
config, err := ReadConfigFile(*configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -18,9 +17,8 @@ type GenerationsCommand struct{}
|
|||||||
|
|
||||||
// Run executes the command.
|
// Run executes the command.
|
||||||
func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error) {
|
func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error) {
|
||||||
var configPath string
|
|
||||||
fs := flag.NewFlagSet("litestream-generations", flag.ContinueOnError)
|
fs := flag.NewFlagSet("litestream-generations", flag.ContinueOnError)
|
||||||
registerConfigFlag(fs, &configPath)
|
configPath := registerConfigFlag(fs)
|
||||||
replicaName := fs.String("replica", "", "replica name")
|
replicaName := fs.String("replica", "", "replica name")
|
||||||
fs.Usage = c.Usage
|
fs.Usage = c.Usage
|
||||||
if err := fs.Parse(args); err != nil {
|
if err := fs.Parse(args); err != nil {
|
||||||
@@ -35,12 +33,19 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error)
|
|||||||
var r litestream.Replica
|
var r litestream.Replica
|
||||||
updatedAt := time.Now()
|
updatedAt := time.Now()
|
||||||
if isURL(fs.Arg(0)) {
|
if isURL(fs.Arg(0)) {
|
||||||
|
if *configPath != "" {
|
||||||
|
return fmt.Errorf("cannot specify a replica URL and the -config flag")
|
||||||
|
}
|
||||||
if r, err = NewReplicaFromConfig(&ReplicaConfig{URL: fs.Arg(0)}, nil); err != nil {
|
if r, err = NewReplicaFromConfig(&ReplicaConfig{URL: fs.Arg(0)}, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if configPath != "" {
|
} else {
|
||||||
|
if *configPath == "" {
|
||||||
|
*configPath = DefaultConfigPath()
|
||||||
|
}
|
||||||
|
|
||||||
// Load configuration.
|
// Load configuration.
|
||||||
config, err := ReadConfigFile(configPath)
|
config, err := ReadConfigFile(*configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -65,8 +70,6 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error)
|
|||||||
if updatedAt, err = db.UpdatedAt(); err != nil {
|
if updatedAt, err = db.UpdatedAt(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return errors.New("config path or replica URL required")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var replicas []litestream.Replica
|
var replicas []litestream.Replica
|
||||||
|
|||||||
@@ -429,8 +429,8 @@ func DefaultConfigPath() string {
|
|||||||
return defaultConfigPath
|
return defaultConfigPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerConfigFlag(fs *flag.FlagSet, p *string) {
|
func registerConfigFlag(fs *flag.FlagSet) *string {
|
||||||
fs.StringVar(p, "config", DefaultConfigPath(), "config path")
|
return fs.String("config", "", "config path")
|
||||||
}
|
}
|
||||||
|
|
||||||
// expand returns an absolute path for s.
|
// expand returns an absolute path for s.
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -19,7 +18,6 @@ import (
|
|||||||
|
|
||||||
// ReplicateCommand represents a command that continuously replicates SQLite databases.
|
// ReplicateCommand represents a command that continuously replicates SQLite databases.
|
||||||
type ReplicateCommand struct {
|
type ReplicateCommand struct {
|
||||||
ConfigPath string
|
|
||||||
Config Config
|
Config Config
|
||||||
|
|
||||||
// List of managed databases specified in the config.
|
// List of managed databases specified in the config.
|
||||||
@@ -34,7 +32,7 @@ func NewReplicateCommand() *ReplicateCommand {
|
|||||||
func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err error) {
|
func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err error) {
|
||||||
fs := flag.NewFlagSet("litestream-replicate", flag.ContinueOnError)
|
fs := flag.NewFlagSet("litestream-replicate", flag.ContinueOnError)
|
||||||
tracePath := fs.String("trace", "", "trace path")
|
tracePath := fs.String("trace", "", "trace path")
|
||||||
registerConfigFlag(fs, &c.ConfigPath)
|
configPath := registerConfigFlag(fs)
|
||||||
fs.Usage = c.Usage
|
fs.Usage = c.Usage
|
||||||
if err := fs.Parse(args); err != nil {
|
if err := fs.Parse(args); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -44,6 +42,10 @@ func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err e
|
|||||||
if fs.NArg() == 1 {
|
if fs.NArg() == 1 {
|
||||||
return fmt.Errorf("must specify at least one replica URL for %s", fs.Arg(0))
|
return fmt.Errorf("must specify at least one replica URL for %s", fs.Arg(0))
|
||||||
} else if fs.NArg() > 1 {
|
} else if fs.NArg() > 1 {
|
||||||
|
if *configPath != "" {
|
||||||
|
return fmt.Errorf("cannot specify a replica URL and the -config flag")
|
||||||
|
}
|
||||||
|
|
||||||
dbConfig := &DBConfig{Path: fs.Arg(0)}
|
dbConfig := &DBConfig{Path: fs.Arg(0)}
|
||||||
for _, u := range fs.Args()[1:] {
|
for _, u := range fs.Args()[1:] {
|
||||||
dbConfig.Replicas = append(dbConfig.Replicas, &ReplicaConfig{
|
dbConfig.Replicas = append(dbConfig.Replicas, &ReplicaConfig{
|
||||||
@@ -52,12 +54,13 @@ func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err e
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
c.Config.DBs = []*DBConfig{dbConfig}
|
c.Config.DBs = []*DBConfig{dbConfig}
|
||||||
} else if c.ConfigPath != "" {
|
} else {
|
||||||
if c.Config, err = ReadConfigFile(c.ConfigPath); err != nil {
|
if *configPath == "" {
|
||||||
|
*configPath = DefaultConfigPath()
|
||||||
|
}
|
||||||
|
if c.Config, err = ReadConfigFile(*configPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return errors.New("-config flag or database/replica arguments required")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable trace logging.
|
// Enable trace logging.
|
||||||
|
|||||||
@@ -17,12 +17,11 @@ type RestoreCommand struct{}
|
|||||||
|
|
||||||
// Run executes the command.
|
// Run executes the command.
|
||||||
func (c *RestoreCommand) Run(ctx context.Context, args []string) (err error) {
|
func (c *RestoreCommand) Run(ctx context.Context, args []string) (err error) {
|
||||||
var configPath string
|
|
||||||
opt := litestream.NewRestoreOptions()
|
opt := litestream.NewRestoreOptions()
|
||||||
opt.Verbose = true
|
opt.Verbose = true
|
||||||
|
|
||||||
fs := flag.NewFlagSet("litestream-restore", flag.ContinueOnError)
|
fs := flag.NewFlagSet("litestream-restore", flag.ContinueOnError)
|
||||||
registerConfigFlag(fs, &configPath)
|
configPath := registerConfigFlag(fs)
|
||||||
fs.StringVar(&opt.OutputPath, "o", "", "output path")
|
fs.StringVar(&opt.OutputPath, "o", "", "output path")
|
||||||
fs.StringVar(&opt.ReplicaName, "replica", "", "replica name")
|
fs.StringVar(&opt.ReplicaName, "replica", "", "replica name")
|
||||||
fs.StringVar(&opt.Generation, "generation", "", "generation name")
|
fs.StringVar(&opt.Generation, "generation", "", "generation name")
|
||||||
@@ -59,15 +58,19 @@ func (c *RestoreCommand) Run(ctx context.Context, args []string) (err error) {
|
|||||||
// Determine replica & generation to restore from.
|
// Determine replica & generation to restore from.
|
||||||
var r litestream.Replica
|
var r litestream.Replica
|
||||||
if isURL(fs.Arg(0)) {
|
if isURL(fs.Arg(0)) {
|
||||||
|
if *configPath != "" {
|
||||||
|
return fmt.Errorf("cannot specify a replica URL and the -config flag")
|
||||||
|
}
|
||||||
if r, err = c.loadFromURL(ctx, fs.Arg(0), &opt); err != nil {
|
if r, err = c.loadFromURL(ctx, fs.Arg(0), &opt); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if configPath != "" {
|
} else {
|
||||||
if r, err = c.loadFromConfig(ctx, fs.Arg(0), configPath, &opt); err != nil {
|
if *configPath == "" {
|
||||||
|
*configPath = DefaultConfigPath()
|
||||||
|
}
|
||||||
|
if r, err = c.loadFromConfig(ctx, fs.Arg(0), *configPath, &opt); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return errors.New("config path or replica URL required")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an error if no matching targets found.
|
// Return an error if no matching targets found.
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@@ -17,9 +16,8 @@ type SnapshotsCommand struct{}
|
|||||||
|
|
||||||
// Run executes the command.
|
// Run executes the command.
|
||||||
func (c *SnapshotsCommand) Run(ctx context.Context, args []string) (err error) {
|
func (c *SnapshotsCommand) Run(ctx context.Context, args []string) (err error) {
|
||||||
var configPath string
|
|
||||||
fs := flag.NewFlagSet("litestream-snapshots", flag.ContinueOnError)
|
fs := flag.NewFlagSet("litestream-snapshots", flag.ContinueOnError)
|
||||||
registerConfigFlag(fs, &configPath)
|
configPath := registerConfigFlag(fs)
|
||||||
replicaName := fs.String("replica", "", "replica name")
|
replicaName := fs.String("replica", "", "replica name")
|
||||||
fs.Usage = c.Usage
|
fs.Usage = c.Usage
|
||||||
if err := fs.Parse(args); err != nil {
|
if err := fs.Parse(args); err != nil {
|
||||||
@@ -33,12 +31,19 @@ func (c *SnapshotsCommand) Run(ctx context.Context, args []string) (err error) {
|
|||||||
var db *litestream.DB
|
var db *litestream.DB
|
||||||
var r litestream.Replica
|
var r litestream.Replica
|
||||||
if isURL(fs.Arg(0)) {
|
if isURL(fs.Arg(0)) {
|
||||||
|
if *configPath != "" {
|
||||||
|
return fmt.Errorf("cannot specify a replica URL and the -config flag")
|
||||||
|
}
|
||||||
if r, err = NewReplicaFromConfig(&ReplicaConfig{URL: fs.Arg(0)}, nil); err != nil {
|
if r, err = NewReplicaFromConfig(&ReplicaConfig{URL: fs.Arg(0)}, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if configPath != "" {
|
} else {
|
||||||
|
if *configPath == "" {
|
||||||
|
*configPath = DefaultConfigPath()
|
||||||
|
}
|
||||||
|
|
||||||
// Load configuration.
|
// Load configuration.
|
||||||
config, err := ReadConfigFile(configPath)
|
config, err := ReadConfigFile(*configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -58,8 +63,6 @@ func (c *SnapshotsCommand) Run(ctx context.Context, args []string) (err error) {
|
|||||||
return fmt.Errorf("replica %q not found for database %q", *replicaName, db.Path())
|
return fmt.Errorf("replica %q not found for database %q", *replicaName, db.Path())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return errors.New("config path or replica URL required")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find snapshots by db or replica.
|
// Find snapshots by db or replica.
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@@ -17,9 +16,8 @@ type WALCommand struct{}
|
|||||||
|
|
||||||
// Run executes the command.
|
// Run executes the command.
|
||||||
func (c *WALCommand) Run(ctx context.Context, args []string) (err error) {
|
func (c *WALCommand) Run(ctx context.Context, args []string) (err error) {
|
||||||
var configPath string
|
|
||||||
fs := flag.NewFlagSet("litestream-wal", flag.ContinueOnError)
|
fs := flag.NewFlagSet("litestream-wal", flag.ContinueOnError)
|
||||||
registerConfigFlag(fs, &configPath)
|
configPath := registerConfigFlag(fs)
|
||||||
replicaName := fs.String("replica", "", "replica name")
|
replicaName := fs.String("replica", "", "replica name")
|
||||||
generation := fs.String("generation", "", "generation name")
|
generation := fs.String("generation", "", "generation name")
|
||||||
fs.Usage = c.Usage
|
fs.Usage = c.Usage
|
||||||
@@ -34,12 +32,19 @@ func (c *WALCommand) Run(ctx context.Context, args []string) (err error) {
|
|||||||
var db *litestream.DB
|
var db *litestream.DB
|
||||||
var r litestream.Replica
|
var r litestream.Replica
|
||||||
if isURL(fs.Arg(0)) {
|
if isURL(fs.Arg(0)) {
|
||||||
|
if *configPath != "" {
|
||||||
|
return fmt.Errorf("cannot specify a replica URL and the -config flag")
|
||||||
|
}
|
||||||
if r, err = NewReplicaFromConfig(&ReplicaConfig{URL: fs.Arg(0)}, nil); err != nil {
|
if r, err = NewReplicaFromConfig(&ReplicaConfig{URL: fs.Arg(0)}, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if configPath != "" {
|
} else {
|
||||||
|
if *configPath == "" {
|
||||||
|
*configPath = DefaultConfigPath()
|
||||||
|
}
|
||||||
|
|
||||||
// Load configuration.
|
// Load configuration.
|
||||||
config, err := ReadConfigFile(configPath)
|
config, err := ReadConfigFile(*configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -59,8 +64,6 @@ func (c *WALCommand) Run(ctx context.Context, args []string) (err error) {
|
|||||||
return fmt.Errorf("replica %q not found for database %q", *replicaName, db.Path())
|
return fmt.Errorf("replica %q not found for database %q", *replicaName, db.Path())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return errors.New("config path or replica URL required")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find WAL files by db or replica.
|
// Find WAL files by db or replica.
|
||||||
|
|||||||
Reference in New Issue
Block a user