// main is the application's entry point. It will either spawn a CLI or HTTP itnerfaces. func main() { configFile := flag.String("config", "", "config file name") command := flag.String("c", "", "command (discover|forget|continuous|move-up|move-below|begin-maintenance|end-maintenance|clusters|topology)") instance := flag.String("i", "", "instance, host:port") sibling := flag.String("s", "", "sibling instance, host:port") owner := flag.String("owner", "", "operation owner") reason := flag.String("reason", "", "operation reason") discovery := flag.Bool("discovery", true, "auto discovery mode") verbose := flag.Bool("verbose", false, "verbose") debug := flag.Bool("debug", false, "debug mode (very verbose)") stack := flag.Bool("stack", false, "add stack trace upon error") flag.Parse() log.SetLevel(log.ERROR) if *verbose { log.SetLevel(log.INFO) } if *debug { log.SetLevel(log.DEBUG) } if *stack { log.SetPrintStackTrace(*stack) } log.Info("starting") if len(*configFile) > 0 { config.ForceRead(*configFile) } else { config.Read("/etc/orchestrator.conf.json", "conf/orchestrator.conf.json", "orchestrator.conf.json") } switch { case len(flag.Args()) == 0 || flag.Arg(0) == "cli": app.Cli(*command, *instance, *sibling, *owner, *reason) case flag.Arg(0) == "http": app.Http(*discovery) default: log.Error("Usage: orchestrator --options... [cli|http]") } }
// ReadInstance reads an instance from the orchestrator backend database func ReadInstance(instanceKey *InstanceKey) (*Instance, bool, error) { db, err := db.OpenOrchestrator() if err != nil { return nil, false, log.Errore(err) } instance := NewInstance() instance.Key = *instanceKey var slaveHostsJson string var secondsSinceLastChecked uint err = db.QueryRow(` select server_id, version, binlog_format, log_bin, log_slave_updates, binary_log_file, binary_log_pos, master_host, master_port, slave_sql_running, slave_io_running, master_log_file, read_master_log_pos, relay_master_log_file, exec_master_log_pos, seconds_behind_master, slave_lag_seconds, slave_hosts, cluster_name, timestampdiff(second, last_checked, now()) as seconds_since_last_checked, (last_checked <= last_seen) is true as is_last_check_valid, timestampdiff(second, last_seen, now()) as seconds_since_last_seen from database_instance where hostname=? and port=?`, instanceKey.Hostname, instanceKey.Port).Scan( &instance.ServerID, &instance.Version, &instance.Binlog_format, &instance.LogBinEnabled, &instance.LogSlaveUpdatesEnabled, &instance.SelfBinlogCoordinates.LogFile, &instance.SelfBinlogCoordinates.LogPos, &instance.MasterKey.Hostname, &instance.MasterKey.Port, &instance.Slave_SQL_Running, &instance.Slave_IO_Running, &instance.ReadBinlogCoordinates.LogFile, &instance.ReadBinlogCoordinates.LogPos, &instance.ExecBinlogCoordinates.LogFile, &instance.ExecBinlogCoordinates.LogPos, &instance.SecondsBehindMaster, &instance.SlaveLagSeconds, &slaveHostsJson, &instance.ClusterName, &secondsSinceLastChecked, &instance.IsLastCheckValid, &instance.SecondsSinceLastSeen, ) if err == sql.ErrNoRows { log.Infof("No entry for %+v", instanceKey) return instance, false, err } if err != nil { log.Error("error on", instanceKey, err) return instance, false, err } instance.IsUpToDate = (secondsSinceLastChecked <= config.Config.InstancePollSeconds) instance.IsRecentlyChecked = (secondsSinceLastChecked <= config.Config.InstancePollSeconds*5) instance.ReadSlaveHostsFromJson(slaveHostsJson) return instance, true, err }