2013-12-03 22:19:42 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
2014-11-11 05:25:03 +00:00
|
|
|
"log"
|
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"
|
2013-12-03 22:19:42 +00:00
|
|
|
)
|
|
|
|
|
2014-10-22 05:32:19 +00:00
|
|
|
const logo = `
|
2015-01-24 20:11:03 +00:00
|
|
|
8888888 .d888 888 8888888b. 888888b.
|
|
|
|
888 d88P" 888 888 "Y88b 888 "88b
|
|
|
|
888 888 888 888 888 888 .88P
|
|
|
|
888 88888b. 888888 888 888 888 888 888 888 888 8888888K.
|
|
|
|
888 888 "88b 888 888 888 888 Y8bd8P' 888 888 888 "Y88b
|
|
|
|
888 888 888 888 888 888 888 X88K 888 888 888 888
|
|
|
|
888 888 888 888 888 Y88b 888 .d8""8b. 888 .d88P 888 d88P
|
|
|
|
8888888 888 888 888 888 "Y88888 888 888 8888888P" 8888888P"
|
|
|
|
|
2014-10-22 05:32:19 +00:00
|
|
|
`
|
|
|
|
|
2014-11-18 00:34:47 +00:00
|
|
|
// These variables are populated via the Go linker.
|
|
|
|
var (
|
2014-12-06 01:02:30 +00:00
|
|
|
version string = "0.9"
|
2014-11-18 00:34:47 +00:00
|
|
|
commit string
|
|
|
|
)
|
|
|
|
|
2014-12-11 21:49:42 +00:00
|
|
|
// Various constants used by the main package.
|
|
|
|
const (
|
2014-12-16 21:24:21 +00:00
|
|
|
messagingClientFile string = "messaging"
|
2014-12-11 21:49:42 +00:00
|
|
|
)
|
|
|
|
|
2013-12-03 22:19:42 +00:00
|
|
|
func main() {
|
2014-12-06 01:02:30 +00:00
|
|
|
log.SetFlags(0)
|
|
|
|
|
2015-02-24 17:47:07 +00:00
|
|
|
// If commit not set, make that clear.
|
|
|
|
if commit == "" {
|
|
|
|
commit = "unknown"
|
|
|
|
}
|
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
// Shift binary name off argument list.
|
|
|
|
args := os.Args[1:]
|
|
|
|
|
|
|
|
// Retrieve command name as first argument.
|
|
|
|
var cmd string
|
|
|
|
if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
|
|
|
|
cmd = args[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Special case -h immediately following binary name
|
2014-12-12 00:04:53 +00:00
|
|
|
if len(args) > 0 && args[0] == "-h" {
|
2014-12-06 01:02:30 +00:00
|
|
|
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]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extract name from args.
|
|
|
|
switch cmd {
|
|
|
|
case "run":
|
|
|
|
execRun(args[1:])
|
|
|
|
case "":
|
|
|
|
execRun(args)
|
2015-03-20 04:23:52 +00:00
|
|
|
case "backup":
|
2015-03-22 16:28:04 +00:00
|
|
|
cmd := NewBackupCommand()
|
|
|
|
if err := cmd.Run(args[1:]...); err != nil {
|
|
|
|
log.Fatalf("backup: %s", err)
|
|
|
|
}
|
2015-03-20 04:23:52 +00:00
|
|
|
case "restore":
|
|
|
|
execRestore(args[1:])
|
2014-12-06 01:02:30 +00:00
|
|
|
case "version":
|
|
|
|
execVersion(args[1:])
|
|
|
|
case "help":
|
|
|
|
execHelp(args[1:])
|
|
|
|
default:
|
|
|
|
log.Fatalf(`influxd: unknown command "%s"`+"\n"+`Run 'influxd help' for usage`+"\n\n", cmd)
|
2014-11-04 20:36:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-02 21:01:35 +00:00
|
|
|
// execRun runs the "run" command.
|
|
|
|
func execRun(args []string) {
|
|
|
|
// Parse command flags.
|
|
|
|
fs := flag.NewFlagSet("", flag.ExitOnError)
|
|
|
|
var (
|
|
|
|
configPath = fs.String("config", "", "")
|
|
|
|
pidPath = fs.String("pidfile", "", "")
|
|
|
|
hostname = fs.String("hostname", "", "")
|
|
|
|
join = fs.String("join", "", "")
|
2015-02-23 20:27:51 +00:00
|
|
|
cpuprofile = fs.String("cpuprofile", "", "")
|
|
|
|
memprofile = fs.String("memprofile", "", "")
|
2015-02-02 21:01:35 +00:00
|
|
|
)
|
|
|
|
fs.Usage = printRunUsage
|
|
|
|
fs.Parse(args)
|
|
|
|
|
2015-02-23 20:27:51 +00:00
|
|
|
// Start profiling, if set.
|
|
|
|
startProfiling(*cpuprofile, *memprofile)
|
|
|
|
defer stopProfiling()
|
|
|
|
|
2015-02-02 21:01:35 +00:00
|
|
|
// Print sweet InfluxDB logo and write the process id to file.
|
|
|
|
log.Print(logo)
|
|
|
|
log.SetPrefix(`[srvr] `)
|
|
|
|
log.SetFlags(log.LstdFlags)
|
|
|
|
writePIDFile(*pidPath)
|
|
|
|
|
|
|
|
config := parseConfig(*configPath, *hostname)
|
|
|
|
|
|
|
|
// Create a logging writer.
|
|
|
|
logWriter := os.Stderr
|
|
|
|
if config.Logging.File != "" {
|
|
|
|
var err error
|
|
|
|
logWriter, err = os.OpenFile(config.Logging.File, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0660)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("unable to open log file %s: %s", config.Logging.File, err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.SetOutput(logWriter)
|
|
|
|
|
|
|
|
Run(config, *join, version, logWriter)
|
|
|
|
|
|
|
|
// Wait indefinitely.
|
|
|
|
<-(chan struct{})(nil)
|
|
|
|
}
|
|
|
|
|
2015-03-20 04:23:52 +00:00
|
|
|
// execRestore restores a backup archive to the data directory and bootstraps the broker.
|
|
|
|
func execRestore(args []string) {
|
|
|
|
// Parse command line arguments.
|
|
|
|
fs := flag.NewFlagSet("", flag.ExitOnError)
|
|
|
|
configPath := fs.String("config", "", "")
|
|
|
|
fs.Usage = printRestoreUsage
|
|
|
|
fs.Parse(args)
|
|
|
|
|
|
|
|
// Path to the archive is the first argument.
|
|
|
|
path := fs.Arg(0)
|
|
|
|
|
|
|
|
Restore(path, *configPath)
|
|
|
|
}
|
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
// 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() {
|
|
|
|
log.Println(`usage: version
|
2014-10-22 00:20:43 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
version displays the InfluxDB version and build git commit hash
|
|
|
|
`)
|
2013-12-03 22:19:42 +00:00
|
|
|
}
|
2014-12-06 01:02:30 +00:00
|
|
|
fs.Parse(args)
|
2014-11-11 05:25:03 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
s := fmt.Sprintf("InfluxDB v%s", version)
|
|
|
|
if commit != "" {
|
|
|
|
s += fmt.Sprintf(" (git: %s)", commit)
|
2014-03-27 23:09:08 +00:00
|
|
|
}
|
2014-12-06 01:02:30 +00:00
|
|
|
log.Print(s)
|
|
|
|
}
|
2014-03-27 16:24:40 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
// execHelp runs the "help" command.
|
|
|
|
func execHelp(args []string) {
|
|
|
|
fmt.Println(`
|
|
|
|
Configure and start an InfluxDB server.
|
2014-11-11 05:25:03 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
Usage:
|
2014-11-11 05:25:03 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
influxd [[command] [arguments]]
|
2014-11-11 05:25:03 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
The commands are:
|
2014-11-11 05:25:03 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
join-cluster create a new node that will join an existing cluster
|
|
|
|
run run node with existing configuration
|
|
|
|
version displays the InfluxDB version
|
2014-10-21 05:32:47 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
"run" is the default command.
|
2014-10-21 05:32:47 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
Use "influxd help [command]" for more information about a command.
|
|
|
|
`)
|
2014-10-21 05:32:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Stopper interface {
|
|
|
|
Stop()
|
|
|
|
}
|
2014-12-06 01:02:30 +00:00
|
|
|
|
|
|
|
type State struct {
|
|
|
|
Mode string `json:"mode"`
|
|
|
|
}
|
2015-02-23 20:27:51 +00:00
|
|
|
|
|
|
|
var prof struct {
|
|
|
|
cpu *os.File
|
|
|
|
mem *os.File
|
|
|
|
}
|
|
|
|
|
|
|
|
func startProfiling(cpuprofile, memprofile string) {
|
|
|
|
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
|
|
|
|
stopProfiling()
|
|
|
|
os.Exit(0)
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
func stopProfiling() {
|
|
|
|
if prof.cpu != nil {
|
|
|
|
pprof.StopCPUProfile()
|
|
|
|
prof.cpu.Close()
|
|
|
|
}
|
|
|
|
if prof.mem != nil {
|
|
|
|
pprof.Lookup("heap").WriteTo(prof.mem, 0)
|
|
|
|
prof.mem.Close()
|
|
|
|
}
|
|
|
|
}
|