func mustNewNode(enableSingle bool) *Node { node := &Node{ Dir: mustTempDir(), } dbConf := store.NewDBConfig("", false) node.Store = store.New(&store.StoreConfig{ DBConf: dbConf, Dir: node.Dir, Tn: mustMockTransport("localhost:0"), }) if err := node.Store.Open(enableSingle); err != nil { node.Deprovision() panic(fmt.Sprintf("failed to open store: %s", err.Error())) } node.RaftAddr = node.Store.Addr().String() node.Service = httpd.New("localhost:0", node.Store, nil) if err := node.Service.Start(); err != nil { node.Deprovision() panic(fmt.Sprintf("failed to start HTTP server: %s", err.Error())) } node.APIAddr = node.Service.Addr().String() return node }
func main() { flag.Parse() if showVersion { fmt.Printf("rqlited version %s (commit %s)\n", version, commit) os.Exit(0) } // Ensure the data path is set. if flag.NArg() == 0 { flag.Usage() os.Exit(1) } dataPath := flag.Arg(0) // Display logo. fmt.Println(logo) // Configure logging and pump out initial message. log.SetFlags(log.LstdFlags) log.SetPrefix("[rqlited] ") log.Printf("rqlited starting, version %s, commit %s, branch %s", version, commit, branch) // Set up profiling, if requested. if cpuprofile != "" { log.Println("profiling enabled") f, err := os.Create(cpuprofile) if err != nil { log.Printf("unable to create path: %s", err.Error()) } defer f.Close() err = pprof.StartCPUProfile(f) if err != nil { log.Fatalf("unable to start CPU Profile: %s", err.Error()) } defer pprof.StopCPUProfile() } // Set up TCP communication between nodes. ln, err := net.Listen("tcp", raftAddr) if err != nil { log.Fatalf("failed to listen on %s: %s", raftAddr, err.Error()) } var adv net.Addr if raftAdv != "" { adv, err = net.ResolveTCPAddr("tcp", raftAdv) if err != nil { log.Fatalf("failed to resolve advertise address %s: %s", raftAdv, err.Error()) } } mux := tcp.NewMux(ln, adv) go mux.Serve() // Start up mux and get transports for cluster. raftTn := mux.Listen(muxRaftHeader) // Create and open the store. dataPath, err = filepath.Abs(dataPath) if err != nil { log.Fatalf("failed to determine absolute data path: %s", err.Error()) } dbConf := store.NewDBConfig(dsn, !onDisk) store := store.New(dbConf, dataPath, raftTn) if err := store.Open(joinAddr == ""); err != nil { log.Fatalf("failed to open store: %s", err.Error()) } store.SnapshotThreshold = raftSnapThreshold store.HeartbeatTimeout, err = time.ParseDuration(raftHeartbeatTimeout) if err != nil { log.Fatalf("failed to parse Raft heartbeat timeout %s: %s", raftHeartbeatTimeout, err.Error()) } // Create and configure cluster service. tn := mux.Listen(muxMetaHeader) cs := cluster.NewService(tn, store) if err := cs.Open(); err != nil { log.Fatalf("failed to open cluster service: %s", err.Error()) } // If join was specified, make the join request. if joinAddr != "" { if !store.JoinRequired() { log.Println("node is already member of cluster, ignoring join request") } else { if err := join(joinAddr, noVerify, raftAddr, raftAdv); err != nil { log.Fatalf("failed to join node at %s: %s", joinAddr, err.Error()) } log.Println("successfully joined node at", joinAddr) } } // Publish to the cluster the mapping between this Raft address and API address. // The Raft layer broadcasts the resolved address, so use that as the key. But // only set different HTTP advertise address if set. apiAdv := httpAddr if httpAdv != "" { apiAdv = httpAdv } if err := publishAPIAddr(cs, raftTn.Addr().String(), apiAdv, publishPeerTimeout); err != nil { log.Fatalf("failed to set peer for %s to %s: %s", raftAddr, httpAddr, err.Error()) } log.Printf("set peer for %s to %s", raftTn.Addr().String(), apiAdv) // Create HTTP server and load authentication information, if supplied. var s *httpd.Service if authFile != "" { f, err := os.Open(authFile) if err != nil { log.Fatalf("failed to open authentication file %s: %s", authFile, err.Error()) } credentialStore := auth.NewCredentialsStore() if err := credentialStore.Load(f); err != nil { log.Fatalf("failed to load authentication file: %s", err.Error()) } s = httpd.New(httpAddr, store, credentialStore) } else { s = httpd.New(httpAddr, store, nil) } s.CertFile = x509Cert s.KeyFile = x509Key s.NoVerifySelect = noVerifySelect s.Expvar = expvar s.Pprof = pprofEnabled s.BuildInfo = map[string]interface{}{ "commit": commit, "branch": branch, "version": version, "build_time": buildtime, } if err := s.Start(); err != nil { log.Fatalf("failed to start HTTP server: %s", err.Error()) } terminate := make(chan os.Signal, 1) signal.Notify(terminate, os.Interrupt) <-terminate if err := store.Close(true); err != nil { log.Printf("failed to close store: %s", err.Error()) } log.Println("rqlite server stopped") }