influxdb/cmd/influxd/main.go

206 lines
4.7 KiB
Go
Raw Normal View History

package main
import (
"flag"
"fmt"
2015-05-30 14:49:49 +00:00
"io"
2015-07-15 17:14:11 +00:00
"log"
"math/rand"
"os"
2015-07-15 17:14:11 +00:00
"os/signal"
"strings"
2015-07-15 17:14:11 +00:00
"syscall"
"time"
2015-01-24 20:11:03 +00:00
"github.com/influxdb/influxdb/cmd/influxd/backup"
2015-05-30 14:49:49 +00:00
"github.com/influxdb/influxdb/cmd/influxd/help"
"github.com/influxdb/influxdb/cmd/influxd/restore"
2015-05-29 19:50:05 +00:00
"github.com/influxdb/influxdb/cmd/influxd/run"
)
// These variables are populated via the Go linker.
var (
version = "0.9"
2015-09-25 06:32:47 +00:00
commit string
branch string
buildTime string
)
func init() {
2015-09-25 06:32:47 +00:00
// If commit, branch, or build time are not set, make that clear.
if commit == "" {
commit = "unknown"
}
if branch == "" {
branch = "unknown"
}
2015-09-25 06:32:47 +00:00
if buildTime == "" {
buildTime = "unknown"
}
}
func main() {
rand.Seed(time.Now().UnixNano())
2015-05-30 14:49:49 +00:00
m := NewMain()
if err := m.Run(os.Args[1:]...); err != nil {
fmt.Fprintln(os.Stderr, err)
2015-05-30 14:49:49 +00:00
os.Exit(1)
}
2015-05-30 14:49:49 +00:00
}
2015-05-30 14:49:49 +00:00
// Main represents the program execution.
type Main struct {
2015-07-15 17:14:11 +00:00
Logger *log.Logger
2015-05-30 14:49:49 +00:00
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}
2015-05-30 14:49:49 +00:00
// NewMain return a new instance of Main.
func NewMain() *Main {
return &Main{
2015-07-15 17:14:11 +00:00
Logger: log.New(os.Stderr, "[run] ", log.LstdFlags),
2015-05-30 14:49:49 +00:00
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
2015-05-30 14:49:49 +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)
// Extract name from args.
2015-05-30 14:49:49 +00:00
switch name {
case "", "run":
cmd := run.NewCommand()
// Tell the server the build details.
cmd.Version = version
cmd.Commit = commit
cmd.Branch = branch
2015-09-25 06:32:47 +00:00
cmd.BuildTime = buildTime
if err := cmd.Run(args...); err != nil {
2015-05-30 14:49:49 +00:00
return fmt.Errorf("run: %s", err)
}
2015-07-15 17:14:11 +00:00
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
m.Logger.Println("Listening for signals")
2015-07-15 17:14:11 +00:00
// Block until one of the signals above is received
select {
case <-signalCh:
m.Logger.Println("Signal received, initializing clean shutdown...")
2015-07-15 17:14:11 +00:00
go func() {
cmd.Close()
}()
}
// Block again until another signal is received, a shutdown timeout elapses,
// or the Command is gracefully closed
m.Logger.Println("Waiting for clean shutdown...")
2015-07-15 17:14:11 +00:00
select {
case <-signalCh:
m.Logger.Println("second signal received, initializing hard shutdown")
case <-time.After(time.Second * 30):
m.Logger.Println("time limit reached, initializing hard shutdown")
case <-cmd.Closed:
m.Logger.Println("server shutdown completed")
}
// goodbye.
case "backup":
name := backup.NewCommand()
if err := name.Run(args...); err != nil {
return fmt.Errorf("backup: %s", err)
}
case "restore":
name := restore.NewCommand()
if err := name.Run(args...); err != nil {
return fmt.Errorf("restore: %s", err)
}
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 := NewVersionCommand().Run(args...); err != nil {
2015-05-30 14:49:49 +00:00
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
}
default:
return fmt.Errorf(`unknown command "%s"`+"\n"+`Run 'influxd help' for usage`+"\n\n", name)
}
return nil
2015-05-30 14:49:49 +00:00
}
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]
}
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
}
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]
}
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
}
// VersionCommand represents the command executed by "influxd version".
type VersionCommand struct {
Stdout io.Writer
Stderr io.Writer
}
// NewVersionCommand return a new instance of VersionCommand.
func NewVersionCommand() *VersionCommand {
return &VersionCommand{
Stdout: os.Stdout,
Stderr: os.Stderr,
}
}
// Run prints the current version and commit info.
func (cmd *VersionCommand) 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(versionUsage)) }
if err := fs.Parse(args); err != nil {
return err
}
// Print version info.
2015-09-25 06:32:47 +00:00
fmt.Fprintf(cmd.Stdout, "InfluxDB v%s (git: %s %s, built %s)\n", version, branch, commit, buildTime)
return nil
}
var versionUsage = `
usage: version
version displays the InfluxDB version, build branch and git commit hash
`