Refactor influxd.Main.

pull/2709/head
Ben Johnson 2015-05-30 08:49:49 -06:00
parent 4872e6db7c
commit 233c63029b
4 changed files with 152 additions and 101 deletions

View File

@ -1,19 +1,31 @@
package help
import "fmt"
import (
"fmt"
"io"
"os"
"strings"
)
// HelpCommand displays help for command-line sub-commands.
type HelpCommand struct {
// Command displays help for command-line sub-commands.
type Command struct {
Stdout io.Writer
}
// NewHelpCommand returns a new instance of HelpCommand.
func NewHelpCommand() *HelpCommand {
return &HelpCommand{}
// NewCommand returns a new instance of Command.
func NewCommand() *Command {
return &Command{
Stdout: os.Stdout,
}
}
// Run executes the command.
func (cmd *HelpCommand) Run(args ...string) error {
fmt.Println(`
func (cmd *Command) Run(args ...string) error {
fmt.Fprintln(cmd.Stdout, strings.TrimSpace(usage))
return nil
}
const usage = `
Configure and start an InfluxDB server.
Usage:
@ -23,13 +35,10 @@ Usage:
The commands are:
config display the default configuration
join-cluster create a new node that will join an existing cluster
run run node with existing configuration
version displays the InfluxDB version
"run" is the default command.
Use "influxd help [command]" for more information about a command.
`)
return nil
}
`

View File

@ -1,8 +1,8 @@
package main
import (
"flag"
"fmt"
"io"
"log"
"math/rand"
"os"
@ -12,123 +12,110 @@ import (
"strings"
"time"
"github.com/influxdb/influxdb/cmd/influxd/help"
"github.com/influxdb/influxdb/cmd/influxd/run"
)
// These variables are populated via the Go linker.
var (
version string = "0.9"
commit string
)
// Various constants used by the main package.
const (
messagingClientFile string = "messaging"
monitoringDatabase string = "_influxdb"
monitoringRetentionPolicy string = "default"
"github.com/influxdb/influxdb/cmd/influxd/version"
)
func main() {
log.SetFlags(0)
log.SetPrefix(`[srvr] `)
log.SetFlags(log.LstdFlags)
rand.Seed(time.Now().UnixNano())
// If commit not set, make that clear.
if commit == "" {
commit = "unknown"
m := NewMain()
if err := m.Run(os.Args[1:]...); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
// Shift binary name off argument list.
args := os.Args[1:]
// Main represents the program execution.
type Main struct {
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}
// Retrieve command name as first argument.
var cmd string
if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
cmd = args[0]
// NewMain return a new instance of Main.
func NewMain() *Main {
return &Main{
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
}
// Special case -h immediately following binary name
if len(args) > 0 && args[0] == "-h" {
cmd = "help"
}
// If command is "help" and has an argument then rewrite args to use "-h".
if cmd == "help" && len(args) > 1 {
args[0], args[1] = args[1], "-h"
cmd = args[0]
}
// Run determines and runs the command specified by the CLI args.
func (m *Main) Run(args ...string) error {
name, args := ParseCommandName(args)
// FIXME(benbjohnson): Parse profiling args & start profiling.
// Extract name from args.
switch cmd {
case "":
switch name {
case "", "run":
if err := run.NewCommand().Run(args...); err != nil {
log.Fatalf("run: %s", err)
}
case "run":
if err := run.NewCommand().Run(args[1:]...); err != nil {
log.Fatalf("run: %s", err)
return fmt.Errorf("run: %s", err)
}
// case "backup":
// cmd := NewBackupCommand()
// if err := cmd.Run(args[1:]...); err != nil {
// log.Fatalf("backup: %s", err)
// name := NewBackupCommand()
// if err := name.Run(args...); err != nil {
// return fmt.Errorf("backup: %s", err)
// }
// case "restore":
// cmd := NewRestoreCommand()
// if err := cmd.Run(args[1:]...); err != nil {
// log.Fatalf("restore: %s", err)
// name := NewRestoreCommand()
// if err := name.Run(args...); err != nil {
// return fmt.Errorf("restore: %s", err)
// }
case "version":
execVersion(args[1:])
case "config":
if err := run.NewPrintConfigCommand().Run(args[1:]...); err != nil {
log.Fatalf("config: %s", err)
if err := run.NewPrintConfigCommand().Run(args...); err != nil {
return fmt.Errorf("config: %s", err)
}
case "version":
if err := version.NewCommand().Run(args...); err != nil {
return fmt.Errorf("version: %s", err)
}
case "help":
if err := help.NewCommand().Run(args...); err != nil {
return fmt.Errorf("help: %s", err)
}
// case "help":
// if err := help.NewCommand().Run(args[1:]...); err != nil {
// log.Fatalf("help: %s", err)
// }
default:
log.Fatalf(`influxd: unknown command "%s"`+"\n"+`Run 'influxd help' for usage`+"\n\n", cmd)
}
return fmt.Errorf(`unknown command "%s"`+"\n"+`Run 'influxd help' for usage`+"\n\n", name)
}
// execVersion runs the "version" command.
// Prints the commit SHA1 if set by the build process.
func execVersion(args []string) {
fs := flag.NewFlagSet("", flag.ExitOnError)
fs.Usage = func() {
fmt.Println(`usage: version
version displays the InfluxDB version and build git commit hash
`)
// ParseCommandName extracts the command name and args from the args list.
func ParseCommandName(args []string) (string, []string) {
// Retrieve command name as first argument.
var name string
if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
name = args[0]
}
fs.Parse(args)
s := fmt.Sprintf("InfluxDB v%s", version)
if commit != "" {
s += fmt.Sprintf(" (git: %s)", commit)
// Special case -h immediately following binary name
if len(args) > 0 && args[0] == "-h" {
name = "help"
}
log.Print(s)
}
type Stopper interface {
Stop()
}
type State struct {
Mode string `json:"mode"`
// If command is "help" and has an argument then rewrite args to use "-h".
if name == "help" && len(args) > 1 {
args[0], args[1] = args[1], "-h"
name = args[0]
}
// If a named command is specified then return it with its arguments.
if name != "" {
return name, args[1:]
}
return "", args
}
// prof stores the file locations of active profiles.
var prof struct {
cpu *os.File
mem *os.File
}
func startProfiling(cpuprofile, memprofile string) {
// StartProfile initializes the cpu and memory profile, if specified.
func StartProfile(cpuprofile, memprofile string) {
if cpuprofile != "" {
f, err := os.Create(cpuprofile)
if err != nil {
@ -151,12 +138,13 @@ func startProfiling(cpuprofile, memprofile string) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
stopProfiling()
StopProfile()
os.Exit(0)
}()
}
func stopProfiling() {
// StopProfile closes the cpu and memory profiles if they are running.
func StopProfile() {
if prof.cpu != nil {
pprof.StopCPUProfile()
prof.cpu.Close()
@ -166,6 +154,3 @@ func stopProfiling() {
prof.mem.Close()
}
}
func warn(v ...interface{}) { fmt.Fprintln(os.Stderr, v...) }
func warnf(msg string, v ...interface{}) { fmt.Fprintf(os.Stderr, msg+"\n", v...) }

View File

@ -376,8 +376,8 @@ func (cmd *RunCommand) Open(config *Config, join string) *Node {
// Start up self-monitoring if enabled.
if cmd.config.Monitoring.Enabled {
database := monitoringDatabase
policy := monitoringRetentionPolicy
database := "_influxdb"
policy := "default"
interval := time.Duration(cmd.config.Monitoring.WriteInterval)
// Ensure database exists.

View File

@ -0,0 +1,57 @@
package version
import (
"flag"
"fmt"
"io"
"os"
"strings"
)
// These variables are populated via the Go linker.
var (
version string = "0.9"
commit string
)
func init() {
// If commit not set, make that clear.
if commit == "" {
commit = "unknown"
}
}
// Command represents the command executed by "influxd version".
type Command struct {
Stdout io.Writer
Stderr io.Writer
}
// NewCommand return a new instance of Command.
func NewCommand() *Command {
return &Command{
Stdout: os.Stdout,
Stderr: os.Stderr,
}
}
// Run prints the current version and commit info.
func (cmd *Command) Run(args ...string) error {
// Parse flags in case -h is specified.
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.Usage = func() { fmt.Fprintln(cmd.Stderr, strings.TrimSpace(usage)) }
if err := fs.Parse(args); err != nil {
return err
}
// Print version info.
fmt.Fprintf(cmd.Stdout, "InfluxDB v%s (git: %s)\n", version, commit)
return nil
}
var usage = `
usage: version
version displays the InfluxDB version and build git commit hash
`