2013-12-03 22:19:42 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2015-05-30 14:49:49 +00:00
|
|
|
"io"
|
2014-11-11 05:25:03 +00:00
|
|
|
"log"
|
2015-03-22 20:58:40 +00:00
|
|
|
"math/rand"
|
2013-12-03 22:19:42 +00:00
|
|
|
"os"
|
2015-02-23 20:27:51 +00:00
|
|
|
"os/signal"
|
|
|
|
"runtime"
|
|
|
|
"runtime/pprof"
|
2014-11-21 03:31:04 +00:00
|
|
|
"strings"
|
2015-03-22 20:58:40 +00:00
|
|
|
"time"
|
2015-01-24 20:11:03 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
"github.com/influxdb/influxdb/cmd/influxd/help"
|
2015-05-29 19:50:05 +00:00
|
|
|
"github.com/influxdb/influxdb/cmd/influxd/run"
|
2015-05-30 14:49:49 +00:00
|
|
|
"github.com/influxdb/influxdb/cmd/influxd/version"
|
2014-12-11 21:49:42 +00:00
|
|
|
)
|
|
|
|
|
2013-12-03 22:19:42 +00:00
|
|
|
func main() {
|
2015-03-22 20:58:40 +00:00
|
|
|
rand.Seed(time.Now().UnixNano())
|
2014-12-06 01:02:30 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
m := NewMain()
|
|
|
|
if err := m.Run(os.Args[1:]...); err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
os.Exit(1)
|
2015-02-24 17:47:07 +00:00
|
|
|
}
|
2015-05-30 14:49:49 +00:00
|
|
|
}
|
2015-02-24 17:47:07 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// Main represents the program execution.
|
|
|
|
type Main struct {
|
|
|
|
Stdin io.Reader
|
|
|
|
Stdout io.Writer
|
|
|
|
Stderr io.Writer
|
|
|
|
}
|
2014-12-06 01:02:30 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// NewMain return a new instance of Main.
|
|
|
|
func NewMain() *Main {
|
|
|
|
return &Main{
|
|
|
|
Stdin: os.Stdin,
|
|
|
|
Stdout: os.Stdout,
|
|
|
|
Stderr: os.Stderr,
|
2014-12-06 01:02:30 +00:00
|
|
|
}
|
2015-05-30 14:49:49 +00:00
|
|
|
}
|
2014-12-06 01:02:30 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// Run determines and runs the command specified by the CLI args.
|
|
|
|
func (m *Main) Run(args ...string) error {
|
|
|
|
name, args := ParseCommandName(args)
|
2014-12-06 01:02:30 +00:00
|
|
|
|
2015-05-29 19:50:05 +00:00
|
|
|
// FIXME(benbjohnson): Parse profiling args & start profiling.
|
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
// Extract name from args.
|
2015-05-30 14:49:49 +00:00
|
|
|
switch name {
|
|
|
|
case "", "run":
|
2015-05-29 19:50:05 +00:00
|
|
|
if err := run.NewCommand().Run(args...); err != nil {
|
2015-05-30 14:49:49 +00:00
|
|
|
return fmt.Errorf("run: %s", err)
|
2015-03-22 20:58:40 +00:00
|
|
|
}
|
2015-05-29 19:50:05 +00:00
|
|
|
// case "backup":
|
2015-05-30 14:49:49 +00:00
|
|
|
// name := NewBackupCommand()
|
|
|
|
// if err := name.Run(args...); err != nil {
|
|
|
|
// return fmt.Errorf("backup: %s", err)
|
2015-05-29 19:50:05 +00:00
|
|
|
// }
|
|
|
|
// case "restore":
|
2015-05-30 14:49:49 +00:00
|
|
|
// name := NewRestoreCommand()
|
|
|
|
// if err := name.Run(args...); err != nil {
|
|
|
|
// return fmt.Errorf("restore: %s", err)
|
2015-05-29 19:50:05 +00:00
|
|
|
// }
|
2015-03-16 15:23:53 +00:00
|
|
|
case "config":
|
2015-05-30 14:49:49 +00:00
|
|
|
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)
|
2015-03-25 16:27:48 +00:00
|
|
|
}
|
2014-11-04 20:36:15 +00:00
|
|
|
}
|
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
return fmt.Errorf(`unknown command "%s"`+"\n"+`Run 'influxd help' for usage`+"\n\n", name)
|
|
|
|
}
|
2014-10-22 00:20:43 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// 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]
|
2013-12-03 22:19:42 +00:00
|
|
|
}
|
2014-11-11 05:25:03 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// Special case -h immediately following binary name
|
|
|
|
if len(args) > 0 && args[0] == "-h" {
|
|
|
|
name = "help"
|
2014-03-27 23:09:08 +00:00
|
|
|
}
|
2014-03-27 16:24:40 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// 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]
|
|
|
|
}
|
2014-12-06 01:02:30 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// If a named command is specified then return it with its arguments.
|
|
|
|
if name != "" {
|
|
|
|
return name, args[1:]
|
|
|
|
}
|
|
|
|
return "", args
|
2014-12-06 01:02:30 +00:00
|
|
|
}
|
2015-02-23 20:27:51 +00:00
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// prof stores the file locations of active profiles.
|
2015-02-23 20:27:51 +00:00
|
|
|
var prof struct {
|
|
|
|
cpu *os.File
|
|
|
|
mem *os.File
|
|
|
|
}
|
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// StartProfile initializes the cpu and memory profile, if specified.
|
|
|
|
func StartProfile(cpuprofile, memprofile string) {
|
2015-02-23 20:27:51 +00:00
|
|
|
if cpuprofile != "" {
|
|
|
|
f, err := os.Create(cpuprofile)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("cpuprofile: %v", err)
|
|
|
|
}
|
|
|
|
prof.cpu = f
|
|
|
|
pprof.StartCPUProfile(prof.cpu)
|
|
|
|
}
|
|
|
|
|
|
|
|
if memprofile != "" {
|
|
|
|
f, err := os.Create(memprofile)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("memprofile: %v", err)
|
|
|
|
}
|
|
|
|
prof.mem = f
|
|
|
|
runtime.MemProfileRate = 4096
|
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
c := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(c, os.Interrupt)
|
|
|
|
<-c
|
2015-05-30 14:49:49 +00:00
|
|
|
StopProfile()
|
2015-02-23 20:27:51 +00:00
|
|
|
os.Exit(0)
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2015-05-30 14:49:49 +00:00
|
|
|
// StopProfile closes the cpu and memory profiles if they are running.
|
|
|
|
func StopProfile() {
|
2015-02-23 20:27:51 +00:00
|
|
|
if prof.cpu != nil {
|
|
|
|
pprof.StopCPUProfile()
|
|
|
|
prof.cpu.Close()
|
|
|
|
}
|
|
|
|
if prof.mem != nil {
|
|
|
|
pprof.Lookup("heap").WriteTo(prof.mem, 0)
|
|
|
|
prof.mem.Close()
|
|
|
|
}
|
|
|
|
}
|