2014-12-06 01:02:30 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2015-03-25 16:49:05 +00:00
|
|
|
"flag"
|
2015-02-12 00:10:18 +00:00
|
|
|
"fmt"
|
2014-12-06 01:02:30 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
2015-02-03 16:51:05 +00:00
|
|
|
"net"
|
2014-12-06 01:02:30 +00:00
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2015-03-25 16:49:05 +00:00
|
|
|
"runtime"
|
2014-12-06 01:02:30 +00:00
|
|
|
"strconv"
|
2014-12-16 07:03:09 +00:00
|
|
|
"strings"
|
2015-02-10 21:41:55 +00:00
|
|
|
"time"
|
2014-12-06 01:02:30 +00:00
|
|
|
|
|
|
|
"github.com/influxdb/influxdb"
|
2015-02-11 07:03:23 +00:00
|
|
|
"github.com/influxdb/influxdb/admin"
|
2015-01-09 00:09:28 +00:00
|
|
|
"github.com/influxdb/influxdb/collectd"
|
2014-12-31 21:37:58 +00:00
|
|
|
"github.com/influxdb/influxdb/graphite"
|
2015-01-20 17:50:13 +00:00
|
|
|
"github.com/influxdb/influxdb/httpd"
|
2014-12-06 01:02:30 +00:00
|
|
|
"github.com/influxdb/influxdb/messaging"
|
2015-03-29 16:26:03 +00:00
|
|
|
"github.com/influxdb/influxdb/opentsdb"
|
2015-03-10 20:53:45 +00:00
|
|
|
"github.com/influxdb/influxdb/raft"
|
2015-03-04 20:31:39 +00:00
|
|
|
"github.com/influxdb/influxdb/udp"
|
2014-12-06 01:02:30 +00:00
|
|
|
)
|
|
|
|
|
2015-03-25 16:49:05 +00:00
|
|
|
type RunCommand struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewRunCommand() *RunCommand {
|
|
|
|
return &RunCommand{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RunCommand) Run(args ...string) error {
|
|
|
|
// 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", "", "")
|
|
|
|
cpuprofile = fs.String("cpuprofile", "", "")
|
|
|
|
memprofile = fs.String("memprofile", "", "")
|
|
|
|
)
|
|
|
|
fs.Usage = printRunUsage
|
|
|
|
fs.Parse(args)
|
|
|
|
|
|
|
|
// Start profiling, if set.
|
|
|
|
startProfiling(*cpuprofile, *memprofile)
|
|
|
|
defer stopProfiling()
|
|
|
|
|
|
|
|
// Print sweet InfluxDB logo and write the process id to file.
|
|
|
|
fmt.Print(logo)
|
|
|
|
writePIDFile(*pidPath)
|
|
|
|
|
|
|
|
// Set parallelism.
|
|
|
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
|
|
|
log.Printf("GOMAXPROCS set to %d", runtime.GOMAXPROCS(0))
|
|
|
|
|
|
|
|
// Parse configuration file from disk.
|
|
|
|
config, err := parseConfig(*configPath, *hostname)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
} else if *configPath == "" {
|
|
|
|
log.Println("No config provided, using default settings")
|
|
|
|
}
|
|
|
|
|
|
|
|
Run(config, *join, version)
|
|
|
|
|
|
|
|
// Wait indefinitely.
|
|
|
|
<-(chan struct{})(nil)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-03-30 22:41:56 +00:00
|
|
|
func Run(config *Config, join, version string) (*messaging.Broker, *influxdb.Server, *raft.Log) {
|
2015-02-24 17:47:07 +00:00
|
|
|
log.Printf("influxdb started, version %s, commit %s", version, commit)
|
|
|
|
|
2015-03-06 18:24:56 +00:00
|
|
|
var initBroker, initServer bool
|
|
|
|
if initBroker = !fileExists(config.BrokerDir()); initBroker {
|
|
|
|
log.Printf("Broker directory missing. Need to create a broker.")
|
|
|
|
}
|
|
|
|
|
|
|
|
if initServer = !fileExists(config.DataDir()); initServer {
|
|
|
|
log.Printf("Data directory missing. Need to create data directory.")
|
|
|
|
}
|
|
|
|
initServer = initServer || initBroker
|
2015-01-29 22:11:10 +00:00
|
|
|
|
2015-01-27 01:29:30 +00:00
|
|
|
// Parse join urls from the --join flag.
|
2015-03-10 20:53:45 +00:00
|
|
|
var joinURLs []url.URL
|
2015-02-02 21:01:35 +00:00
|
|
|
if join == "" {
|
2015-01-27 01:29:30 +00:00
|
|
|
joinURLs = parseURLs(config.JoinURLs())
|
|
|
|
} else {
|
2015-02-02 21:01:35 +00:00
|
|
|
joinURLs = parseURLs(join)
|
2015-01-27 01:29:30 +00:00
|
|
|
}
|
2014-12-31 19:42:53 +00:00
|
|
|
|
2015-03-10 20:53:45 +00:00
|
|
|
// Open broker & raft log, initialize or join as necessary.
|
2015-03-26 00:40:18 +00:00
|
|
|
b, l := openBroker(config.BrokerDir(), config.BrokerURL(), initBroker, joinURLs, config.Logging.RaftTracing)
|
2014-12-30 22:46:50 +00:00
|
|
|
|
2015-01-07 00:21:32 +00:00
|
|
|
// Start the broker handler.
|
2015-03-31 22:45:33 +00:00
|
|
|
h := &Handler{
|
|
|
|
Config: config,
|
|
|
|
Broker: b,
|
|
|
|
Log: l,
|
|
|
|
}
|
2015-03-10 20:53:45 +00:00
|
|
|
|
2015-03-31 22:45:33 +00:00
|
|
|
// We want to make sure we are spun up before we exit this function, so we manually listen and serve
|
|
|
|
listener, err := net.Listen("tcp", config.BrokerAddr())
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("TCP server failed to listen on %s. %s ", config.BrokerAddr(), err)
|
|
|
|
}
|
|
|
|
go func() {
|
|
|
|
err := http.Serve(listener, h)
|
2015-02-03 16:51:05 +00:00
|
|
|
if err != nil {
|
2015-03-31 22:45:33 +00:00
|
|
|
log.Fatalf("TCP server failed to server on %s: %s", config.BrokerAddr(), err)
|
2015-02-03 16:51:05 +00:00
|
|
|
}
|
2015-03-31 22:45:33 +00:00
|
|
|
}()
|
|
|
|
log.Printf("TCP server listening on %s", config.BrokerAddr())
|
2015-02-12 21:38:33 +00:00
|
|
|
|
2015-03-31 22:45:33 +00:00
|
|
|
// have it occasionally tell a data node in the cluster to run continuous queries
|
|
|
|
if config.ContinuousQuery.Disable {
|
|
|
|
log.Printf("Not running continuous queries. [continuous_queries].disable is set to true.")
|
|
|
|
} else {
|
|
|
|
b.RunContinuousQueryLoop()
|
2014-12-31 19:42:53 +00:00
|
|
|
}
|
2014-12-30 22:46:50 +00:00
|
|
|
|
2015-01-07 00:21:32 +00:00
|
|
|
// Open server, initialize or join as necessary.
|
2015-03-26 00:40:18 +00:00
|
|
|
s := openServer(config, b, initServer, initBroker, joinURLs)
|
2015-02-05 22:54:32 +00:00
|
|
|
s.SetAuthenticationEnabled(config.Authentication.Enabled)
|
2014-12-31 19:42:53 +00:00
|
|
|
|
2015-02-10 21:41:55 +00:00
|
|
|
// Enable retention policy enforcement if requested.
|
|
|
|
if config.Data.RetentionCheckEnabled {
|
|
|
|
interval := time.Duration(config.Data.RetentionCheckPeriod)
|
2015-02-11 01:17:28 +00:00
|
|
|
if err := s.StartRetentionPolicyEnforcement(interval); err != nil {
|
2015-02-10 21:41:55 +00:00
|
|
|
log.Fatalf("retention policy enforcement failed: %s", err.Error())
|
|
|
|
}
|
|
|
|
log.Printf("broker enforcing retention policies with check interval of %s", interval)
|
|
|
|
}
|
|
|
|
|
2015-03-09 23:27:15 +00:00
|
|
|
// Start shard group pre-create
|
|
|
|
interval := config.ShardGroupPreCreateCheckPeriod()
|
|
|
|
if err := s.StartShardGroupsPreCreate(interval); err != nil {
|
|
|
|
log.Fatalf("shard group pre-create failed: %s", err.Error())
|
|
|
|
}
|
|
|
|
log.Printf("shard group pre-create with check interval of %s", interval)
|
|
|
|
|
2015-01-10 16:08:00 +00:00
|
|
|
// Start the server handler. Attach to broker if listening on the same port.
|
2015-01-07 00:21:32 +00:00
|
|
|
if s != nil {
|
2015-03-31 22:45:33 +00:00
|
|
|
h.Server = s
|
2015-03-26 23:09:48 +00:00
|
|
|
if config.Snapshot.Enabled {
|
|
|
|
// Start snapshot handler.
|
|
|
|
go func() {
|
|
|
|
log.Fatal(http.ListenAndServe(
|
|
|
|
config.SnapshotAddr(),
|
|
|
|
&httpd.SnapshotHandler{
|
|
|
|
CreateSnapshotWriter: s.CreateSnapshotWriter,
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}()
|
|
|
|
log.Printf("snapshot endpoint listening on %s", config.SnapshotAddr())
|
|
|
|
} else {
|
|
|
|
log.Println("snapshot endpoint disabled")
|
|
|
|
}
|
2015-03-22 16:28:04 +00:00
|
|
|
|
2015-02-11 07:34:17 +00:00
|
|
|
// Start the admin interface on the default port
|
2015-02-12 00:10:18 +00:00
|
|
|
if config.Admin.Enabled {
|
|
|
|
port := fmt.Sprintf(":%d", config.Admin.Port)
|
|
|
|
log.Printf("starting admin server on %s", port)
|
|
|
|
a := admin.NewServer(port)
|
2015-02-11 07:34:17 +00:00
|
|
|
go a.ListenAndServe()
|
|
|
|
}
|
2015-02-11 07:03:23 +00:00
|
|
|
|
2015-01-09 00:09:28 +00:00
|
|
|
// Spin up the collectd server
|
|
|
|
if config.Collectd.Enabled {
|
|
|
|
c := config.Collectd
|
2015-01-10 03:12:18 +00:00
|
|
|
cs := collectd.NewServer(s, c.TypesDB)
|
|
|
|
cs.Database = c.Database
|
2015-01-11 14:44:52 +00:00
|
|
|
err := collectd.ListenAndServe(cs, c.ConnectionString(config.BindAddress))
|
2015-01-09 00:09:28 +00:00
|
|
|
if err != nil {
|
2015-01-11 14:44:52 +00:00
|
|
|
log.Printf("failed to start collectd Server: %v\n", err.Error())
|
2015-01-09 00:09:28 +00:00
|
|
|
}
|
|
|
|
}
|
2015-02-11 07:03:23 +00:00
|
|
|
|
2015-03-04 20:31:39 +00:00
|
|
|
// Start the server bound to a UDP listener
|
2015-03-04 21:37:04 +00:00
|
|
|
if config.UDP.Enabled {
|
|
|
|
log.Printf("Starting UDP listener on %s", config.DataAddrUDP())
|
2015-03-04 20:31:39 +00:00
|
|
|
u := udp.NewUDPServer(s)
|
2015-03-04 21:37:04 +00:00
|
|
|
if err := u.ListenAndServe(config.DataAddrUDP()); err != nil {
|
|
|
|
log.Printf("Failed to start UDP listener on %s: %s", config.DataAddrUDP(), err)
|
2015-03-04 20:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-01-06 22:26:31 +00:00
|
|
|
// Spin up any Graphite servers
|
2015-01-08 20:28:10 +00:00
|
|
|
for _, c := range config.Graphites {
|
2015-01-06 22:26:31 +00:00
|
|
|
if !c.Enabled {
|
|
|
|
continue
|
|
|
|
}
|
2015-01-02 16:09:11 +00:00
|
|
|
|
2015-01-07 07:18:14 +00:00
|
|
|
// Configure Graphite parsing.
|
|
|
|
parser := graphite.NewParser()
|
2015-01-08 00:15:39 +00:00
|
|
|
parser.Separator = c.NameSeparatorString()
|
2015-01-08 20:23:48 +00:00
|
|
|
parser.LastEnabled = c.LastEnabled()
|
2015-01-07 07:18:14 +00:00
|
|
|
|
2015-03-12 20:29:51 +00:00
|
|
|
if err := s.CreateDatabaseIfNotExists(c.DatabaseString()); err != nil {
|
|
|
|
log.Fatalf("failed to create database for %s Graphite server: %s", c.Protocol, err.Error())
|
|
|
|
}
|
|
|
|
|
2015-03-12 19:12:23 +00:00
|
|
|
// Spin up the server.
|
|
|
|
var g graphite.Server
|
2015-03-12 20:29:51 +00:00
|
|
|
g, err := graphite.NewServer(c.Protocol, parser, s, c.DatabaseString())
|
2015-03-12 19:12:23 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to initialize %s Graphite server: %s", c.Protocol, err.Error())
|
|
|
|
}
|
2015-03-12 20:29:51 +00:00
|
|
|
|
2015-03-12 19:12:23 +00:00
|
|
|
err = g.ListenAndServe(c.ConnectionString(config.BindAddress))
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to start %s Graphite server: %s", c.Protocol, err.Error())
|
2015-01-06 03:14:43 +00:00
|
|
|
}
|
2015-01-02 16:09:11 +00:00
|
|
|
}
|
2015-03-12 23:23:33 +00:00
|
|
|
|
2015-03-29 16:26:03 +00:00
|
|
|
// Spin up any OpenTSDB servers
|
|
|
|
if config.OpenTSDB.Enabled {
|
|
|
|
o := config.OpenTSDB
|
|
|
|
db := o.DatabaseString()
|
|
|
|
laddr := o.ListenAddress(config.BindAddress)
|
|
|
|
policy := o.RetentionPolicy
|
|
|
|
|
|
|
|
if err := s.CreateDatabaseIfNotExists(db); err != nil {
|
|
|
|
log.Fatalf("failed to create database for OpenTSDB server: %s", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if policy != "" {
|
|
|
|
// Ensure retention policy exists.
|
|
|
|
rp := influxdb.NewRetentionPolicy(policy)
|
|
|
|
if err := s.CreateRetentionPolicyIfNotExists(db, rp); err != nil {
|
|
|
|
log.Fatalf("failed to create retention policy for OpenTSDB: %s", err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
os := opentsdb.NewServer(s, policy, db)
|
|
|
|
|
2015-04-06 18:07:31 +00:00
|
|
|
log.Println("Starting OpenTSDB service on", laddr)
|
2015-03-29 16:26:03 +00:00
|
|
|
go os.ListenAndServe(laddr)
|
|
|
|
}
|
|
|
|
|
2015-03-12 23:23:33 +00:00
|
|
|
// Start up self-monitoring if enabled.
|
2015-04-03 21:24:28 +00:00
|
|
|
if config.Monitoring.Enabled {
|
2015-04-03 21:35:44 +00:00
|
|
|
database := monitoringDatabase
|
|
|
|
policy := monitoringRetentionPolicy
|
2015-04-03 21:24:28 +00:00
|
|
|
interval := time.Duration(config.Monitoring.WriteInterval)
|
2015-03-13 22:26:04 +00:00
|
|
|
|
2015-03-13 23:42:06 +00:00
|
|
|
// Ensure database exists.
|
2015-03-13 22:26:04 +00:00
|
|
|
if err := s.CreateDatabaseIfNotExists(database); err != nil {
|
2015-04-03 21:24:28 +00:00
|
|
|
log.Fatalf("failed to create database %s for internal monitoring: %s", database, err.Error())
|
2015-03-13 22:26:04 +00:00
|
|
|
}
|
2015-03-13 23:42:06 +00:00
|
|
|
|
|
|
|
// Ensure retention policy exists.
|
|
|
|
rp := influxdb.NewRetentionPolicy(policy)
|
|
|
|
if err := s.CreateRetentionPolicyIfNotExists(database, rp); err != nil {
|
2015-04-03 21:24:28 +00:00
|
|
|
log.Fatalf("failed to create retention policy for internal monitoring: %s", err.Error())
|
2015-03-13 23:42:06 +00:00
|
|
|
}
|
|
|
|
|
2015-03-13 23:10:40 +00:00
|
|
|
s.StartSelfMonitoring(database, policy, interval)
|
2015-03-13 22:58:55 +00:00
|
|
|
log.Printf("started self-monitoring at interval of %s", interval)
|
2015-03-12 23:23:33 +00:00
|
|
|
}
|
2014-12-31 19:42:53 +00:00
|
|
|
}
|
2015-02-12 16:59:32 +00:00
|
|
|
|
2015-02-12 19:23:10 +00:00
|
|
|
// unless disabled, start the loop to report anonymous usage stats every 24h
|
|
|
|
if !config.ReportingDisabled {
|
2015-03-06 18:24:56 +00:00
|
|
|
// Make sure we have a config object b4 we try to use it.
|
2015-03-10 22:27:37 +00:00
|
|
|
if clusterID := b.Broker.ClusterID(); clusterID != 0 {
|
2015-03-24 03:13:11 +00:00
|
|
|
go s.StartReportingLoop(clusterID)
|
2015-03-06 18:24:56 +00:00
|
|
|
}
|
2015-02-12 19:23:10 +00:00
|
|
|
}
|
2015-02-12 16:59:32 +00:00
|
|
|
|
2015-03-30 22:41:56 +00:00
|
|
|
return b.Broker, s, l
|
2014-12-30 22:46:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// write the current process id to a file specified by path.
|
|
|
|
func writePIDFile(path string) {
|
|
|
|
if path == "" {
|
|
|
|
return
|
2014-12-06 01:02:30 +00:00
|
|
|
}
|
|
|
|
|
2015-01-27 02:33:06 +00:00
|
|
|
// Ensure the required directory structure exists.
|
2015-03-06 18:24:56 +00:00
|
|
|
err := os.MkdirAll(filepath.Dir(path), 0755)
|
2015-01-27 02:33:06 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2014-12-30 22:46:50 +00:00
|
|
|
// Retrieve the PID and write it.
|
|
|
|
pid := strconv.Itoa(os.Getpid())
|
|
|
|
if err := ioutil.WriteFile(path, []byte(pid), 0644); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-22 20:58:40 +00:00
|
|
|
// parseConfig parses the configuration from a given path. Sets overrides as needed.
|
|
|
|
func parseConfig(path, hostname string) (*Config, error) {
|
2015-01-15 20:42:56 +00:00
|
|
|
if path == "" {
|
2015-03-20 22:13:59 +00:00
|
|
|
c, err := NewConfig()
|
|
|
|
if err != nil {
|
2015-03-22 21:38:41 +00:00
|
|
|
return nil, fmt.Errorf("failed to generate default config: %s. Please supply an explicit configuration file", err.Error())
|
2015-03-20 22:13:59 +00:00
|
|
|
}
|
2015-03-22 21:38:41 +00:00
|
|
|
return c, nil
|
2015-01-15 20:42:56 +00:00
|
|
|
}
|
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
// Parse configuration.
|
2014-12-30 22:46:50 +00:00
|
|
|
config, err := ParseConfigFile(path)
|
2015-01-15 20:42:56 +00:00
|
|
|
if err != nil {
|
2015-03-22 20:58:40 +00:00
|
|
|
return nil, fmt.Errorf("config: %s", err)
|
2014-12-06 01:02:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Override config properties.
|
2014-12-30 22:46:50 +00:00
|
|
|
if hostname != "" {
|
|
|
|
config.Hostname = hostname
|
2014-12-06 01:02:30 +00:00
|
|
|
}
|
|
|
|
|
2015-03-22 20:58:40 +00:00
|
|
|
return config, nil
|
2014-12-30 22:46:50 +00:00
|
|
|
}
|
2014-12-06 01:02:30 +00:00
|
|
|
|
2015-01-07 00:21:32 +00:00
|
|
|
// creates and initializes a broker.
|
2015-03-26 00:40:18 +00:00
|
|
|
func openBroker(path string, u url.URL, initializing bool, joinURLs []url.URL, raftTracing bool) (*influxdb.Broker, *raft.Log) {
|
2015-03-10 20:53:45 +00:00
|
|
|
// Create raft log.
|
|
|
|
l := raft.NewLog()
|
|
|
|
l.SetURL(u)
|
2015-03-10 22:27:37 +00:00
|
|
|
l.DebugEnabled = raftTracing
|
2015-03-10 20:53:45 +00:00
|
|
|
|
2015-01-07 00:21:32 +00:00
|
|
|
// Create broker.
|
2015-01-20 02:44:47 +00:00
|
|
|
b := influxdb.NewBroker()
|
2015-03-10 20:53:45 +00:00
|
|
|
b.Log = l
|
2015-01-20 02:44:47 +00:00
|
|
|
|
2015-03-10 20:53:45 +00:00
|
|
|
// Open broker so it can feed last index data to the log.
|
|
|
|
if err := b.Open(path); err != nil {
|
2015-03-18 15:58:56 +00:00
|
|
|
log.Fatalf("failed to open broker at %s : %s", path, err)
|
2014-12-16 03:35:26 +00:00
|
|
|
}
|
2015-03-20 22:14:42 +00:00
|
|
|
log.Printf("broker opened at %s", path)
|
2015-01-07 00:21:32 +00:00
|
|
|
|
2015-03-10 20:53:45 +00:00
|
|
|
// Attach the broker as the finite state machine of the raft log.
|
|
|
|
l.FSM = &messaging.RaftFSM{Broker: b}
|
|
|
|
|
|
|
|
// Open raft log inside broker directory.
|
|
|
|
if err := l.Open(filepath.Join(path, "raft")); err != nil {
|
|
|
|
log.Fatalf("raft: %s", err)
|
|
|
|
}
|
|
|
|
|
2015-03-06 18:24:56 +00:00
|
|
|
// If this is a new broker then we can initialize two ways:
|
2015-01-07 00:21:32 +00:00
|
|
|
// 1) Start a brand new cluster.
|
|
|
|
// 2) Join an existing cluster.
|
|
|
|
if initializing {
|
|
|
|
if len(joinURLs) == 0 {
|
2015-03-10 20:53:45 +00:00
|
|
|
if err := l.Initialize(); err != nil {
|
|
|
|
log.Fatalf("initialize raft log: %s", err)
|
|
|
|
}
|
2015-01-07 00:21:32 +00:00
|
|
|
} else {
|
2015-03-10 20:53:45 +00:00
|
|
|
joinLog(l, joinURLs)
|
2015-01-07 00:21:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-10 20:53:45 +00:00
|
|
|
return b, l
|
2015-01-07 00:21:32 +00:00
|
|
|
}
|
|
|
|
|
2015-03-10 20:53:45 +00:00
|
|
|
// joins a raft log to an existing cluster.
|
|
|
|
func joinLog(l *raft.Log, joinURLs []url.URL) {
|
2015-01-07 00:21:32 +00:00
|
|
|
// Attempts to join each server until successful.
|
|
|
|
for _, u := range joinURLs {
|
2015-03-10 20:53:45 +00:00
|
|
|
if err := l.Join(u); err != nil {
|
|
|
|
log.Printf("join: failed to connect to raft cluster: %s: %s", u, err)
|
2015-01-07 00:21:32 +00:00
|
|
|
} else {
|
2015-03-10 20:53:45 +00:00
|
|
|
log.Printf("join: connected raft log to %s", u)
|
2015-01-07 00:21:32 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2015-03-10 20:53:45 +00:00
|
|
|
log.Fatalf("join: failed to connect raft log to any specified server")
|
2015-01-07 00:21:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// creates and initializes a server.
|
2015-03-26 00:40:18 +00:00
|
|
|
func openServer(config *Config, b *influxdb.Broker, initServer, initBroker bool, joinURLs []url.URL) *influxdb.Server {
|
2015-03-20 21:10:50 +00:00
|
|
|
// Use broker URL if there are no join URLs passed.
|
2015-03-11 18:00:45 +00:00
|
|
|
clientJoinURLs := joinURLs
|
2015-03-20 21:10:50 +00:00
|
|
|
if len(joinURLs) == 0 {
|
2015-03-11 18:00:45 +00:00
|
|
|
clientJoinURLs = []url.URL{b.URL()}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create messaging client to the brokers.
|
2015-03-30 22:41:56 +00:00
|
|
|
c := influxdb.NewMessagingClient(config.DataURL())
|
2015-04-01 18:01:17 +00:00
|
|
|
c.SetURLs(clientJoinURLs)
|
|
|
|
|
2015-03-14 19:36:06 +00:00
|
|
|
if err := c.Open(filepath.Join(config.Data.Dir, messagingClientFile)); err != nil {
|
2015-03-11 18:00:45 +00:00
|
|
|
log.Fatalf("messaging client error: %s", err)
|
|
|
|
}
|
|
|
|
|
2015-03-14 19:36:06 +00:00
|
|
|
// If no URLs exist on the client the return an error since we cannot reach a broker.
|
|
|
|
if len(c.URLs()) == 0 {
|
|
|
|
log.Fatal("messaging client has no broker URLs")
|
|
|
|
}
|
|
|
|
|
2015-01-07 00:21:32 +00:00
|
|
|
// Create and open the server.
|
2015-02-05 22:54:32 +00:00
|
|
|
s := influxdb.NewServer()
|
2015-03-08 06:55:23 +00:00
|
|
|
s.WriteTrace = config.Logging.WriteTracing
|
2015-03-06 01:52:38 +00:00
|
|
|
s.RetentionAutoCreate = config.Data.RetentionAutoCreate
|
2015-01-25 21:41:39 +00:00
|
|
|
s.RecomputePreviousN = config.ContinuousQuery.RecomputePreviousN
|
|
|
|
s.RecomputeNoOlderThan = time.Duration(config.ContinuousQuery.RecomputeNoOlderThan)
|
|
|
|
s.ComputeRunsPerInterval = config.ContinuousQuery.ComputeRunsPerInterval
|
|
|
|
s.ComputeNoMoreThan = time.Duration(config.ContinuousQuery.ComputeNoMoreThan)
|
2015-03-24 03:13:11 +00:00
|
|
|
s.Version = version
|
|
|
|
s.CommitHash = commit
|
2015-01-25 21:41:39 +00:00
|
|
|
|
2015-03-11 18:00:45 +00:00
|
|
|
// Open server with data directory and broker client.
|
|
|
|
if err := s.Open(config.Data.Dir, c); err != nil {
|
2014-12-31 21:47:10 +00:00
|
|
|
log.Fatalf("failed to open data server: %v", err.Error())
|
2014-12-16 03:35:26 +00:00
|
|
|
}
|
2015-03-20 22:14:42 +00:00
|
|
|
log.Printf("data server opened at %s", config.Data.Dir)
|
2015-01-07 00:21:32 +00:00
|
|
|
|
|
|
|
// If the server is uninitialized then initialize or join it.
|
2015-03-06 18:24:56 +00:00
|
|
|
if initServer {
|
2015-01-07 00:21:32 +00:00
|
|
|
if len(joinURLs) == 0 {
|
2015-03-11 18:00:45 +00:00
|
|
|
if initBroker {
|
|
|
|
if err := s.Initialize(b.URL()); err != nil {
|
|
|
|
log.Fatalf("server initialization error: %s", err)
|
|
|
|
}
|
|
|
|
}
|
2015-01-07 00:21:32 +00:00
|
|
|
} else {
|
2015-01-25 21:41:39 +00:00
|
|
|
joinServer(s, config.DataURL(), joinURLs)
|
2015-01-07 00:21:32 +00:00
|
|
|
}
|
2015-03-06 18:24:56 +00:00
|
|
|
}
|
|
|
|
|
2014-12-31 19:42:53 +00:00
|
|
|
return s
|
|
|
|
}
|
2014-12-16 03:35:26 +00:00
|
|
|
|
2015-01-07 00:21:32 +00:00
|
|
|
// joins a server to an existing cluster.
|
2015-03-10 20:53:45 +00:00
|
|
|
func joinServer(s *influxdb.Server, u url.URL, joinURLs []url.URL) {
|
2015-01-07 00:21:32 +00:00
|
|
|
// TODO: Use separate broker and data join urls.
|
|
|
|
|
|
|
|
// Create data node on an existing data node.
|
|
|
|
for _, joinURL := range joinURLs {
|
2015-03-10 20:53:45 +00:00
|
|
|
if err := s.Join(&u, &joinURL); err != nil {
|
2015-01-07 00:21:32 +00:00
|
|
|
log.Printf("join: failed to connect data node: %s: %s", u, err)
|
|
|
|
} else {
|
|
|
|
log.Printf("join: connected data node to %s", u)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Fatalf("join: failed to connect data node to any specified server")
|
|
|
|
}
|
|
|
|
|
2014-12-31 19:42:53 +00:00
|
|
|
// parses a comma-delimited list of URLs.
|
2015-03-10 20:53:45 +00:00
|
|
|
func parseURLs(s string) (a []url.URL) {
|
2015-01-07 00:21:32 +00:00
|
|
|
if s == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-12-31 19:42:53 +00:00
|
|
|
for _, s := range strings.Split(s, ",") {
|
|
|
|
u, err := url.Parse(s)
|
|
|
|
if err != nil {
|
2015-01-07 00:21:32 +00:00
|
|
|
log.Fatalf("cannot parse urls: %s", err)
|
2014-12-31 19:42:53 +00:00
|
|
|
}
|
2015-03-10 20:53:45 +00:00
|
|
|
a = append(a, *u)
|
2014-12-16 06:05:01 +00:00
|
|
|
}
|
2014-12-31 19:42:53 +00:00
|
|
|
return
|
|
|
|
}
|
2014-12-06 01:02:30 +00:00
|
|
|
|
2014-12-31 19:42:53 +00:00
|
|
|
// returns true if the file exists.
|
|
|
|
func fileExists(path string) bool {
|
|
|
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
2014-12-06 01:02:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func printRunUsage() {
|
2014-12-11 21:49:42 +00:00
|
|
|
log.Printf(`usage: run [flags]
|
2014-12-06 01:02:30 +00:00
|
|
|
|
2015-01-10 16:08:00 +00:00
|
|
|
run starts the broker and data node server. If this is the first time running
|
|
|
|
the command then a new cluster will be initialized unless the -join argument
|
|
|
|
is used.
|
2014-12-06 01:02:30 +00:00
|
|
|
|
|
|
|
-config <path>
|
2015-01-07 00:21:32 +00:00
|
|
|
Set the path to the configuration file.
|
2014-12-06 01:02:30 +00:00
|
|
|
|
|
|
|
-hostname <name>
|
2015-01-07 00:21:32 +00:00
|
|
|
Override the hostname, the 'hostname' configuration
|
|
|
|
option will be overridden.
|
2014-12-06 01:02:30 +00:00
|
|
|
|
2015-01-10 16:08:00 +00:00
|
|
|
-join <url>
|
2015-01-07 00:21:32 +00:00
|
|
|
Joins the server to an existing cluster.
|
2014-12-16 07:03:09 +00:00
|
|
|
|
2014-12-06 01:02:30 +00:00
|
|
|
-pidfile <path>
|
2015-01-07 00:21:32 +00:00
|
|
|
Write process ID to a file.
|
2015-01-16 23:45:31 +00:00
|
|
|
`)
|
2014-12-06 01:02:30 +00:00
|
|
|
}
|