This commit is contained in:
Xiang Li 2013-08-13 18:40:53 -07:00 committed by Brandon Philips
parent f8764df6ad
commit cb33641f5f
4 changed files with 87 additions and 81 deletions

View File

@ -14,7 +14,43 @@ import (
// Config // Config
//-------------------------------------- //--------------------------------------
func parseInfo(path string) *Info { // Get the server info from previous conf file
// or from the user
func getInfo(path string) *Info {
infoPath := filepath.Join(path, "info")
if force {
// Delete the old configuration if exist
logPath := filepath.Join(path, "log")
confPath := filepath.Join(path, "conf")
snapshotPath := filepath.Join(path, "snapshot")
os.Remove(infoPath)
os.Remove(logPath)
os.Remove(confPath)
os.RemoveAll(snapshotPath)
} else if info := readInfo(infoPath); info != nil {
infof("Found node configuration in '%s'. Ignoring flags", infoPath)
return info
}
// Read info from command line
info := &argInfo
// Write to file.
content, _ := json.MarshalIndent(info, "", " ")
content = []byte(string(content) + "\n")
if err := ioutil.WriteFile(infoPath, content, 0644); err != nil {
fatalf("Unable to write info to file: %v", err)
}
infof("Wrote node configuration to '%s'", infoPath)
return info
}
// readInfo reads from info file and decode to Info struct
func readInfo(path string) *Info {
file, err := os.Open(path) file, err := os.Open(path)
if err != nil { if err != nil {
@ -38,44 +74,6 @@ func parseInfo(path string) *Info {
return info return info
} }
// Get the server info from previous conf file
// or from the user
func getInfo(path string) *Info {
// Read in the server info if available.
infoPath := filepath.Join(path, "info")
// Delete the old configuration if exist
if force {
logPath := filepath.Join(path, "log")
confPath := filepath.Join(path, "conf")
snapshotPath := filepath.Join(path, "snapshot")
os.Remove(infoPath)
os.Remove(logPath)
os.Remove(confPath)
os.RemoveAll(snapshotPath)
}
info := parseInfo(infoPath)
if info != nil {
infof("Found node configuration in '%s'. Ignoring flags", infoPath)
return info
}
info = &argInfo
// Write to file.
content, _ := json.MarshalIndent(info, "", " ")
content = []byte(string(content) + "\n")
if err := ioutil.WriteFile(infoPath, content, 0644); err != nil {
fatalf("Unable to write info to file: %v", err)
}
infof("Wrote node configuration to '%s'", infoPath)
return info
}
func tlsConfigFromInfo(info TLSInfo) (t TLSConfig, ok bool) { func tlsConfigFromInfo(info TLSInfo) (t TLSConfig, ok bool) {
var keyFile, certFile, CAFile string var keyFile, certFile, CAFile string
var tlsCert tls.Certificate var tlsCert tls.Certificate

47
etcd.go
View File

@ -4,13 +4,11 @@ import (
"crypto/tls" "crypto/tls"
"flag" "flag"
"github.com/coreos/etcd/store" "github.com/coreos/etcd/store"
"github.com/coreos/etcd/web" "github.com/coreos/go-raft"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"os/signal"
"runtime/pprof"
"strings" "strings"
"time" "time"
) )
@ -142,27 +140,12 @@ func main() {
flag.Parse() flag.Parse()
if cpuprofile != "" { if cpuprofile != "" {
f, err := os.Create(cpuprofile) runCPUProfile()
if err != nil {
fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for sig := range c {
infof("captured %v, stopping profiler and exiting..", sig)
pprof.StopCPUProfile()
os.Exit(1)
}
}()
} }
if veryVerbose { if veryVerbose {
verbose = true verbose = true
raft.SetLogLevel(raft.Debug)
} }
if machines != "" { if machines != "" {
@ -175,6 +158,7 @@ func main() {
cluster = strings.Split(string(b), ",") cluster = strings.Split(string(b), ",")
} }
// Check TLS arguments
raftTLSConfig, ok := tlsConfigFromInfo(argInfo.RaftTLS) raftTLSConfig, ok := tlsConfigFromInfo(argInfo.RaftTLS)
if !ok { if !ok {
fatal("Please specify cert and key file or cert and key file and CAFile or none of the three") fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
@ -190,13 +174,11 @@ func main() {
fatal("ERROR: server name required. e.g. '-n=server_name'") fatal("ERROR: server name required. e.g. '-n=server_name'")
} }
// Check host name arguments
argInfo.RaftURL = sanitizeURL(argInfo.RaftURL, raftTLSConfig.Scheme) argInfo.RaftURL = sanitizeURL(argInfo.RaftURL, raftTLSConfig.Scheme)
argInfo.EtcdURL = sanitizeURL(argInfo.EtcdURL, etcdTLSConfig.Scheme) argInfo.EtcdURL = sanitizeURL(argInfo.EtcdURL, etcdTLSConfig.Scheme)
argInfo.WebURL = sanitizeURL(argInfo.WebURL, "http") argInfo.WebURL = sanitizeURL(argInfo.WebURL, "http")
// Setup commands.
registerCommands()
// Read server info from file or grab it from user. // Read server info from file or grab it from user.
if err := os.MkdirAll(dirPath, 0744); err != nil { if err := os.MkdirAll(dirPath, 0744); err != nil {
fatalf("Unable to create path: %s", err) fatalf("Unable to create path: %s", err)
@ -208,21 +190,16 @@ func main() {
etcdStore = store.CreateStore(maxSize) etcdStore = store.CreateStore(maxSize)
snapConf = newSnapshotConf() snapConf = newSnapshotConf()
startWebInterface()
startRaft(raftTLSConfig) startRaft(raftTLSConfig)
if argInfo.WebURL != "" { startEtcd(etcdTLSConfig)
// start web
argInfo.WebURL = sanitizeURL(argInfo.WebURL, "http")
go webHelper()
go web.Start(raftServer, argInfo.WebURL)
}
startEtcdTransport(*info, etcdTLSConfig.Scheme, etcdTLSConfig.Server)
} }
// Start to listen and response client command // Start to listen and response etcd client command
func startEtcdTransport(info Info, scheme string, tlsConf tls.Config) { func startEtcd(tlsConf TLSConfig) {
u, err := url.Parse(info.EtcdURL) u, err := url.Parse(info.EtcdURL)
if err != nil { if err != nil {
fatalf("invalid url '%s': %s", info.EtcdURL, err) fatalf("invalid url '%s': %s", info.EtcdURL, err)
@ -231,11 +208,11 @@ func startEtcdTransport(info Info, scheme string, tlsConf tls.Config) {
server := http.Server{ server := http.Server{
Handler: NewEtcdMuxer(), Handler: NewEtcdMuxer(),
TLSConfig: &tlsConf, TLSConfig: &tlsConf.Server,
Addr: u.Host, Addr: u.Host,
} }
if scheme == "http" { if tlsConf.Scheme == "http" {
fatal(server.ListenAndServe()) fatal(server.ListenAndServe())
} else { } else {
fatal(server.ListenAndServeTLS(info.EtcdTLS.CertFile, info.EtcdTLS.KeyFile)) fatal(server.ListenAndServeTLS(info.EtcdTLS.CertFile, info.EtcdTLS.KeyFile))

View File

@ -12,23 +12,21 @@ import (
"github.com/coreos/go-raft" "github.com/coreos/go-raft"
) )
var raftTransporter transporter
var raftServer *raft.Server var raftServer *raft.Server
// Start the raft server // Start the raft server
func startRaft(tlsConfig TLSConfig) { func startRaft(tlsConfig TLSConfig) {
if veryVerbose {
raft.SetLogLevel(raft.Debug)
}
var err error
raftName := info.Name raftName := info.Name
// Setup commands.
registerCommands()
// Create transporter for raft // Create transporter for raft
raftTransporter = newTransporter(tlsConfig.Scheme, tlsConfig.Client) raftTransporter := newTransporter(tlsConfig.Scheme, tlsConfig.Client)
// Create raft server // Create raft server
var err error
raftServer, err = raft.NewServer(raftName, dirPath, raftTransporter, etcdStore, nil) raftServer, err = raft.NewServer(raftName, dirPath, raftTransporter, etcdStore, nil)
if err != nil { if err != nil {

33
util.go
View File

@ -10,6 +10,8 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"os/signal"
"runtime/pprof"
"strconv" "strconv"
"time" "time"
) )
@ -48,6 +50,15 @@ func webHelper() {
} }
} }
// startWebInterface starts web interface if webURL is not empty
func startWebInterface() {
if argInfo.WebURL != "" {
// start web
go webHelper()
go web.Start(raftServer, argInfo.WebURL)
}
}
//-------------------------------------- //--------------------------------------
// HTTP Utilities // HTTP Utilities
//-------------------------------------- //--------------------------------------
@ -144,3 +155,25 @@ func fatal(v ...interface{}) {
logger.Println("FATAL " + fmt.Sprint(v...)) logger.Println("FATAL " + fmt.Sprint(v...))
os.Exit(1) os.Exit(1)
} }
//--------------------------------------
// CPU profile
//--------------------------------------
func runCPUProfile() {
f, err := os.Create(cpuprofile)
if err != nil {
fatal(err)
}
pprof.StartCPUProfile(f)
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for sig := range c {
infof("captured %v, stopping profiler and exiting..", sig)
pprof.StopCPUProfile()
os.Exit(1)
}
}()
}