// The influx_tools command displays detailed information about InfluxDB data files. package main import ( "errors" "fmt" "io" "os" "time" "github.com/influxdata/influxdb/cmd" "github.com/influxdata/influxdb/cmd/influx_tools/compact" "github.com/influxdata/influxdb/cmd/influx_tools/export" genexec "github.com/influxdata/influxdb/cmd/influx_tools/generate/exec" geninit "github.com/influxdata/influxdb/cmd/influx_tools/generate/init" "github.com/influxdata/influxdb/cmd/influx_tools/help" "github.com/influxdata/influxdb/cmd/influx_tools/importer" "github.com/influxdata/influxdb/cmd/influx_tools/server" "github.com/influxdata/influxdb/cmd/influxd/run" "github.com/influxdata/influxdb/services/meta" "github.com/influxdata/influxdb/tsdb" _ "github.com/influxdata/influxdb/tsdb/engine" "go.uber.org/zap" ) func main() { m := NewMain() if err := m.Run(os.Args[1:]...); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } // Main represents the program execution. type Main struct { Stdin io.Reader Stdout io.Writer Stderr io.Writer } // NewMain returns a new instance of Main. func NewMain() *Main { return &Main{ Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, } } // Run determines and runs the command specified by the CLI args. func (m *Main) Run(args ...string) error { name, args := cmd.ParseCommandName(args) // Extract name from args. switch name { case "", "help": if err := help.NewCommand().Run(args...); err != nil { return fmt.Errorf("help failed: %s", err) } case "compact-shard": c := compact.NewCommand() if err := c.Run(args); err != nil { return fmt.Errorf("compact-shard failed: %s", err) } case "export": c := export.NewCommand(&ossServer{logger: zap.NewNop()}) if err := c.Run(args); err != nil { return fmt.Errorf("export failed: %s", err) } case "import": c := importer.NewCommand(&ossServer{logger: zap.NewNop()}) if err := c.Run(args); err != nil { return fmt.Errorf("import failed: %s", err) } case "gen-init": c := geninit.NewCommand(&ossServer{logger: zap.NewNop()}) if err := c.Run(args); err != nil { return fmt.Errorf("gen-init failed: %s", err) } case "gen-exec": deps := genexec.Dependencies{Server: &ossServer{logger: zap.NewNop()}} c := genexec.NewCommand(deps) if err := c.Run(args); err != nil { return fmt.Errorf("gen-exec failed: %s", err) } default: return fmt.Errorf(`unknown command "%s"`+"\n"+`Run 'influx-tools help' for usage`+"\n\n", name) } return nil } type ossServer struct { logger *zap.Logger config *run.Config noClient bool client *meta.Client mc server.MetaClient } func (s *ossServer) Open(path string) (err error) { s.config, err = s.parseConfig(path) if err != nil { return err } // Validate the configuration. if err = s.config.Validate(); err != nil { return fmt.Errorf("validate config: %s", err) } if s.noClient { return nil } s.client = meta.NewClient(s.config.Meta) if err = s.client.Open(); err != nil { s.client = nil return err } s.mc = &ossMetaClient{s.client} return nil } func (s *ossServer) Close() { if s.client != nil { s.client.Close() s.client = nil } } func (s *ossServer) MetaClient() server.MetaClient { return s.mc } func (s *ossServer) TSDBConfig() tsdb.Config { return s.config.Data } func (s *ossServer) Logger() *zap.Logger { return s.logger } func (s *ossServer) NodeID() uint64 { return 0 } // ParseConfig parses the config at path. // It returns a demo configuration if path is blank. func (s *ossServer) parseConfig(path string) (*run.Config, error) { path = s.resolvePath(path) // Use demo configuration if no config path is specified. if path == "" { return nil, errors.New("missing config file") } config := run.NewConfig() if err := config.FromTomlFile(path); err != nil { return nil, err } return config, nil } func (s *ossServer) resolvePath(path string) string { if path != "" { if path == os.DevNull { return "" } return path } for _, p := range []string{ os.ExpandEnv("${HOME}/.influxdb/influxdb.conf"), "/etc/influxdb/influxdb.conf", } { if _, err := os.Stat(p); err == nil { return p } } return "" } type ossMetaClient struct { *meta.Client } func (*ossMetaClient) NodeID() uint64 { return 0 } func (c *ossMetaClient) NodeShardGroupsByTimeRange(database, policy string, min, max time.Time) (a []meta.ShardGroupInfo, err error) { return c.ShardGroupsByTimeRange(database, policy, min, max) }