mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-07 02:07:58 +00:00
Add vendor folder to git
This commit is contained in:
parent
66cf5eaafb
commit
183585f56f
6916 changed files with 2629581 additions and 1 deletions
317
vendor/github.com/coreos/etcd/etcdmain/config.go
generated
vendored
Normal file
317
vendor/github.com/coreos/etcd/etcdmain/config.go
generated
vendored
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Every change should be reflected on help.go as well.
|
||||
|
||||
package etcdmain
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/etcd/embed"
|
||||
"github.com/coreos/etcd/pkg/flags"
|
||||
"github.com/coreos/etcd/version"
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
||||
var (
|
||||
proxyFlagOff = "off"
|
||||
proxyFlagReadonly = "readonly"
|
||||
proxyFlagOn = "on"
|
||||
|
||||
fallbackFlagExit = "exit"
|
||||
fallbackFlagProxy = "proxy"
|
||||
|
||||
ignored = []string{
|
||||
"cluster-active-size",
|
||||
"cluster-remove-delay",
|
||||
"cluster-sync-interval",
|
||||
"config",
|
||||
"force",
|
||||
"max-result-buffer",
|
||||
"max-retry-attempts",
|
||||
"peer-heartbeat-interval",
|
||||
"peer-election-timeout",
|
||||
"retry-interval",
|
||||
"snapshot",
|
||||
"v",
|
||||
"vv",
|
||||
}
|
||||
)
|
||||
|
||||
type configProxy struct {
|
||||
ProxyFailureWaitMs uint `json:"proxy-failure-wait"`
|
||||
ProxyRefreshIntervalMs uint `json:"proxy-refresh-interval"`
|
||||
ProxyDialTimeoutMs uint `json:"proxy-dial-timeout"`
|
||||
ProxyWriteTimeoutMs uint `json:"proxy-write-timeout"`
|
||||
ProxyReadTimeoutMs uint `json:"proxy-read-timeout"`
|
||||
Fallback string
|
||||
Proxy string
|
||||
ProxyJSON string `json:"proxy"`
|
||||
FallbackJSON string `json:"discovery-fallback"`
|
||||
}
|
||||
|
||||
// config holds the config for a command line invocation of etcd
|
||||
type config struct {
|
||||
embed.Config
|
||||
configProxy
|
||||
configFlags
|
||||
configFile string
|
||||
printVersion bool
|
||||
ignored []string
|
||||
logOutput string
|
||||
}
|
||||
|
||||
// configFlags has the set of flags used for command line parsing a Config
|
||||
type configFlags struct {
|
||||
*flag.FlagSet
|
||||
clusterState *flags.StringsFlag
|
||||
fallback *flags.StringsFlag
|
||||
proxy *flags.StringsFlag
|
||||
}
|
||||
|
||||
func newConfig() *config {
|
||||
cfg := &config{
|
||||
Config: *embed.NewConfig(),
|
||||
configProxy: configProxy{
|
||||
Proxy: proxyFlagOff,
|
||||
ProxyFailureWaitMs: 5000,
|
||||
ProxyRefreshIntervalMs: 30000,
|
||||
ProxyDialTimeoutMs: 1000,
|
||||
ProxyWriteTimeoutMs: 5000,
|
||||
},
|
||||
ignored: ignored,
|
||||
}
|
||||
cfg.configFlags = configFlags{
|
||||
FlagSet: flag.NewFlagSet("etcd", flag.ContinueOnError),
|
||||
clusterState: flags.NewStringsFlag(
|
||||
embed.ClusterStateFlagNew,
|
||||
embed.ClusterStateFlagExisting,
|
||||
),
|
||||
fallback: flags.NewStringsFlag(
|
||||
fallbackFlagExit,
|
||||
fallbackFlagProxy,
|
||||
),
|
||||
proxy: flags.NewStringsFlag(
|
||||
proxyFlagOff,
|
||||
proxyFlagReadonly,
|
||||
proxyFlagOn,
|
||||
),
|
||||
}
|
||||
|
||||
fs := cfg.FlagSet
|
||||
fs.Usage = func() {
|
||||
fmt.Fprintln(os.Stderr, usageline)
|
||||
}
|
||||
|
||||
fs.StringVar(&cfg.configFile, "config-file", "", "Path to the server configuration file")
|
||||
|
||||
// member
|
||||
fs.Var(cfg.CorsInfo, "cors", "Comma-separated white list of origins for CORS (cross-origin resource sharing).")
|
||||
fs.StringVar(&cfg.Dir, "data-dir", cfg.Dir, "Path to the data directory.")
|
||||
fs.StringVar(&cfg.WalDir, "wal-dir", cfg.WalDir, "Path to the dedicated wal directory.")
|
||||
fs.Var(flags.NewURLsValue(embed.DefaultListenPeerURLs), "listen-peer-urls", "List of URLs to listen on for peer traffic.")
|
||||
fs.Var(flags.NewURLsValue(embed.DefaultListenClientURLs), "listen-client-urls", "List of URLs to listen on for client traffic.")
|
||||
fs.UintVar(&cfg.MaxSnapFiles, "max-snapshots", cfg.MaxSnapFiles, "Maximum number of snapshot files to retain (0 is unlimited).")
|
||||
fs.UintVar(&cfg.MaxWalFiles, "max-wals", cfg.MaxWalFiles, "Maximum number of wal files to retain (0 is unlimited).")
|
||||
fs.StringVar(&cfg.Name, "name", cfg.Name, "Human-readable name for this member.")
|
||||
fs.Uint64Var(&cfg.SnapCount, "snapshot-count", cfg.SnapCount, "Number of committed transactions to trigger a snapshot to disk.")
|
||||
fs.UintVar(&cfg.TickMs, "heartbeat-interval", cfg.TickMs, "Time (in milliseconds) of a heartbeat interval.")
|
||||
fs.UintVar(&cfg.ElectionMs, "election-timeout", cfg.ElectionMs, "Time (in milliseconds) for an election to timeout.")
|
||||
fs.Int64Var(&cfg.QuotaBackendBytes, "quota-backend-bytes", cfg.QuotaBackendBytes, "Raise alarms when backend size exceeds the given quota. 0 means use the default quota.")
|
||||
|
||||
// clustering
|
||||
fs.Var(flags.NewURLsValue(embed.DefaultInitialAdvertisePeerURLs), "initial-advertise-peer-urls", "List of this member's peer URLs to advertise to the rest of the cluster.")
|
||||
fs.Var(flags.NewURLsValue(embed.DefaultAdvertiseClientURLs), "advertise-client-urls", "List of this member's client URLs to advertise to the public.")
|
||||
fs.StringVar(&cfg.Durl, "discovery", cfg.Durl, "Discovery URL used to bootstrap the cluster.")
|
||||
fs.Var(cfg.fallback, "discovery-fallback", fmt.Sprintf("Valid values include %s", strings.Join(cfg.fallback.Values, ", ")))
|
||||
if err := cfg.fallback.Set(fallbackFlagProxy); err != nil {
|
||||
// Should never happen.
|
||||
plog.Panicf("unexpected error setting up discovery-fallback flag: %v", err)
|
||||
}
|
||||
fs.StringVar(&cfg.Dproxy, "discovery-proxy", cfg.Dproxy, "HTTP proxy to use for traffic to discovery service.")
|
||||
fs.StringVar(&cfg.DNSCluster, "discovery-srv", cfg.DNSCluster, "DNS domain used to bootstrap initial cluster.")
|
||||
fs.StringVar(&cfg.InitialCluster, "initial-cluster", cfg.InitialCluster, "Initial cluster configuration for bootstrapping.")
|
||||
fs.StringVar(&cfg.InitialClusterToken, "initial-cluster-token", cfg.InitialClusterToken, "Initial cluster token for the etcd cluster during bootstrap.")
|
||||
fs.Var(cfg.clusterState, "initial-cluster-state", "Initial cluster state ('new' or 'existing').")
|
||||
if err := cfg.clusterState.Set(embed.ClusterStateFlagNew); err != nil {
|
||||
// Should never happen.
|
||||
plog.Panicf("unexpected error setting up clusterStateFlag: %v", err)
|
||||
}
|
||||
fs.BoolVar(&cfg.StrictReconfigCheck, "strict-reconfig-check", cfg.StrictReconfigCheck, "Reject reconfiguration requests that would cause quorum loss.")
|
||||
|
||||
// proxy
|
||||
fs.Var(cfg.proxy, "proxy", fmt.Sprintf("Valid values include %s", strings.Join(cfg.proxy.Values, ", ")))
|
||||
if err := cfg.proxy.Set(proxyFlagOff); err != nil {
|
||||
// Should never happen.
|
||||
plog.Panicf("unexpected error setting up proxyFlag: %v", err)
|
||||
}
|
||||
fs.UintVar(&cfg.ProxyFailureWaitMs, "proxy-failure-wait", cfg.ProxyFailureWaitMs, "Time (in milliseconds) an endpoint will be held in a failed state.")
|
||||
fs.UintVar(&cfg.ProxyRefreshIntervalMs, "proxy-refresh-interval", cfg.ProxyRefreshIntervalMs, "Time (in milliseconds) of the endpoints refresh interval.")
|
||||
fs.UintVar(&cfg.ProxyDialTimeoutMs, "proxy-dial-timeout", cfg.ProxyDialTimeoutMs, "Time (in milliseconds) for a dial to timeout.")
|
||||
fs.UintVar(&cfg.ProxyWriteTimeoutMs, "proxy-write-timeout", cfg.ProxyWriteTimeoutMs, "Time (in milliseconds) for a write to timeout.")
|
||||
fs.UintVar(&cfg.ProxyReadTimeoutMs, "proxy-read-timeout", cfg.ProxyReadTimeoutMs, "Time (in milliseconds) for a read to timeout.")
|
||||
|
||||
// security
|
||||
fs.StringVar(&cfg.ClientTLSInfo.CAFile, "ca-file", "", "DEPRECATED: Path to the client server TLS CA file.")
|
||||
fs.StringVar(&cfg.ClientTLSInfo.CertFile, "cert-file", "", "Path to the client server TLS cert file.")
|
||||
fs.StringVar(&cfg.ClientTLSInfo.KeyFile, "key-file", "", "Path to the client server TLS key file.")
|
||||
fs.BoolVar(&cfg.ClientTLSInfo.ClientCertAuth, "client-cert-auth", false, "Enable client cert authentication.")
|
||||
fs.StringVar(&cfg.ClientTLSInfo.TrustedCAFile, "trusted-ca-file", "", "Path to the client server TLS trusted CA key file.")
|
||||
fs.BoolVar(&cfg.ClientAutoTLS, "auto-tls", false, "Client TLS using generated certificates")
|
||||
fs.StringVar(&cfg.PeerTLSInfo.CAFile, "peer-ca-file", "", "DEPRECATED: Path to the peer server TLS CA file.")
|
||||
fs.StringVar(&cfg.PeerTLSInfo.CertFile, "peer-cert-file", "", "Path to the peer server TLS cert file.")
|
||||
fs.StringVar(&cfg.PeerTLSInfo.KeyFile, "peer-key-file", "", "Path to the peer server TLS key file.")
|
||||
fs.BoolVar(&cfg.PeerTLSInfo.ClientCertAuth, "peer-client-cert-auth", false, "Enable peer client cert authentication.")
|
||||
fs.StringVar(&cfg.PeerTLSInfo.TrustedCAFile, "peer-trusted-ca-file", "", "Path to the peer server TLS trusted CA file.")
|
||||
fs.BoolVar(&cfg.PeerAutoTLS, "peer-auto-tls", false, "Peer TLS using generated certificates")
|
||||
|
||||
// logging
|
||||
fs.BoolVar(&cfg.Debug, "debug", false, "Enable debug-level logging for etcd.")
|
||||
fs.StringVar(&cfg.LogPkgLevels, "log-package-levels", "", "Specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG').")
|
||||
fs.StringVar(&cfg.logOutput, "log-output", "default", "Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.")
|
||||
|
||||
// unsafe
|
||||
fs.BoolVar(&cfg.ForceNewCluster, "force-new-cluster", false, "Force to create a new one member cluster.")
|
||||
|
||||
// version
|
||||
fs.BoolVar(&cfg.printVersion, "version", false, "Print the version and exit.")
|
||||
|
||||
fs.IntVar(&cfg.AutoCompactionRetention, "auto-compaction-retention", 0, "Auto compaction retention for mvcc key value store in hour. 0 means disable auto compaction.")
|
||||
|
||||
// pprof profiler via HTTP
|
||||
fs.BoolVar(&cfg.EnablePprof, "enable-pprof", false, "Enable runtime profiling data via HTTP server. Address is at client URL + \"/debug/pprof/\"")
|
||||
|
||||
// additional metrics
|
||||
fs.StringVar(&cfg.Metrics, "metrics", cfg.Metrics, "Set level of detail for exported metrics, specify 'extensive' to include histogram metrics")
|
||||
|
||||
// ignored
|
||||
for _, f := range cfg.ignored {
|
||||
fs.Var(&flags.IgnoredFlag{Name: f}, f, "")
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (cfg *config) parse(arguments []string) error {
|
||||
perr := cfg.FlagSet.Parse(arguments)
|
||||
switch perr {
|
||||
case nil:
|
||||
case flag.ErrHelp:
|
||||
fmt.Println(flagsline)
|
||||
os.Exit(0)
|
||||
default:
|
||||
os.Exit(2)
|
||||
}
|
||||
if len(cfg.FlagSet.Args()) != 0 {
|
||||
return fmt.Errorf("'%s' is not a valid flag", cfg.FlagSet.Arg(0))
|
||||
}
|
||||
|
||||
if cfg.printVersion {
|
||||
fmt.Printf("etcd Version: %s\n", version.Version)
|
||||
fmt.Printf("Git SHA: %s\n", version.GitSHA)
|
||||
fmt.Printf("Go Version: %s\n", runtime.Version())
|
||||
fmt.Printf("Go OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
var err error
|
||||
if cfg.configFile != "" {
|
||||
plog.Infof("Loading server configuration from %q", cfg.configFile)
|
||||
err = cfg.configFromFile(cfg.configFile)
|
||||
} else {
|
||||
err = cfg.configFromCmdLine()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (cfg *config) configFromCmdLine() error {
|
||||
err := flags.SetFlagsFromEnv("ETCD", cfg.FlagSet)
|
||||
if err != nil {
|
||||
plog.Fatalf("%v", err)
|
||||
}
|
||||
|
||||
cfg.LPUrls = flags.URLsFromFlag(cfg.FlagSet, "listen-peer-urls")
|
||||
cfg.APUrls = flags.URLsFromFlag(cfg.FlagSet, "initial-advertise-peer-urls")
|
||||
cfg.LCUrls = flags.URLsFromFlag(cfg.FlagSet, "listen-client-urls")
|
||||
cfg.ACUrls = flags.URLsFromFlag(cfg.FlagSet, "advertise-client-urls")
|
||||
cfg.ClusterState = cfg.clusterState.String()
|
||||
cfg.Fallback = cfg.fallback.String()
|
||||
cfg.Proxy = cfg.proxy.String()
|
||||
|
||||
// disable default advertise-client-urls if lcurls is set
|
||||
missingAC := flags.IsSet(cfg.FlagSet, "listen-client-urls") && !flags.IsSet(cfg.FlagSet, "advertise-client-urls")
|
||||
if !cfg.mayBeProxy() && missingAC {
|
||||
cfg.ACUrls = nil
|
||||
}
|
||||
|
||||
// disable default initial-cluster if discovery is set
|
||||
if (cfg.Durl != "" || cfg.DNSCluster != "") && !flags.IsSet(cfg.FlagSet, "initial-cluster") {
|
||||
cfg.InitialCluster = ""
|
||||
}
|
||||
|
||||
return cfg.validate()
|
||||
}
|
||||
|
||||
func (cfg *config) configFromFile(path string) error {
|
||||
eCfg, err := embed.ConfigFromFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Config = *eCfg
|
||||
|
||||
// load extra config information
|
||||
b, rerr := ioutil.ReadFile(path)
|
||||
if rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
if yerr := yaml.Unmarshal(b, &cfg.configProxy); yerr != nil {
|
||||
return yerr
|
||||
}
|
||||
if cfg.FallbackJSON != "" {
|
||||
if err := cfg.fallback.Set(cfg.FallbackJSON); err != nil {
|
||||
plog.Panicf("unexpected error setting up discovery-fallback flag: %v", err)
|
||||
}
|
||||
cfg.Fallback = cfg.fallback.String()
|
||||
}
|
||||
if cfg.ProxyJSON != "" {
|
||||
if err := cfg.proxy.Set(cfg.ProxyJSON); err != nil {
|
||||
plog.Panicf("unexpected error setting up proxyFlag: %v", err)
|
||||
}
|
||||
cfg.Proxy = cfg.proxy.String()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cfg *config) mayBeProxy() bool {
|
||||
mayFallbackToProxy := cfg.Durl != "" && cfg.Fallback == fallbackFlagProxy
|
||||
return cfg.Proxy != proxyFlagOff || mayFallbackToProxy
|
||||
}
|
||||
|
||||
func (cfg *config) validate() error {
|
||||
err := cfg.Config.Validate()
|
||||
// TODO(yichengq): check this for joining through discovery service case
|
||||
if err == embed.ErrUnsetAdvertiseClientURLsFlag && cfg.mayBeProxy() {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (cfg config) isProxy() bool { return cfg.proxy.String() != proxyFlagOff }
|
||||
func (cfg config) isReadonlyProxy() bool { return cfg.proxy.String() == proxyFlagReadonly }
|
||||
func (cfg config) shouldFallbackToProxy() bool { return cfg.fallback.String() == fallbackFlagProxy }
|
||||
529
vendor/github.com/coreos/etcd/etcdmain/config_test.go
generated
vendored
Normal file
529
vendor/github.com/coreos/etcd/etcdmain/config_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,529 @@
|
|||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package etcdmain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/etcd/embed"
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
||||
func TestConfigParsingMemberFlags(t *testing.T) {
|
||||
args := []string{
|
||||
"-data-dir=testdir",
|
||||
"-name=testname",
|
||||
"-max-wals=10",
|
||||
"-max-snapshots=10",
|
||||
"-snapshot-count=10",
|
||||
"-listen-peer-urls=http://localhost:8000,https://localhost:8001",
|
||||
"-listen-client-urls=http://localhost:7000,https://localhost:7001",
|
||||
// it should be set if -listen-client-urls is set
|
||||
"-advertise-client-urls=http://localhost:7000,https://localhost:7001",
|
||||
}
|
||||
|
||||
cfg := newConfig()
|
||||
err := cfg.parse(args)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
validateMemberFlags(t, cfg)
|
||||
}
|
||||
|
||||
func TestConfigFileMemberFields(t *testing.T) {
|
||||
yc := struct {
|
||||
Dir string `json:"data-dir"`
|
||||
MaxSnapFiles uint `json:"max-snapshots"`
|
||||
MaxWalFiles uint `json:"max-wals"`
|
||||
Name string `json:"name"`
|
||||
SnapCount uint64 `json:"snapshot-count"`
|
||||
LPUrls string `json:"listen-peer-urls"`
|
||||
LCUrls string `json:"listen-client-urls"`
|
||||
AcurlsCfgFile string `json:"advertise-client-urls"`
|
||||
}{
|
||||
"testdir",
|
||||
10,
|
||||
10,
|
||||
"testname",
|
||||
10,
|
||||
"http://localhost:8000,https://localhost:8001",
|
||||
"http://localhost:7000,https://localhost:7001",
|
||||
"http://localhost:7000,https://localhost:7001",
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(&yc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tmpfile := mustCreateCfgFile(t, b)
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
args := []string{
|
||||
fmt.Sprintf("--config-file=%s", tmpfile.Name()),
|
||||
}
|
||||
|
||||
cfg := newConfig()
|
||||
if err = cfg.parse(args); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
validateMemberFlags(t, cfg)
|
||||
}
|
||||
|
||||
func TestConfigParsingClusteringFlags(t *testing.T) {
|
||||
args := []string{
|
||||
"-initial-cluster=0=http://localhost:8000",
|
||||
"-initial-cluster-state=existing",
|
||||
"-initial-cluster-token=etcdtest",
|
||||
"-initial-advertise-peer-urls=http://localhost:8000,https://localhost:8001",
|
||||
"-advertise-client-urls=http://localhost:7000,https://localhost:7001",
|
||||
"-discovery-fallback=exit",
|
||||
}
|
||||
|
||||
cfg := newConfig()
|
||||
if err := cfg.parse(args); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
validateClusteringFlags(t, cfg)
|
||||
}
|
||||
|
||||
func TestConfigFileClusteringFields(t *testing.T) {
|
||||
yc := struct {
|
||||
InitialCluster string `json:"initial-cluster"`
|
||||
ClusterState string `json:"initial-cluster-state"`
|
||||
InitialClusterToken string `json:"initial-cluster-token"`
|
||||
Apurls string `json:"initial-advertise-peer-urls"`
|
||||
Acurls string `json:"advertise-client-urls"`
|
||||
Fallback string `json:"discovery-fallback"`
|
||||
}{
|
||||
"0=http://localhost:8000",
|
||||
"existing",
|
||||
"etcdtest",
|
||||
"http://localhost:8000,https://localhost:8001",
|
||||
"http://localhost:7000,https://localhost:7001",
|
||||
"exit",
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(&yc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tmpfile := mustCreateCfgFile(t, b)
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
args := []string{
|
||||
fmt.Sprintf("--config-file=%s", tmpfile.Name()),
|
||||
}
|
||||
cfg := newConfig()
|
||||
err = cfg.parse(args)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
validateClusteringFlags(t, cfg)
|
||||
}
|
||||
|
||||
func TestConfigParsingOtherFlags(t *testing.T) {
|
||||
args := []string{"-proxy=readonly"}
|
||||
|
||||
cfg := newConfig()
|
||||
err := cfg.parse(args)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
validateOtherFlags(t, cfg)
|
||||
}
|
||||
|
||||
func TestConfigFileOtherFields(t *testing.T) {
|
||||
yc := struct {
|
||||
ProxyCfgFile string `json:"proxy"`
|
||||
}{
|
||||
"readonly",
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(&yc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tmpfile := mustCreateCfgFile(t, b)
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
args := []string{
|
||||
fmt.Sprintf("--config-file=%s", tmpfile.Name()),
|
||||
}
|
||||
|
||||
cfg := newConfig()
|
||||
err = cfg.parse(args)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
validateOtherFlags(t, cfg)
|
||||
}
|
||||
|
||||
func TestConfigParsingConflictClusteringFlags(t *testing.T) {
|
||||
conflictArgs := [][]string{
|
||||
{
|
||||
"-initial-cluster=0=localhost:8000",
|
||||
"-discovery=http://example.com/abc",
|
||||
},
|
||||
{
|
||||
"-discovery-srv=example.com",
|
||||
"-discovery=http://example.com/abc",
|
||||
},
|
||||
{
|
||||
"-initial-cluster=0=localhost:8000",
|
||||
"-discovery-srv=example.com",
|
||||
},
|
||||
{
|
||||
"-initial-cluster=0=localhost:8000",
|
||||
"-discovery=http://example.com/abc",
|
||||
"-discovery-srv=example.com",
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range conflictArgs {
|
||||
cfg := newConfig()
|
||||
if err := cfg.parse(tt); err != embed.ErrConflictBootstrapFlags {
|
||||
t.Errorf("%d: err = %v, want %v", i, err, embed.ErrConflictBootstrapFlags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileConflictClusteringFlags(t *testing.T) {
|
||||
tests := []struct {
|
||||
InitialCluster string `json:"initial-cluster"`
|
||||
DNSCluster string `json:"discovery-srv"`
|
||||
Durl string `json:"discovery"`
|
||||
}{
|
||||
{
|
||||
InitialCluster: "0=localhost:8000",
|
||||
Durl: "http://example.com/abc",
|
||||
},
|
||||
{
|
||||
DNSCluster: "example.com",
|
||||
Durl: "http://example.com/abc",
|
||||
},
|
||||
{
|
||||
InitialCluster: "0=localhost:8000",
|
||||
DNSCluster: "example.com",
|
||||
},
|
||||
{
|
||||
InitialCluster: "0=localhost:8000",
|
||||
Durl: "http://example.com/abc",
|
||||
DNSCluster: "example.com",
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
b, err := yaml.Marshal(&tt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tmpfile := mustCreateCfgFile(t, b)
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
args := []string{
|
||||
fmt.Sprintf("--config-file=%s", tmpfile.Name()),
|
||||
}
|
||||
|
||||
cfg := newConfig()
|
||||
if err := cfg.parse(args); err != embed.ErrConflictBootstrapFlags {
|
||||
t.Errorf("%d: err = %v, want %v", i, err, embed.ErrConflictBootstrapFlags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigParsingMissedAdvertiseClientURLsFlag(t *testing.T) {
|
||||
tests := []struct {
|
||||
args []string
|
||||
werr error
|
||||
}{
|
||||
{
|
||||
[]string{
|
||||
"-initial-cluster=infra1=http://127.0.0.1:2380",
|
||||
"-listen-client-urls=http://127.0.0.1:2379",
|
||||
},
|
||||
embed.ErrUnsetAdvertiseClientURLsFlag,
|
||||
},
|
||||
{
|
||||
[]string{
|
||||
"-discovery-srv=example.com",
|
||||
"-listen-client-urls=http://127.0.0.1:2379",
|
||||
},
|
||||
embed.ErrUnsetAdvertiseClientURLsFlag,
|
||||
},
|
||||
{
|
||||
[]string{
|
||||
"-discovery=http://example.com/abc",
|
||||
"-discovery-fallback=exit",
|
||||
"-listen-client-urls=http://127.0.0.1:2379",
|
||||
},
|
||||
embed.ErrUnsetAdvertiseClientURLsFlag,
|
||||
},
|
||||
{
|
||||
[]string{
|
||||
"-listen-client-urls=http://127.0.0.1:2379",
|
||||
},
|
||||
embed.ErrUnsetAdvertiseClientURLsFlag,
|
||||
},
|
||||
{
|
||||
[]string{
|
||||
"-discovery=http://example.com/abc",
|
||||
"-listen-client-urls=http://127.0.0.1:2379",
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
[]string{
|
||||
"-proxy=on",
|
||||
"-listen-client-urls=http://127.0.0.1:2379",
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
[]string{
|
||||
"-proxy=readonly",
|
||||
"-listen-client-urls=http://127.0.0.1:2379",
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
cfg := newConfig()
|
||||
if err := cfg.parse(tt.args); err != tt.werr {
|
||||
t.Errorf("%d: err = %v, want %v", i, err, tt.werr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigIsNewCluster(t *testing.T) {
|
||||
tests := []struct {
|
||||
state string
|
||||
wIsNew bool
|
||||
}{
|
||||
{embed.ClusterStateFlagExisting, false},
|
||||
{embed.ClusterStateFlagNew, true},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
cfg := newConfig()
|
||||
args := []string{"--initial-cluster-state", tests[i].state}
|
||||
if err := cfg.parse(args); err != nil {
|
||||
t.Fatalf("#%d: unexpected clusterState.Set error: %v", i, err)
|
||||
}
|
||||
if g := cfg.IsNewCluster(); g != tt.wIsNew {
|
||||
t.Errorf("#%d: isNewCluster = %v, want %v", i, g, tt.wIsNew)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigIsProxy(t *testing.T) {
|
||||
tests := []struct {
|
||||
proxy string
|
||||
wIsProxy bool
|
||||
}{
|
||||
{proxyFlagOff, false},
|
||||
{proxyFlagReadonly, true},
|
||||
{proxyFlagOn, true},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
cfg := newConfig()
|
||||
if err := cfg.proxy.Set(tt.proxy); err != nil {
|
||||
t.Fatalf("#%d: unexpected proxy.Set error: %v", i, err)
|
||||
}
|
||||
if g := cfg.isProxy(); g != tt.wIsProxy {
|
||||
t.Errorf("#%d: isProxy = %v, want %v", i, g, tt.wIsProxy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigIsReadonlyProxy(t *testing.T) {
|
||||
tests := []struct {
|
||||
proxy string
|
||||
wIsReadonly bool
|
||||
}{
|
||||
{proxyFlagOff, false},
|
||||
{proxyFlagReadonly, true},
|
||||
{proxyFlagOn, false},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
cfg := newConfig()
|
||||
if err := cfg.proxy.Set(tt.proxy); err != nil {
|
||||
t.Fatalf("#%d: unexpected proxy.Set error: %v", i, err)
|
||||
}
|
||||
if g := cfg.isReadonlyProxy(); g != tt.wIsReadonly {
|
||||
t.Errorf("#%d: isReadonlyProxy = %v, want %v", i, g, tt.wIsReadonly)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigShouldFallbackToProxy(t *testing.T) {
|
||||
tests := []struct {
|
||||
fallback string
|
||||
wFallback bool
|
||||
}{
|
||||
{fallbackFlagProxy, true},
|
||||
{fallbackFlagExit, false},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
cfg := newConfig()
|
||||
if err := cfg.fallback.Set(tt.fallback); err != nil {
|
||||
t.Fatalf("#%d: unexpected fallback.Set error: %v", i, err)
|
||||
}
|
||||
if g := cfg.shouldFallbackToProxy(); g != tt.wFallback {
|
||||
t.Errorf("#%d: shouldFallbackToProxy = %v, want %v", i, g, tt.wFallback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigFileElectionTimeout(t *testing.T) {
|
||||
tests := []struct {
|
||||
TickMs uint `json:"heartbeat-interval"`
|
||||
ElectionMs uint `json:"election-timeout"`
|
||||
errStr string
|
||||
}{
|
||||
{
|
||||
ElectionMs: 1000,
|
||||
TickMs: 800,
|
||||
errStr: "should be at least as 5 times as",
|
||||
},
|
||||
{
|
||||
ElectionMs: 60000,
|
||||
errStr: "is too long, and should be set less than",
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
b, err := yaml.Marshal(&tt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tmpfile := mustCreateCfgFile(t, b)
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
args := []string{
|
||||
fmt.Sprintf("--config-file=%s", tmpfile.Name()),
|
||||
}
|
||||
|
||||
cfg := newConfig()
|
||||
if err := cfg.parse(args); err == nil || !strings.Contains(err.Error(), tt.errStr) {
|
||||
t.Errorf("%d: Wrong err = %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mustCreateCfgFile(t *testing.T, b []byte) *os.File {
|
||||
tmpfile, err := ioutil.TempFile("", "servercfg")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = tmpfile.Write(b)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = tmpfile.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return tmpfile
|
||||
}
|
||||
|
||||
func validateMemberFlags(t *testing.T, cfg *config) {
|
||||
wcfg := &embed.Config{
|
||||
Dir: "testdir",
|
||||
LPUrls: []url.URL{{Scheme: "http", Host: "localhost:8000"}, {Scheme: "https", Host: "localhost:8001"}},
|
||||
LCUrls: []url.URL{{Scheme: "http", Host: "localhost:7000"}, {Scheme: "https", Host: "localhost:7001"}},
|
||||
MaxSnapFiles: 10,
|
||||
MaxWalFiles: 10,
|
||||
Name: "testname",
|
||||
SnapCount: 10,
|
||||
}
|
||||
|
||||
if cfg.Dir != wcfg.Dir {
|
||||
t.Errorf("dir = %v, want %v", cfg.Dir, wcfg.Dir)
|
||||
}
|
||||
if cfg.MaxSnapFiles != wcfg.MaxSnapFiles {
|
||||
t.Errorf("maxsnap = %v, want %v", cfg.MaxSnapFiles, wcfg.MaxSnapFiles)
|
||||
}
|
||||
if cfg.MaxWalFiles != wcfg.MaxWalFiles {
|
||||
t.Errorf("maxwal = %v, want %v", cfg.MaxWalFiles, wcfg.MaxWalFiles)
|
||||
}
|
||||
if cfg.Name != wcfg.Name {
|
||||
t.Errorf("name = %v, want %v", cfg.Name, wcfg.Name)
|
||||
}
|
||||
if cfg.SnapCount != wcfg.SnapCount {
|
||||
t.Errorf("snapcount = %v, want %v", cfg.SnapCount, wcfg.SnapCount)
|
||||
}
|
||||
if !reflect.DeepEqual(cfg.LPUrls, wcfg.LPUrls) {
|
||||
t.Errorf("listen-peer-urls = %v, want %v", cfg.LPUrls, wcfg.LPUrls)
|
||||
}
|
||||
if !reflect.DeepEqual(cfg.LCUrls, wcfg.LCUrls) {
|
||||
t.Errorf("listen-client-urls = %v, want %v", cfg.LCUrls, wcfg.LCUrls)
|
||||
}
|
||||
}
|
||||
|
||||
func validateClusteringFlags(t *testing.T, cfg *config) {
|
||||
wcfg := newConfig()
|
||||
wcfg.APUrls = []url.URL{{Scheme: "http", Host: "localhost:8000"}, {Scheme: "https", Host: "localhost:8001"}}
|
||||
wcfg.ACUrls = []url.URL{{Scheme: "http", Host: "localhost:7000"}, {Scheme: "https", Host: "localhost:7001"}}
|
||||
wcfg.ClusterState = embed.ClusterStateFlagExisting
|
||||
wcfg.fallback.Set(fallbackFlagExit)
|
||||
wcfg.InitialCluster = "0=http://localhost:8000"
|
||||
wcfg.InitialClusterToken = "etcdtest"
|
||||
|
||||
if cfg.ClusterState != wcfg.ClusterState {
|
||||
t.Errorf("clusterState = %v, want %v", cfg.ClusterState, wcfg.ClusterState)
|
||||
}
|
||||
if cfg.fallback.String() != wcfg.fallback.String() {
|
||||
t.Errorf("fallback = %v, want %v", cfg.fallback, wcfg.fallback)
|
||||
}
|
||||
if cfg.InitialCluster != wcfg.InitialCluster {
|
||||
t.Errorf("initialCluster = %v, want %v", cfg.InitialCluster, wcfg.InitialCluster)
|
||||
}
|
||||
if cfg.InitialClusterToken != wcfg.InitialClusterToken {
|
||||
t.Errorf("initialClusterToken = %v, want %v", cfg.InitialClusterToken, wcfg.InitialClusterToken)
|
||||
}
|
||||
if !reflect.DeepEqual(cfg.APUrls, wcfg.APUrls) {
|
||||
t.Errorf("initial-advertise-peer-urls = %v, want %v", cfg.LPUrls, wcfg.LPUrls)
|
||||
}
|
||||
if !reflect.DeepEqual(cfg.ACUrls, wcfg.ACUrls) {
|
||||
t.Errorf("advertise-client-urls = %v, want %v", cfg.LCUrls, wcfg.LCUrls)
|
||||
}
|
||||
}
|
||||
|
||||
func validateOtherFlags(t *testing.T, cfg *config) {
|
||||
wcfg := newConfig()
|
||||
wcfg.proxy.Set(proxyFlagReadonly)
|
||||
if cfg.proxy.String() != wcfg.proxy.String() {
|
||||
t.Errorf("proxy = %v, want %v", cfg.proxy, wcfg.proxy)
|
||||
}
|
||||
}
|
||||
16
vendor/github.com/coreos/etcd/etcdmain/doc.go
generated
vendored
Normal file
16
vendor/github.com/coreos/etcd/etcdmain/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package etcdmain contains the main entry point for the etcd binary.
|
||||
package etcdmain
|
||||
411
vendor/github.com/coreos/etcd/etcdmain/etcd.go
generated
vendored
Normal file
411
vendor/github.com/coreos/etcd/etcdmain/etcd.go
generated
vendored
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package etcdmain
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/discovery"
|
||||
"github.com/coreos/etcd/embed"
|
||||
"github.com/coreos/etcd/etcdserver"
|
||||
"github.com/coreos/etcd/pkg/cors"
|
||||
"github.com/coreos/etcd/pkg/fileutil"
|
||||
pkgioutil "github.com/coreos/etcd/pkg/ioutil"
|
||||
"github.com/coreos/etcd/pkg/osutil"
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"github.com/coreos/etcd/pkg/types"
|
||||
"github.com/coreos/etcd/proxy/httpproxy"
|
||||
"github.com/coreos/etcd/version"
|
||||
"github.com/coreos/pkg/capnslog"
|
||||
"github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type dirType string
|
||||
|
||||
var plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdmain")
|
||||
|
||||
var (
|
||||
dirMember = dirType("member")
|
||||
dirProxy = dirType("proxy")
|
||||
dirEmpty = dirType("empty")
|
||||
)
|
||||
|
||||
func startEtcdOrProxyV2() {
|
||||
grpc.EnableTracing = false
|
||||
|
||||
cfg := newConfig()
|
||||
defaultInitialCluster := cfg.InitialCluster
|
||||
|
||||
err := cfg.parse(os.Args[1:])
|
||||
if err != nil {
|
||||
plog.Errorf("error verifying flags, %v. See 'etcd --help'.", err)
|
||||
switch err {
|
||||
case embed.ErrUnsetAdvertiseClientURLsFlag:
|
||||
plog.Errorf("When listening on specific address(es), this etcd process must advertise accessible url(s) to each connected client.")
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
setupLogging(cfg)
|
||||
|
||||
var stopped <-chan struct{}
|
||||
var errc <-chan error
|
||||
|
||||
plog.Infof("etcd Version: %s\n", version.Version)
|
||||
plog.Infof("Git SHA: %s\n", version.GitSHA)
|
||||
plog.Infof("Go Version: %s\n", runtime.Version())
|
||||
plog.Infof("Go OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
|
||||
|
||||
GoMaxProcs := runtime.GOMAXPROCS(0)
|
||||
plog.Infof("setting maximum number of CPUs to %d, total number of available CPUs is %d", GoMaxProcs, runtime.NumCPU())
|
||||
|
||||
defaultHost, dhErr := (&cfg.Config).UpdateDefaultClusterFromName(defaultInitialCluster)
|
||||
if defaultHost != "" {
|
||||
plog.Infof("advertising using detected default host %q", defaultHost)
|
||||
}
|
||||
if dhErr != nil {
|
||||
plog.Noticef("failed to detect default host (%v)", dhErr)
|
||||
}
|
||||
|
||||
if cfg.Dir == "" {
|
||||
cfg.Dir = fmt.Sprintf("%v.etcd", cfg.Name)
|
||||
plog.Warningf("no data-dir provided, using default data-dir ./%s", cfg.Dir)
|
||||
}
|
||||
|
||||
which := identifyDataDirOrDie(cfg.Dir)
|
||||
if which != dirEmpty {
|
||||
plog.Noticef("the server is already initialized as %v before, starting as etcd %v...", which, which)
|
||||
switch which {
|
||||
case dirMember:
|
||||
stopped, errc, err = startEtcd(&cfg.Config)
|
||||
case dirProxy:
|
||||
err = startProxy(cfg)
|
||||
default:
|
||||
plog.Panicf("unhandled dir type %v", which)
|
||||
}
|
||||
} else {
|
||||
shouldProxy := cfg.isProxy()
|
||||
if !shouldProxy {
|
||||
stopped, errc, err = startEtcd(&cfg.Config)
|
||||
if derr, ok := err.(*etcdserver.DiscoveryError); ok && derr.Err == discovery.ErrFullCluster {
|
||||
if cfg.shouldFallbackToProxy() {
|
||||
plog.Noticef("discovery cluster full, falling back to %s", fallbackFlagProxy)
|
||||
shouldProxy = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if shouldProxy {
|
||||
err = startProxy(cfg)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if derr, ok := err.(*etcdserver.DiscoveryError); ok {
|
||||
switch derr.Err {
|
||||
case discovery.ErrDuplicateID:
|
||||
plog.Errorf("member %q has previously registered with discovery service token (%s).", cfg.Name, cfg.Durl)
|
||||
plog.Errorf("But etcd could not find valid cluster configuration in the given data dir (%s).", cfg.Dir)
|
||||
plog.Infof("Please check the given data dir path if the previous bootstrap succeeded")
|
||||
plog.Infof("or use a new discovery token if the previous bootstrap failed.")
|
||||
case discovery.ErrDuplicateName:
|
||||
plog.Errorf("member with duplicated name has registered with discovery service token(%s).", cfg.Durl)
|
||||
plog.Errorf("please check (cURL) the discovery token for more information.")
|
||||
plog.Errorf("please do not reuse the discovery token and generate a new one to bootstrap the cluster.")
|
||||
default:
|
||||
plog.Errorf("%v", err)
|
||||
plog.Infof("discovery token %s was used, but failed to bootstrap the cluster.", cfg.Durl)
|
||||
plog.Infof("please generate a new discovery token and try to bootstrap again.")
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if strings.Contains(err.Error(), "include") && strings.Contains(err.Error(), "--initial-cluster") {
|
||||
plog.Infof("%v", err)
|
||||
if cfg.InitialCluster == cfg.InitialClusterFromName(cfg.Name) {
|
||||
plog.Infof("forgot to set --initial-cluster flag?")
|
||||
}
|
||||
if types.URLs(cfg.APUrls).String() == embed.DefaultInitialAdvertisePeerURLs {
|
||||
plog.Infof("forgot to set --initial-advertise-peer-urls flag?")
|
||||
}
|
||||
if cfg.InitialCluster == cfg.InitialClusterFromName(cfg.Name) && len(cfg.Durl) == 0 {
|
||||
plog.Infof("if you want to use discovery service, please set --discovery flag.")
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
plog.Fatalf("%v", err)
|
||||
}
|
||||
|
||||
osutil.HandleInterrupts()
|
||||
|
||||
// At this point, the initialization of etcd is done.
|
||||
// The listeners are listening on the TCP ports and ready
|
||||
// for accepting connections. The etcd instance should be
|
||||
// joined with the cluster and ready to serve incoming
|
||||
// connections.
|
||||
notifySystemd()
|
||||
|
||||
select {
|
||||
case lerr := <-errc:
|
||||
// fatal out on listener errors
|
||||
plog.Fatal(lerr)
|
||||
case <-stopped:
|
||||
}
|
||||
|
||||
osutil.Exit(0)
|
||||
}
|
||||
|
||||
// startEtcd runs StartEtcd in addition to hooks needed for standalone etcd.
|
||||
func startEtcd(cfg *embed.Config) (<-chan struct{}, <-chan error, error) {
|
||||
if cfg.Metrics == "extensive" {
|
||||
grpc_prometheus.EnableHandlingTimeHistogram()
|
||||
}
|
||||
|
||||
e, err := embed.StartEtcd(cfg)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
osutil.RegisterInterruptHandler(e.Server.Stop)
|
||||
select {
|
||||
case <-e.Server.ReadyNotify(): // wait for e.Server to join the cluster
|
||||
case <-e.Server.StopNotify(): // publish aborted from 'ErrStopped'
|
||||
}
|
||||
return e.Server.StopNotify(), e.Err(), nil
|
||||
}
|
||||
|
||||
// startProxy launches an HTTP proxy for client communication which proxies to other etcd nodes.
|
||||
func startProxy(cfg *config) error {
|
||||
plog.Notice("proxy: this proxy supports v2 API only!")
|
||||
|
||||
pt, err := transport.NewTimeoutTransport(cfg.PeerTLSInfo, time.Duration(cfg.ProxyDialTimeoutMs)*time.Millisecond, time.Duration(cfg.ProxyReadTimeoutMs)*time.Millisecond, time.Duration(cfg.ProxyWriteTimeoutMs)*time.Millisecond)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pt.MaxIdleConnsPerHost = httpproxy.DefaultMaxIdleConnsPerHost
|
||||
|
||||
tr, err := transport.NewTimeoutTransport(cfg.PeerTLSInfo, time.Duration(cfg.ProxyDialTimeoutMs)*time.Millisecond, time.Duration(cfg.ProxyReadTimeoutMs)*time.Millisecond, time.Duration(cfg.ProxyWriteTimeoutMs)*time.Millisecond)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.Dir = filepath.Join(cfg.Dir, "proxy")
|
||||
err = os.MkdirAll(cfg.Dir, fileutil.PrivateDirMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var peerURLs []string
|
||||
clusterfile := filepath.Join(cfg.Dir, "cluster")
|
||||
|
||||
b, err := ioutil.ReadFile(clusterfile)
|
||||
switch {
|
||||
case err == nil:
|
||||
if cfg.Durl != "" {
|
||||
plog.Warningf("discovery token ignored since the proxy has already been initialized. Valid cluster file found at %q", clusterfile)
|
||||
}
|
||||
if cfg.DNSCluster != "" {
|
||||
plog.Warningf("DNS SRV discovery ignored since the proxy has already been initialized. Valid cluster file found at %q", clusterfile)
|
||||
}
|
||||
urls := struct{ PeerURLs []string }{}
|
||||
err = json.Unmarshal(b, &urls)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
peerURLs = urls.PeerURLs
|
||||
plog.Infof("proxy: using peer urls %v from cluster file %q", peerURLs, clusterfile)
|
||||
case os.IsNotExist(err):
|
||||
var urlsmap types.URLsMap
|
||||
urlsmap, _, err = cfg.PeerURLsMapAndToken("proxy")
|
||||
if err != nil {
|
||||
return fmt.Errorf("error setting up initial cluster: %v", err)
|
||||
}
|
||||
|
||||
if cfg.Durl != "" {
|
||||
var s string
|
||||
s, err = discovery.GetCluster(cfg.Durl, cfg.Dproxy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if urlsmap, err = types.NewURLsMap(s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
peerURLs = urlsmap.URLs()
|
||||
plog.Infof("proxy: using peer urls %v ", peerURLs)
|
||||
default:
|
||||
return err
|
||||
}
|
||||
|
||||
clientURLs := []string{}
|
||||
uf := func() []string {
|
||||
gcls, gerr := etcdserver.GetClusterFromRemotePeers(peerURLs, tr)
|
||||
|
||||
if gerr != nil {
|
||||
plog.Warningf("proxy: %v", gerr)
|
||||
return []string{}
|
||||
}
|
||||
|
||||
clientURLs = gcls.ClientURLs()
|
||||
|
||||
urls := struct{ PeerURLs []string }{gcls.PeerURLs()}
|
||||
b, jerr := json.Marshal(urls)
|
||||
if jerr != nil {
|
||||
plog.Warningf("proxy: error on marshal peer urls %s", jerr)
|
||||
return clientURLs
|
||||
}
|
||||
|
||||
err = pkgioutil.WriteAndSyncFile(clusterfile+".bak", b, 0600)
|
||||
if err != nil {
|
||||
plog.Warningf("proxy: error on writing urls %s", err)
|
||||
return clientURLs
|
||||
}
|
||||
err = os.Rename(clusterfile+".bak", clusterfile)
|
||||
if err != nil {
|
||||
plog.Warningf("proxy: error on updating clusterfile %s", err)
|
||||
return clientURLs
|
||||
}
|
||||
if !reflect.DeepEqual(gcls.PeerURLs(), peerURLs) {
|
||||
plog.Noticef("proxy: updated peer urls in cluster file from %v to %v", peerURLs, gcls.PeerURLs())
|
||||
}
|
||||
peerURLs = gcls.PeerURLs()
|
||||
|
||||
return clientURLs
|
||||
}
|
||||
ph := httpproxy.NewHandler(pt, uf, time.Duration(cfg.ProxyFailureWaitMs)*time.Millisecond, time.Duration(cfg.ProxyRefreshIntervalMs)*time.Millisecond)
|
||||
ph = &cors.CORSHandler{
|
||||
Handler: ph,
|
||||
Info: cfg.CorsInfo,
|
||||
}
|
||||
|
||||
if cfg.isReadonlyProxy() {
|
||||
ph = httpproxy.NewReadonlyHandler(ph)
|
||||
}
|
||||
// Start a proxy server goroutine for each listen address
|
||||
for _, u := range cfg.LCUrls {
|
||||
var (
|
||||
l net.Listener
|
||||
tlscfg *tls.Config
|
||||
)
|
||||
if !cfg.ClientTLSInfo.Empty() {
|
||||
tlscfg, err = cfg.ClientTLSInfo.ServerConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
l, err := transport.NewListener(u.Host, u.Scheme, tlscfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
host := u.String()
|
||||
go func() {
|
||||
plog.Info("proxy: listening for client requests on ", host)
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/metrics", prometheus.Handler())
|
||||
mux.Handle("/", ph)
|
||||
plog.Fatal(http.Serve(l, mux))
|
||||
}()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// identifyDataDirOrDie returns the type of the data dir.
|
||||
// Dies if the datadir is invalid.
|
||||
func identifyDataDirOrDie(dir string) dirType {
|
||||
names, err := fileutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return dirEmpty
|
||||
}
|
||||
plog.Fatalf("error listing data dir: %s", dir)
|
||||
}
|
||||
|
||||
var m, p bool
|
||||
for _, name := range names {
|
||||
switch dirType(name) {
|
||||
case dirMember:
|
||||
m = true
|
||||
case dirProxy:
|
||||
p = true
|
||||
default:
|
||||
plog.Warningf("found invalid file/dir %s under data dir %s (Ignore this if you are upgrading etcd)", name, dir)
|
||||
}
|
||||
}
|
||||
|
||||
if m && p {
|
||||
plog.Fatal("invalid datadir. Both member and proxy directories exist.")
|
||||
}
|
||||
if m {
|
||||
return dirMember
|
||||
}
|
||||
if p {
|
||||
return dirProxy
|
||||
}
|
||||
return dirEmpty
|
||||
}
|
||||
|
||||
func setupLogging(cfg *config) {
|
||||
capnslog.SetGlobalLogLevel(capnslog.INFO)
|
||||
if cfg.Debug {
|
||||
capnslog.SetGlobalLogLevel(capnslog.DEBUG)
|
||||
}
|
||||
if cfg.LogPkgLevels != "" {
|
||||
repoLog := capnslog.MustRepoLogger("github.com/coreos/etcd")
|
||||
settings, err := repoLog.ParseLogLevelConfig(cfg.LogPkgLevels)
|
||||
if err != nil {
|
||||
plog.Warningf("couldn't parse log level string: %s, continuing with default levels", err.Error())
|
||||
return
|
||||
}
|
||||
repoLog.SetLogLevel(settings)
|
||||
}
|
||||
|
||||
// capnslog initially SetFormatter(NewDefaultFormatter(os.Stderr))
|
||||
// where NewDefaultFormatter returns NewJournaldFormatter when syscall.Getppid() == 1
|
||||
// specify 'stdout' or 'stderr' to skip journald logging even when running under systemd
|
||||
switch cfg.logOutput {
|
||||
case "stdout":
|
||||
capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stdout, cfg.Debug))
|
||||
case "stderr":
|
||||
capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stderr, cfg.Debug))
|
||||
case "default":
|
||||
default:
|
||||
plog.Panicf(`unknown log-output %q (only supports "default", "stdout", "stderr")`, cfg.logOutput)
|
||||
}
|
||||
}
|
||||
|
||||
func checkSupportArch() {
|
||||
// TODO qualify arm64
|
||||
if runtime.GOARCH == "amd64" {
|
||||
return
|
||||
}
|
||||
if env, ok := os.LookupEnv("ETCD_UNSUPPORTED_ARCH"); ok && env == runtime.GOARCH {
|
||||
plog.Warningf("running etcd on unsupported architecture %q since ETCD_UNSUPPORTED_ARCH is set", env)
|
||||
return
|
||||
}
|
||||
plog.Errorf("etcd on unsupported platform without ETCD_UNSUPPORTED_ARCH=%s set.", runtime.GOARCH)
|
||||
os.Exit(1)
|
||||
}
|
||||
143
vendor/github.com/coreos/etcd/etcdmain/gateway.go
generated
vendored
Normal file
143
vendor/github.com/coreos/etcd/etcdmain/gateway.go
generated
vendored
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package etcdmain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/client"
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"github.com/coreos/etcd/proxy/tcpproxy"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
gatewayListenAddr string
|
||||
gatewayEndpoints []string
|
||||
gatewayDNSCluster string
|
||||
gatewayInsecureDiscovery bool
|
||||
getewayRetryDelay time.Duration
|
||||
gatewayCA string
|
||||
)
|
||||
|
||||
var (
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "etcd",
|
||||
Short: "etcd server",
|
||||
SuggestFor: []string{"etcd"},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(newGatewayCommand())
|
||||
}
|
||||
|
||||
// newGatewayCommand returns the cobra command for "gateway".
|
||||
func newGatewayCommand() *cobra.Command {
|
||||
lpc := &cobra.Command{
|
||||
Use: "gateway <subcommand>",
|
||||
Short: "gateway related command",
|
||||
}
|
||||
lpc.AddCommand(newGatewayStartCommand())
|
||||
|
||||
return lpc
|
||||
}
|
||||
|
||||
func newGatewayStartCommand() *cobra.Command {
|
||||
cmd := cobra.Command{
|
||||
Use: "start",
|
||||
Short: "start the gateway",
|
||||
Run: startGateway,
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&gatewayListenAddr, "listen-addr", "127.0.0.1:23790", "listen address")
|
||||
cmd.Flags().StringVar(&gatewayDNSCluster, "discovery-srv", "", "DNS domain used to bootstrap initial cluster")
|
||||
cmd.Flags().BoolVar(&gatewayInsecureDiscovery, "insecure-discovery", false, "accept insecure SRV records")
|
||||
cmd.Flags().StringVar(&gatewayCA, "trusted-ca-file", "", "path to the client server TLS CA file.")
|
||||
|
||||
cmd.Flags().StringSliceVar(&gatewayEndpoints, "endpoints", []string{"127.0.0.1:2379"}, "comma separated etcd cluster endpoints")
|
||||
|
||||
cmd.Flags().DurationVar(&getewayRetryDelay, "retry-delay", time.Minute, "duration of delay before retrying failed endpoints")
|
||||
|
||||
return &cmd
|
||||
}
|
||||
|
||||
func stripSchema(eps []string) []string {
|
||||
var endpoints []string
|
||||
|
||||
for _, ep := range eps {
|
||||
|
||||
if u, err := url.Parse(ep); err == nil && u.Host != "" {
|
||||
ep = u.Host
|
||||
}
|
||||
|
||||
endpoints = append(endpoints, ep)
|
||||
}
|
||||
|
||||
return endpoints
|
||||
}
|
||||
func startGateway(cmd *cobra.Command, args []string) {
|
||||
endpoints := gatewayEndpoints
|
||||
if gatewayDNSCluster != "" {
|
||||
eps, err := client.NewSRVDiscover().Discover(gatewayDNSCluster)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
plog.Infof("discovered the cluster %s from %s", eps, gatewayDNSCluster)
|
||||
// confirm TLS connections are good
|
||||
if !gatewayInsecureDiscovery {
|
||||
tlsInfo := transport.TLSInfo{
|
||||
TrustedCAFile: gatewayCA,
|
||||
ServerName: gatewayDNSCluster,
|
||||
}
|
||||
plog.Infof("validating discovered endpoints %v", eps)
|
||||
endpoints, err = transport.ValidateSecureEndpoints(tlsInfo, eps)
|
||||
if err != nil {
|
||||
plog.Warningf("%v", err)
|
||||
}
|
||||
plog.Infof("using discovered endpoints %v", endpoints)
|
||||
}
|
||||
}
|
||||
|
||||
// Strip the schema from the endpoints because we start just a TCP proxy
|
||||
endpoints = stripSchema(endpoints)
|
||||
|
||||
if len(endpoints) == 0 {
|
||||
plog.Fatalf("no endpoints found")
|
||||
}
|
||||
|
||||
l, err := net.Listen("tcp", gatewayListenAddr)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
tp := tcpproxy.TCPProxy{
|
||||
Listener: l,
|
||||
Endpoints: endpoints,
|
||||
MonitorInterval: getewayRetryDelay,
|
||||
}
|
||||
|
||||
// At this point, etcd gateway listener is initialized
|
||||
notifySystemd()
|
||||
|
||||
tp.Run()
|
||||
}
|
||||
188
vendor/github.com/coreos/etcd/etcdmain/grpc_proxy.go
generated
vendored
Normal file
188
vendor/github.com/coreos/etcd/etcdmain/grpc_proxy.go
generated
vendored
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package etcdmain
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/clientv3"
|
||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"github.com/coreos/etcd/proxy/grpcproxy"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/cockroachdb/cmux"
|
||||
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var (
|
||||
grpcProxyListenAddr string
|
||||
grpcProxyEndpoints []string
|
||||
grpcProxyCert string
|
||||
grpcProxyKey string
|
||||
grpcProxyCA string
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(newGRPCProxyCommand())
|
||||
}
|
||||
|
||||
// newGRPCProxyCommand returns the cobra command for "grpc-proxy".
|
||||
func newGRPCProxyCommand() *cobra.Command {
|
||||
lpc := &cobra.Command{
|
||||
Use: "grpc-proxy <subcommand>",
|
||||
Short: "grpc-proxy related command",
|
||||
}
|
||||
lpc.AddCommand(newGRPCProxyStartCommand())
|
||||
|
||||
return lpc
|
||||
}
|
||||
|
||||
func newGRPCProxyStartCommand() *cobra.Command {
|
||||
cmd := cobra.Command{
|
||||
Use: "start",
|
||||
Short: "start the grpc proxy",
|
||||
Run: startGRPCProxy,
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&grpcProxyListenAddr, "listen-addr", "127.0.0.1:23790", "listen address")
|
||||
cmd.Flags().StringSliceVar(&grpcProxyEndpoints, "endpoints", []string{"127.0.0.1:2379"}, "comma separated etcd cluster endpoints")
|
||||
cmd.Flags().StringVar(&grpcProxyCert, "cert", "", "identify secure connections with etcd servers using this TLS certificate file")
|
||||
cmd.Flags().StringVar(&grpcProxyKey, "key", "", "identify secure connections with etcd servers using this TLS key file")
|
||||
cmd.Flags().StringVar(&grpcProxyCA, "cacert", "", "verify certificates of TLS-enabled secure etcd servers using this CA bundle")
|
||||
|
||||
return &cmd
|
||||
}
|
||||
|
||||
func startGRPCProxy(cmd *cobra.Command, args []string) {
|
||||
l, err := net.Listen("tcp", grpcProxyListenAddr)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if l, err = transport.NewKeepAliveListener(l, "tcp", nil); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
plog.Infof("listening for grpc-proxy client requests on %s", grpcProxyListenAddr)
|
||||
defer func() {
|
||||
l.Close()
|
||||
plog.Infof("stopping listening for grpc-proxy client requests on %s", grpcProxyListenAddr)
|
||||
}()
|
||||
m := cmux.New(l)
|
||||
|
||||
cfg, err := newClientCfg()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
client, err := clientv3.New(*cfg)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
kvp, _ := grpcproxy.NewKvProxy(client)
|
||||
watchp, _ := grpcproxy.NewWatchProxy(client)
|
||||
clusterp := grpcproxy.NewClusterProxy(client)
|
||||
leasep := grpcproxy.NewLeaseProxy(client)
|
||||
mainp := grpcproxy.NewMaintenanceProxy(client)
|
||||
authp := grpcproxy.NewAuthProxy(client)
|
||||
|
||||
server := grpc.NewServer(
|
||||
grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
|
||||
grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
|
||||
)
|
||||
pb.RegisterKVServer(server, kvp)
|
||||
pb.RegisterWatchServer(server, watchp)
|
||||
pb.RegisterClusterServer(server, clusterp)
|
||||
pb.RegisterLeaseServer(server, leasep)
|
||||
pb.RegisterMaintenanceServer(server, mainp)
|
||||
pb.RegisterAuthServer(server, authp)
|
||||
|
||||
errc := make(chan error)
|
||||
|
||||
grpcl := m.Match(cmux.HTTP2())
|
||||
go func() { errc <- server.Serve(grpcl) }()
|
||||
|
||||
httpmux := http.NewServeMux()
|
||||
httpmux.HandleFunc("/", http.NotFound)
|
||||
httpmux.Handle("/metrics", prometheus.Handler())
|
||||
srvhttp := &http.Server{
|
||||
Handler: httpmux,
|
||||
}
|
||||
|
||||
var httpl net.Listener
|
||||
if cfg.TLS != nil {
|
||||
srvhttp.TLSConfig = cfg.TLS
|
||||
httpl = tls.NewListener(m.Match(cmux.Any()), cfg.TLS)
|
||||
} else {
|
||||
httpl = m.Match(cmux.HTTP1())
|
||||
}
|
||||
go func() { errc <- srvhttp.Serve(httpl) }()
|
||||
|
||||
go func() { errc <- m.Serve() }()
|
||||
|
||||
// grpc-proxy is initialized, ready to serve
|
||||
notifySystemd()
|
||||
|
||||
fmt.Fprintln(os.Stderr, <-errc)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func newClientCfg() (*clientv3.Config, error) {
|
||||
// set tls if any one tls option set
|
||||
var cfgtls *transport.TLSInfo
|
||||
tlsinfo := transport.TLSInfo{}
|
||||
if grpcProxyCert != "" {
|
||||
tlsinfo.CertFile = grpcProxyCert
|
||||
cfgtls = &tlsinfo
|
||||
}
|
||||
|
||||
if grpcProxyKey != "" {
|
||||
tlsinfo.KeyFile = grpcProxyKey
|
||||
cfgtls = &tlsinfo
|
||||
}
|
||||
|
||||
if grpcProxyCA != "" {
|
||||
tlsinfo.CAFile = grpcProxyCA
|
||||
cfgtls = &tlsinfo
|
||||
}
|
||||
|
||||
cfg := clientv3.Config{
|
||||
Endpoints: grpcProxyEndpoints,
|
||||
DialTimeout: 5 * time.Second,
|
||||
}
|
||||
if cfgtls != nil {
|
||||
clientTLS, err := cfgtls.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.TLS = clientTLS
|
||||
}
|
||||
|
||||
// TODO: support insecure tls
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
159
vendor/github.com/coreos/etcd/etcdmain/help.go
generated
vendored
Normal file
159
vendor/github.com/coreos/etcd/etcdmain/help.go
generated
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package etcdmain
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/coreos/etcd/embed"
|
||||
)
|
||||
|
||||
var (
|
||||
usageline = `usage: etcd [flags]
|
||||
start an etcd server
|
||||
|
||||
etcd --version
|
||||
show the version of etcd
|
||||
|
||||
etcd -h | --help
|
||||
show the help information about etcd
|
||||
|
||||
etcd --config-file
|
||||
path to the server configuration file
|
||||
`
|
||||
flagsline = `
|
||||
member flags:
|
||||
|
||||
--name 'default'
|
||||
human-readable name for this member.
|
||||
--data-dir '${name}.etcd'
|
||||
path to the data directory.
|
||||
--wal-dir ''
|
||||
path to the dedicated wal directory.
|
||||
--snapshot-count '10000'
|
||||
number of committed transactions to trigger a snapshot to disk.
|
||||
--heartbeat-interval '100'
|
||||
time (in milliseconds) of a heartbeat interval.
|
||||
--election-timeout '1000'
|
||||
time (in milliseconds) for an election to timeout. See tuning documentation for details.
|
||||
--listen-peer-urls 'http://localhost:2380'
|
||||
list of URLs to listen on for peer traffic.
|
||||
--listen-client-urls 'http://localhost:2379'
|
||||
list of URLs to listen on for client traffic.
|
||||
--max-snapshots '` + strconv.Itoa(embed.DefaultMaxSnapshots) + `'
|
||||
maximum number of snapshot files to retain (0 is unlimited).
|
||||
--max-wals '` + strconv.Itoa(embed.DefaultMaxWALs) + `'
|
||||
maximum number of wal files to retain (0 is unlimited).
|
||||
--cors ''
|
||||
comma-separated whitelist of origins for CORS (cross-origin resource sharing).
|
||||
--quota-backend-bytes '0'
|
||||
raise alarms when backend size exceeds the given quota (0 defaults to low space quota).
|
||||
|
||||
clustering flags:
|
||||
|
||||
--initial-advertise-peer-urls 'http://localhost:2380'
|
||||
list of this member's peer URLs to advertise to the rest of the cluster.
|
||||
--initial-cluster 'default=http://localhost:2380'
|
||||
initial cluster configuration for bootstrapping.
|
||||
--initial-cluster-state 'new'
|
||||
initial cluster state ('new' or 'existing').
|
||||
--initial-cluster-token 'etcd-cluster'
|
||||
initial cluster token for the etcd cluster during bootstrap.
|
||||
Specifying this can protect you from unintended cross-cluster interaction when running multiple clusters.
|
||||
--advertise-client-urls 'http://localhost:2379'
|
||||
list of this member's client URLs to advertise to the public.
|
||||
The client URLs advertised should be accessible to machines that talk to etcd cluster. etcd client libraries parse these URLs to connect to the cluster.
|
||||
--discovery ''
|
||||
discovery URL used to bootstrap the cluster.
|
||||
--discovery-fallback 'proxy'
|
||||
expected behavior ('exit' or 'proxy') when discovery services fails.
|
||||
"proxy" supports v2 API only.
|
||||
--discovery-proxy ''
|
||||
HTTP proxy to use for traffic to discovery service.
|
||||
--discovery-srv ''
|
||||
dns srv domain used to bootstrap the cluster.
|
||||
--strict-reconfig-check
|
||||
reject reconfiguration requests that would cause quorum loss.
|
||||
--auto-compaction-retention '0'
|
||||
auto compaction retention in hour. 0 means disable auto compaction.
|
||||
|
||||
proxy flags:
|
||||
"proxy" supports v2 API only.
|
||||
|
||||
--proxy 'off'
|
||||
proxy mode setting ('off', 'readonly' or 'on').
|
||||
--proxy-failure-wait 5000
|
||||
time (in milliseconds) an endpoint will be held in a failed state.
|
||||
--proxy-refresh-interval 30000
|
||||
time (in milliseconds) of the endpoints refresh interval.
|
||||
--proxy-dial-timeout 1000
|
||||
time (in milliseconds) for a dial to timeout.
|
||||
--proxy-write-timeout 5000
|
||||
time (in milliseconds) for a write to timeout.
|
||||
--proxy-read-timeout 0
|
||||
time (in milliseconds) for a read to timeout.
|
||||
|
||||
|
||||
security flags:
|
||||
|
||||
--ca-file '' [DEPRECATED]
|
||||
path to the client server TLS CA file. '-ca-file ca.crt' could be replaced by '-trusted-ca-file ca.crt -client-cert-auth' and etcd will perform the same.
|
||||
--cert-file ''
|
||||
path to the client server TLS cert file.
|
||||
--key-file ''
|
||||
path to the client server TLS key file.
|
||||
--client-cert-auth 'false'
|
||||
enable client cert authentication.
|
||||
--trusted-ca-file ''
|
||||
path to the client server TLS trusted CA key file.
|
||||
--auto-tls 'false'
|
||||
client TLS using generated certificates.
|
||||
--peer-ca-file '' [DEPRECATED]
|
||||
path to the peer server TLS CA file. '-peer-ca-file ca.crt' could be replaced by '-peer-trusted-ca-file ca.crt -peer-client-cert-auth' and etcd will perform the same.
|
||||
--peer-cert-file ''
|
||||
path to the peer server TLS cert file.
|
||||
--peer-key-file ''
|
||||
path to the peer server TLS key file.
|
||||
--peer-client-cert-auth 'false'
|
||||
enable peer client cert authentication.
|
||||
--peer-trusted-ca-file ''
|
||||
path to the peer server TLS trusted CA file.
|
||||
--peer-auto-tls 'false'
|
||||
peer TLS using self-generated certificates if --peer-key-file and --peer-cert-file are not provided.
|
||||
|
||||
logging flags
|
||||
|
||||
--debug 'false'
|
||||
enable debug-level logging for etcd.
|
||||
--log-package-levels ''
|
||||
specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG').
|
||||
--log-output 'default'
|
||||
specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.
|
||||
|
||||
unsafe flags:
|
||||
|
||||
Please be CAUTIOUS when using unsafe flags because it will break the guarantees
|
||||
given by the consensus protocol.
|
||||
|
||||
--force-new-cluster 'false'
|
||||
force to create a new one-member cluster.
|
||||
|
||||
profiling flags:
|
||||
--enable-pprof 'false'
|
||||
Enable runtime profiling data via HTTP server. Address is at client URL + "/debug/pprof/"
|
||||
--metrics 'basic'
|
||||
Set level of detail for exported metrics, specify 'extensive' to include histogram metrics.
|
||||
`
|
||||
)
|
||||
53
vendor/github.com/coreos/etcd/etcdmain/main.go
generated
vendored
Normal file
53
vendor/github.com/coreos/etcd/etcdmain/main.go
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package etcdmain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/coreos/go-systemd/daemon"
|
||||
systemdutil "github.com/coreos/go-systemd/util"
|
||||
)
|
||||
|
||||
func Main() {
|
||||
checkSupportArch()
|
||||
|
||||
if len(os.Args) > 1 {
|
||||
switch os.Args[1] {
|
||||
case "gateway", "grpc-proxy":
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Fprint(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
startEtcdOrProxyV2()
|
||||
}
|
||||
|
||||
func notifySystemd() {
|
||||
if !systemdutil.IsRunningSystemd() {
|
||||
return
|
||||
}
|
||||
sent, err := daemon.SdNotify(false, "READY=1")
|
||||
if err != nil {
|
||||
plog.Errorf("failed to notify systemd for readiness: %v", err)
|
||||
}
|
||||
if !sent {
|
||||
plog.Errorf("forgot to set Type=notify in systemd service file?")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue