|
@@ -21,6 +21,7 @@ import (
|
|
|
"os"
|
|
"os"
|
|
|
"strings"
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
+ "github.com/coreos/etcd/etcdserver"
|
|
|
"github.com/coreos/etcd/pkg/expect"
|
|
"github.com/coreos/etcd/pkg/expect"
|
|
|
"github.com/coreos/etcd/pkg/fileutil"
|
|
"github.com/coreos/etcd/pkg/fileutil"
|
|
|
)
|
|
)
|
|
@@ -122,7 +123,8 @@ type etcdProcess struct {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
type etcdProcessConfig struct {
|
|
type etcdProcessConfig struct {
|
|
|
- args []string
|
|
|
|
|
|
|
+ execPath string
|
|
|
|
|
+ args []string
|
|
|
|
|
|
|
|
dataDirPath string
|
|
dataDirPath string
|
|
|
keepDataDir bool
|
|
keepDataDir bool
|
|
@@ -137,12 +139,16 @@ type etcdProcessConfig struct {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
type etcdProcessClusterConfig struct {
|
|
type etcdProcessClusterConfig struct {
|
|
|
|
|
+ execPath string
|
|
|
dataDirPath string
|
|
dataDirPath string
|
|
|
keepDataDir bool
|
|
keepDataDir bool
|
|
|
|
|
|
|
|
- clusterSize int
|
|
|
|
|
- basePort int
|
|
|
|
|
- proxySize int
|
|
|
|
|
|
|
+ clusterSize int
|
|
|
|
|
+ basePort int
|
|
|
|
|
+ proxySize int
|
|
|
|
|
+
|
|
|
|
|
+ snapCount int // default is 10000
|
|
|
|
|
+
|
|
|
clientTLS clientConnType
|
|
clientTLS clientConnType
|
|
|
isPeerTLS bool
|
|
isPeerTLS bool
|
|
|
isPeerAutoTLS bool
|
|
isPeerAutoTLS bool
|
|
@@ -175,7 +181,7 @@ func newEtcdProcessCluster(cfg *etcdProcessClusterConfig) (*etcdProcessCluster,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func newEtcdProcess(cfg *etcdProcessConfig) (*etcdProcess, error) {
|
|
func newEtcdProcess(cfg *etcdProcessConfig) (*etcdProcess, error) {
|
|
|
- if !fileutil.Exist("../bin/etcd") {
|
|
|
|
|
|
|
+ if !fileutil.Exist(cfg.execPath) {
|
|
|
return nil, fmt.Errorf("could not find etcd binary")
|
|
return nil, fmt.Errorf("could not find etcd binary")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -185,7 +191,7 @@ func newEtcdProcess(cfg *etcdProcessConfig) (*etcdProcess, error) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- child, err := spawnCmd(append([]string{"../bin/etcd"}, cfg.args...))
|
|
|
|
|
|
|
+ child, err := spawnCmd(append([]string{cfg.execPath}, cfg.args...))
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
@@ -197,6 +203,13 @@ func (cfg *etcdProcessClusterConfig) etcdProcessConfigs() []*etcdProcessConfig {
|
|
|
cfg.basePort = etcdProcessBasePort
|
|
cfg.basePort = etcdProcessBasePort
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if cfg.execPath == "" {
|
|
|
|
|
+ cfg.execPath = "../bin/etcd"
|
|
|
|
|
+ }
|
|
|
|
|
+ if cfg.snapCount == 0 {
|
|
|
|
|
+ cfg.snapCount = etcdserver.DefaultSnapCount
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
clientScheme := "http"
|
|
clientScheme := "http"
|
|
|
if cfg.clientTLS == clientTLS {
|
|
if cfg.clientTLS == clientTLS {
|
|
|
clientScheme = "https"
|
|
clientScheme = "https"
|
|
@@ -244,6 +257,7 @@ func (cfg *etcdProcessClusterConfig) etcdProcessConfigs() []*etcdProcessConfig {
|
|
|
"--initial-advertise-peer-urls", purl.String(),
|
|
"--initial-advertise-peer-urls", purl.String(),
|
|
|
"--initial-cluster-token", cfg.initialToken,
|
|
"--initial-cluster-token", cfg.initialToken,
|
|
|
"--data-dir", dataDirPath,
|
|
"--data-dir", dataDirPath,
|
|
|
|
|
+ "--snapshot-count", fmt.Sprintf("%d", cfg.snapCount),
|
|
|
}
|
|
}
|
|
|
if cfg.forceNewCluster {
|
|
if cfg.forceNewCluster {
|
|
|
args = append(args, "--force-new-cluster")
|
|
args = append(args, "--force-new-cluster")
|
|
@@ -256,6 +270,7 @@ func (cfg *etcdProcessClusterConfig) etcdProcessConfigs() []*etcdProcessConfig {
|
|
|
|
|
|
|
|
args = append(args, cfg.tlsArgs()...)
|
|
args = append(args, cfg.tlsArgs()...)
|
|
|
etcdCfgs[i] = &etcdProcessConfig{
|
|
etcdCfgs[i] = &etcdProcessConfig{
|
|
|
|
|
+ execPath: cfg.execPath,
|
|
|
args: args,
|
|
args: args,
|
|
|
dataDirPath: dataDirPath,
|
|
dataDirPath: dataDirPath,
|
|
|
keepDataDir: cfg.keepDataDir,
|
|
keepDataDir: cfg.keepDataDir,
|
|
@@ -281,6 +296,7 @@ func (cfg *etcdProcessClusterConfig) etcdProcessConfigs() []*etcdProcessConfig {
|
|
|
}
|
|
}
|
|
|
args = append(args, cfg.tlsArgs()...)
|
|
args = append(args, cfg.tlsArgs()...)
|
|
|
etcdCfgs[cfg.clusterSize+i] = &etcdProcessConfig{
|
|
etcdCfgs[cfg.clusterSize+i] = &etcdProcessConfig{
|
|
|
|
|
+ execPath: cfg.execPath,
|
|
|
args: args,
|
|
args: args,
|
|
|
dataDirPath: dataDirPath,
|
|
dataDirPath: dataDirPath,
|
|
|
keepDataDir: cfg.keepDataDir,
|
|
keepDataDir: cfg.keepDataDir,
|
|
@@ -351,7 +367,7 @@ func (epc *etcdProcessCluster) Start() (err error) {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (epc *etcdProcessCluster) Restart() error {
|
|
|
|
|
|
|
+func (epc *etcdProcessCluster) RestartAll() error {
|
|
|
for i := range epc.procs {
|
|
for i := range epc.procs {
|
|
|
proc, err := newEtcdProcess(epc.procs[i].cfg)
|
|
proc, err := newEtcdProcess(epc.procs[i].cfg)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -363,7 +379,29 @@ func (epc *etcdProcessCluster) Restart() error {
|
|
|
return epc.Start()
|
|
return epc.Start()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (epc *etcdProcessCluster) Stop() (err error) {
|
|
|
|
|
|
|
+func (epr *etcdProcess) Restart() error {
|
|
|
|
|
+ proc, err := newEtcdProcess(epr.cfg)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ epr.Stop()
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ *epr = *proc
|
|
|
|
|
+
|
|
|
|
|
+ readyStr := "enabled capabilities for version"
|
|
|
|
|
+ if proc.cfg.isProxy {
|
|
|
|
|
+ readyStr = "httpproxy: endpoints found"
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if _, err = proc.proc.Expect(readyStr); err != nil {
|
|
|
|
|
+ epr.Stop()
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ close(proc.donec)
|
|
|
|
|
+
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (epc *etcdProcessCluster) StopAll() (err error) {
|
|
|
for _, p := range epc.procs {
|
|
for _, p := range epc.procs {
|
|
|
if p == nil {
|
|
if p == nil {
|
|
|
continue
|
|
continue
|
|
@@ -380,8 +418,21 @@ func (epc *etcdProcessCluster) Stop() (err error) {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (epr *etcdProcess) Stop() error {
|
|
|
|
|
+ if epr == nil {
|
|
|
|
|
+ return nil
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if err := epr.proc.Stop(); err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ <-epr.donec
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func (epc *etcdProcessCluster) Close() error {
|
|
func (epc *etcdProcessCluster) Close() error {
|
|
|
- err := epc.Stop()
|
|
|
|
|
|
|
+ err := epc.StopAll()
|
|
|
for _, p := range epc.procs {
|
|
for _, p := range epc.procs {
|
|
|
os.RemoveAll(p.cfg.dataDirPath)
|
|
os.RemoveAll(p.cfg.dataDirPath)
|
|
|
}
|
|
}
|