package etcdserver import ( "net/url" "strings" "time" "github.com/coreos/etcd/embed" "github.com/coreos/etcd/pkg/osutil" "github.com/coreos/etcd/pkg/types" "github.com/golang/glog" configapi "github.com/openshift/origin/pkg/cmd/server/api" ) const defaultName = "openshift.local" // RunEtcd starts an etcd server and runs it forever func RunEtcd(etcdServerConfig *configapi.EtcdConfig) { cfg := embed.NewConfig() cfg.Debug = true cfg.Name = defaultName cfg.Dir = etcdServerConfig.StorageDir clientTLS := configapi.UseTLS(etcdServerConfig.ServingInfo) if clientTLS { cfg.ClientTLSInfo.CAFile = etcdServerConfig.ServingInfo.ClientCA cfg.ClientTLSInfo.CertFile = etcdServerConfig.ServingInfo.ServerCert.CertFile cfg.ClientTLSInfo.KeyFile = etcdServerConfig.ServingInfo.ServerCert.KeyFile cfg.ClientTLSInfo.ClientCertAuth = len(cfg.ClientTLSInfo.CAFile) > 0 } u, err := types.NewURLs(addressToURLs(etcdServerConfig.ServingInfo.BindAddress, clientTLS)) if err != nil { glog.Fatalf("Unable to build etcd peer URLs: %v", err) } cfg.LCUrls = []url.URL(u) peerTLS := configapi.UseTLS(etcdServerConfig.PeerServingInfo) if peerTLS { cfg.PeerTLSInfo.CAFile = etcdServerConfig.PeerServingInfo.ClientCA cfg.PeerTLSInfo.CertFile = etcdServerConfig.PeerServingInfo.ServerCert.CertFile cfg.PeerTLSInfo.KeyFile = etcdServerConfig.PeerServingInfo.ServerCert.KeyFile cfg.PeerTLSInfo.ClientCertAuth = len(cfg.PeerTLSInfo.CAFile) > 0 } u, err = types.NewURLs(addressToURLs(etcdServerConfig.PeerServingInfo.BindAddress, peerTLS)) if err != nil { glog.Fatalf("Unable to build etcd peer URLs: %v", err) } cfg.LPUrls = []url.URL(u) u, err = types.NewURLs(addressToURLs(etcdServerConfig.Address, clientTLS)) if err != nil { glog.Fatalf("Unable to build etcd announce client URLs: %v", err) } cfg.ACUrls = []url.URL(u) u, err = types.NewURLs(addressToURLs(etcdServerConfig.PeerAddress, peerTLS)) if err != nil { glog.Fatalf("Unable to build etcd announce peer URLs: %v", err) } cfg.APUrls = []url.URL(u) cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name) osutil.HandleInterrupts() e, err := embed.StartEtcd(cfg) if err != nil { glog.Fatalf("Unable to start etcd: %v", err) } go func() { defer e.Close() select { case <-e.Server.ReadyNotify(): glog.Infof("Started etcd at %s", etcdServerConfig.Address) case <-time.After(60 * time.Second): glog.Warning("etcd took too long to start, stopped") e.Server.Stop() // trigger a shutdown } glog.Fatalf("etcd has returned an error: %v", <-e.Err()) }() } // addressToURLs turns a host:port comma delimited list into an array valid // URL strings with the appropriate prefix for the TLS mode. func addressToURLs(addr string, isTLS bool) []string { addrs := strings.Split(addr, ",") for i := range addrs { if isTLS { addrs[i] = "https://" + addrs[i] } else { addrs[i] = "http://" + addrs[i] } } return addrs }