func (etcd *ETCDClusterRunner) detectRunningEtcd(index int) bool {
	var client *etcdclient.Client

	if etcd.serverSSL == nil {
		client = etcdclient.NewClient([]string{})
	} else {
		var err error
		client, err = etcdstoreadapter.NewETCDTLSClient(
			[]string{etcd.clientURL(index)},
			etcd.serverSSL.CertFile,
			etcd.serverSSL.KeyFile,
			etcd.serverSSL.CAFile,
		)
		Expect(err).NotTo(HaveOccurred())
	}
	return client.SetCluster([]string{etcd.clientURL(index)})
}
func (etcd *ETCDClusterRunner) start(nuke bool) {
	etcd.mutex.RLock()
	running := etcd.running
	etcd.mutex.RUnlock()

	if running {
		return
	}

	etcd.mutex.Lock()
	defer etcd.mutex.Unlock()

	etcd.etcdProcesses = make([]ifrit.Process, etcd.numNodes)

	clusterURLs := make([]string, etcd.numNodes)
	for i := 0; i < etcd.numNodes; i++ {
		clusterURLs[i] = etcd.nodeName(i) + "=" + etcd.serverURL(i)
	}

	for i := 0; i < etcd.numNodes; i++ {
		if nuke {
			etcd.nukeArtifacts(i)
		}

		if etcd.detectRunningEtcd(i) {
			log.Fatalf("Detected an ETCD already running on %s", etcd.clientURL(i))
		}

		var args []string
		if etcd.serverSSL != nil {
			args = append(args,
				"--cert-file="+etcd.serverSSL.CertFile,
				"--key-file="+etcd.serverSSL.KeyFile,
			)
			if etcd.serverSSL.CAFile != "" {
				args = append(args, "--ca-file="+etcd.serverSSL.CAFile)
			}
		}

		os.MkdirAll(etcd.tmpPath(i), 0700)
		process := ginkgomon.Invoke(ginkgomon.New(ginkgomon.Config{
			Name:              "etcd_cluster",
			AnsiColorCode:     "33m",
			StartCheck:        "etcdserver: published",
			StartCheckTimeout: 10 * time.Second,
			Command: exec.Command(
				"etcd",
				append([]string{
					"--name", etcd.nodeName(i),
					"--data-dir", etcd.tmpPath(i),
					"--listen-client-urls", etcd.clientURL(i),
					"--listen-peer-urls", etcd.serverURL(i),
					"--initial-cluster", strings.Join(clusterURLs, ","),
					"--initial-advertise-peer-urls", etcd.serverURL(i),
					"--initial-cluster-state", "new",
					"--advertise-client-urls", etcd.clientURL(i),
				}, args...)...,
			),
		}))

		etcd.etcdProcesses[i] = process

		Eventually(func() bool {
			defer func() {
				// https://github.com/coreos/go-etcd/issues/114
				recover()
			}()

			return etcd.detectRunningEtcd(i)
		}, 10, 0.05).Should(BeTrue(), "Expected ETCD to be up and running")
	}

	var client *etcdclient.Client
	if etcd.serverSSL == nil {
		client = etcdclient.NewClient(etcd.NodeURLS())
	} else {
		var err error
		client, err = etcdstoreadapter.NewETCDTLSClient(
			etcd.NodeURLS(),
			etcd.serverSSL.CertFile,
			etcd.serverSSL.KeyFile,
			etcd.serverSSL.CAFile,
		)
		Expect(err).NotTo(HaveOccurred())
	}
	etcd.client = client

	etcd.running = true
}