func main() { flag.Parse() if flags.Help { flag.Usage() os.Exit(2) } if flags.Version { fmt.Printf("%s main: %s, data: %s\n", path.Base(os.Args[0]), cbgt.VERSION, cbgt.VERSION) os.Exit(0) } cmd.MainCommon(cbgt.VERSION, flagAliases) options := cmd.ParseOptions(flags.Options, "CBGTCTL_ENV_OPTIONS", nil) cfg, err := cmd.MainCfgClient(path.Base(os.Args[0]), flags.CfgConnect) if err != nil { log.Fatalf("%v", err) return } if flags.IndexTypes != "" { cmd.RegisterIndexTypes(strings.Split(flags.IndexTypes, ",")) } nodesToRemove := []string(nil) if len(flags.RemoveNodes) > 0 { nodesToRemove = strings.Split(flags.RemoveNodes, ",") } steps := map[string]bool{} if flags.Steps != "" { steps = cbgt.StringsToMap(strings.Split(flags.Steps, ",")) } // ------------------------------------------------ if steps != nil && steps["rebalance"] { steps["rebalance_"] = true steps["unregister"] = true steps["planner"] = true } // ------------------------------------------------ if steps != nil && steps["rebalance_"] { log.Printf("main: step rebalance_") err := rebalance.RunRebalance(cfg, flags.Server, options, nodesToRemove, flags.FavorMinNodes, flags.DryRun, flags.Verbose, nil) if err != nil { log.Fatalf("main: RunRebalance, err: %v", err) return } } // ------------------------------------------------ err = cmd.PlannerSteps(steps, cfg, cbgt.VERSION, flags.Server, options, nodesToRemove, flags.DryRun, nil) if err != nil { log.Fatalf("main: PlannerSteps, err: %v", err) return } // ------------------------------------------------ var c *ctl.Ctl if steps != nil && (steps["service"] || steps["rest"] || steps["prompt"]) { c, err = ctl.StartCtl(cfg, flags.Server, options, ctl.CtlOptions{ DryRun: flags.DryRun, Verbose: flags.Verbose, FavorMinNodes: flags.FavorMinNodes, WaitForMemberNodes: flags.WaitForMemberNodes, }) if err != nil { log.Fatalf("main: StartCtl, err: %v", err) return } if steps["service"] { // TODO. } if steps["rest"] { bindHttp := flags.BindHttp if bindHttp[0] == ':' { bindHttp = "localhost" + bindHttp } if strings.HasPrefix(bindHttp, "0.0.0.0:") { bindHttp = "localhost" + bindHttp[len("0.0.0.0"):] } http.Handle("/", newRestRouter(c)) go func() { log.Printf("------------------------------------------------------------") log.Printf("REST API is available: http://%s", bindHttp) log.Printf("------------------------------------------------------------") err := http.ListenAndServe(bindHttp, nil) // Blocks. if err != nil { log.Fatalf("main: listen, err: %v\n"+ " Please check that your -bindHttp parameter (%q)\n"+ " is correct and available.", err, bindHttp) } }() } if steps["prompt"] { go runCtlPrompt(c) } <-make(chan struct{}) } // ------------------------------------------------ log.Printf("main: done") }
func main() { platform.HideConsole(true) defer platform.HideConsole(false) flag.Parse() if flags.Help { flag.Usage() os.Exit(2) } if flags.Version { fmt.Printf("%s main: %s, data: %s\n", path.Base(os.Args[0]), VERSION, cbgt.VERSION) os.Exit(0) } if os.Getenv("GOMAXPROCS") == "" { runtime.GOMAXPROCS(runtime.NumCPU()) } mr, err := cbgt.NewMsgRing(os.Stderr, 1000) if err != nil { log.Fatalf("main: could not create MsgRing, err: %v", err) } log.SetOutput(mr) log.SetLoggerCallback(LoggerFunc) log.Printf("main: %s started (%s/%s)", os.Args[0], VERSION, cbgt.VERSION) rand.Seed(time.Now().UTC().UnixNano()) // disabling as speculative change for // https://issues.couchbase.com/browse/MB-20002 // theory being that invoking signal.Notify() // interferes with forestdb signal handler // go cmd.DumpOnSignalForPlatform() MainWelcome(flagAliases) s, err := os.Stat(flags.DataDir) if err != nil { if os.IsNotExist(err) { if flags.DataDir == DEFAULT_DATA_DIR { log.Printf("main: creating data directory, dataDir: %s", flags.DataDir) err = os.Mkdir(flags.DataDir, 0700) if err != nil { log.Fatalf("main: could not create data directory,"+ " dataDir: %s, err: %v", flags.DataDir, err) } } else { log.Fatalf("main: data directory does not exist,"+ " dataDir: %s", flags.DataDir) return } } else { log.Fatalf("main: could not access data directory,"+ " dataDir: %s, err: %v", flags.DataDir, err) return } } else { if !s.IsDir() { log.Fatalf("main: not a directory, dataDir: %s", flags.DataDir) return } } wd, err := os.Getwd() if err != nil { log.Fatalf("main: os.Getwd, err: %#v", err) return } log.Printf("main: curr dir: %q", wd) dataDirAbs, err := filepath.Abs(flags.DataDir) if err != nil { log.Fatalf("main: filepath.Abs, err: %#v", err) return } log.Printf("main: data dir: %q", dataDirAbs) uuid := flags.UUID if uuid != "" { uuidPath := flags.DataDir + string(os.PathSeparator) + cmdName + ".uuid" err = ioutil.WriteFile(uuidPath, []byte(uuid), 0600) if err != nil { log.Fatalf("main: could not write uuidPath: %s\n"+ " Please check that your -data/-dataDir parameter (%q)\n"+ " is to a writable directory where %s can persist data.", uuidPath, flags.DataDir, cmdName) return } } if uuid == "" { uuid, err = cmd.MainUUID(cmdName, flags.DataDir) if err != nil { log.Fatalf("%v", err) return } } options := cmd.ParseOptions(flags.Options, "CBFT_ENV_OPTIONS", map[string]string{ "managerLoadDataDir": "async", "authType": flags.AuthType, }) err = InitHttpOptions(options) if err != nil { log.Fatalf("main: InitHttpOptions, err: %v", err) return } // User may supply a comma-separated list of HOST:PORT values for // http addresss/port listening, but only the first http entry // is used for cbgt node and Cfg registration. bindHttpList := strings.Split(flags.BindHttp, ",") // If cfg is down, we error, leaving it to some user-supplied // outside watchdog to backoff and restart/retry. cfg, err := cmd.MainCfgEx(cmdName, flags.CfgConnect, bindHttpList[0], flags.Register, flags.DataDir, uuid, options) if err != nil { if err == cmd.ErrorBindHttp { log.Fatalf("%v", err) return } log.Fatalf("main: could not start cfg, cfgConnect: %s, err: %v\n"+ " Please check that your -cfg/-cfgConnect parameter (%q)\n"+ " is correct and/or that your configuration provider\n"+ " is available.", flags.CfgConnect, err, flags.CfgConnect) return } var tagsArr []string if flags.Tags != "" { tagsArr = strings.Split(flags.Tags, ",") } router, err := MainStart(cfg, uuid, tagsArr, flags.Container, flags.Weight, flags.Extras, bindHttpList[0], flags.DataDir, flags.StaticDir, flags.StaticETag, flags.Server, flags.Register, mr, options) if err != nil { log.Fatal(err) } if flags.Register == "unknown" { log.Printf("main: unregistered node; now exiting") os.Exit(0) } http.Handle("/", router) anyHostPorts := map[string]bool{} // Bind to 0.0.0.0's first for http listening. for _, bindHttp := range bindHttpList { if strings.HasPrefix(bindHttp, "0.0.0.0:") { go MainServeHttp("http", bindHttp, nil, "", "") anyHostPorts[bindHttp] = true } } for i := len(bindHttpList) - 1; i >= 1; i-- { go MainServeHttp("http", bindHttpList[i], anyHostPorts, "", "") } if flags.BindHttps != "" { bindHttpsList := strings.Split(flags.BindHttps, ",") // Bind to 0.0.0.0's first for https listening. for _, bindHttps := range bindHttpsList { if strings.HasPrefix(bindHttps, "0.0.0.0:") { go MainServeHttp("https", bindHttps, nil, flags.TlsCertFile, flags.TlsKeyFile) anyHostPorts[bindHttps] = true } } for _, bindHttps := range bindHttpsList { go MainServeHttp("https", bindHttps, anyHostPorts, flags.TlsCertFile, flags.TlsKeyFile) } } MainServeHttp("http", bindHttpList[0], anyHostPorts, "", "") <-(make(chan struct{})) // Block forever. }