Jan Chaloupka 005d87
From 81519130b0abec199ddc9e3559e64884742b1bf5 Mon Sep 17 00:00:00 2001
Jan Chaloupka 005d87
From: Jan Chaloupka <jchaloup@redhat.com>
Jan Chaloupka 005d87
Date: Tue, 7 Nov 2017 14:04:01 +0100
Jan Chaloupka 005d87
Subject: [PATCH] hack etcdmain to generate etcd.1
Jan Chaloupka 005d87
Jan Chaloupka 005d87
---
Jan Chaloupka 005d87
 etcdmain/config.go       |  25 ++++----
Jan Chaloupka 005d87
 etcdmain/fake_flagset.go | 157 +++++++++++++++++++++++++++++++++++++++++++++++
Jan Chaloupka 005d87
 2 files changed, 171 insertions(+), 11 deletions(-)
Jan Chaloupka 005d87
 create mode 100644 etcdmain/fake_flagset.go
Jan Chaloupka 005d87
Jan Chaloupka 005d87
diff --git a/etcdmain/config.go b/etcdmain/config.go
Jan Chaloupka 005d87
index b873220..4770334 100644
Jan Chaloupka 005d87
--- a/etcdmain/config.go
Jan Chaloupka 005d87
+++ b/etcdmain/config.go
Jan Chaloupka 005d87
@@ -118,14 +118,14 @@ func newConfig() *config {
Jan Chaloupka 005d87
 		),
Jan Chaloupka 005d87
 	}
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	fs := cfg.FlagSet
Jan Chaloupka 005d87
-	fs.Usage = func() {
Jan Chaloupka 005d87
+	fs := InitFlagSet(cfg.FlagSet)
Jan Chaloupka 005d87
+	cfg.FlagSet.Usage = func() {
Jan Chaloupka 005d87
 		fmt.Fprintln(os.Stderr, usageline)
Jan Chaloupka 005d87
 	}
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.configFile, "config-file", "", "Path to the server configuration file")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	// member
Jan Chaloupka 005d87
+	fs.AddGroup("member")
Jan Chaloupka 005d87
 	fs.Var(cfg.CorsInfo, "cors", "Comma-separated white list of origins for CORS (cross-origin resource sharing).")
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.Dir, "data-dir", cfg.Dir, "Path to the data directory.")
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.WalDir, "wal-dir", cfg.WalDir, "Path to the dedicated wal directory.")
Jan Chaloupka 005d87
@@ -139,7 +139,7 @@ func newConfig() *config {
Jan Chaloupka 005d87
 	fs.UintVar(&cfg.ElectionMs, "election-timeout", cfg.ElectionMs, "Time (in milliseconds) for an election to timeout.")
Jan Chaloupka 005d87
 	fs.Int64Var(&cfg.QuotaBackendBytes, "quota-backend-bytes", cfg.QuotaBackendBytes, "Raise alarms when backend size exceeds the given quota. 0 means use the default quota.")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	// clustering
Jan Chaloupka 005d87
+	fs.AddGroup("clustering")
Jan Chaloupka 005d87
 	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.")
Jan Chaloupka 005d87
 	fs.Var(flags.NewURLsValue(embed.DefaultAdvertiseClientURLs), "advertise-client-urls", "List of this member's client URLs to advertise to the public.")
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.Durl, "discovery", cfg.Durl, "Discovery URL used to bootstrap the cluster.")
Jan Chaloupka 005d87
@@ -160,7 +160,7 @@ func newConfig() *config {
Jan Chaloupka 005d87
 	fs.BoolVar(&cfg.StrictReconfigCheck, "strict-reconfig-check", cfg.StrictReconfigCheck, "Reject reconfiguration requests that would cause quorum loss.")
Jan Chaloupka 005d87
 	fs.BoolVar(&cfg.EnableV2, "enable-v2", true, "Accept etcd V2 client requests.")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	// proxy
Jan Chaloupka 005d87
+	fs.AddGroup("proxy")
Jan Chaloupka 005d87
 	fs.Var(cfg.proxy, "proxy", fmt.Sprintf("Valid values include %s", strings.Join(cfg.proxy.Values, ", ")))
Jan Chaloupka 005d87
 	if err := cfg.proxy.Set(proxyFlagOff); err != nil {
Jan Chaloupka 005d87
 		// Should never happen.
Jan Chaloupka 005d87
@@ -172,7 +172,7 @@ func newConfig() *config {
Jan Chaloupka 005d87
 	fs.UintVar(&cfg.ProxyWriteTimeoutMs, "proxy-write-timeout", cfg.ProxyWriteTimeoutMs, "Time (in milliseconds) for a write to timeout.")
Jan Chaloupka 005d87
 	fs.UintVar(&cfg.ProxyReadTimeoutMs, "proxy-read-timeout", cfg.ProxyReadTimeoutMs, "Time (in milliseconds) for a read to timeout.")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	// security
Jan Chaloupka 005d87
+	fs.AddGroup("security")
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.ClientTLSInfo.CAFile, "ca-file", "", "DEPRECATED: Path to the client server TLS CA file.")
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.ClientTLSInfo.CertFile, "cert-file", "", "Path to the client server TLS cert file.")
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.ClientTLSInfo.KeyFile, "key-file", "", "Path to the client server TLS key file.")
Jan Chaloupka 005d87
@@ -186,28 +186,31 @@ func newConfig() *config {
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.PeerTLSInfo.TrustedCAFile, "peer-trusted-ca-file", "", "Path to the peer server TLS trusted CA file.")
Jan Chaloupka 005d87
 	fs.BoolVar(&cfg.PeerAutoTLS, "peer-auto-tls", false, "Peer TLS using generated certificates")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	// logging
Jan Chaloupka 005d87
+	fs.AddGroup("logging")
Jan Chaloupka 005d87
 	fs.BoolVar(&cfg.Debug, "debug", false, "Enable debug-level logging for etcd.")
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.LogPkgLevels, "log-package-levels", "", "Specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG').")
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.logOutput, "log-output", "default", "Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	// unsafe
Jan Chaloupka 005d87
+	fs.AddGroup("unsafe")
Jan Chaloupka 005d87
 	fs.BoolVar(&cfg.ForceNewCluster, "force-new-cluster", false, "Force to create a new one member cluster.")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	// version
Jan Chaloupka 005d87
+	fs.AddGroup("version")
Jan Chaloupka 005d87
 	fs.BoolVar(&cfg.printVersion, "version", false, "Print the version and exit.")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
 	fs.IntVar(&cfg.AutoCompactionRetention, "auto-compaction-retention", 0, "Auto compaction retention for mvcc key value store in hour. 0 means disable auto compaction.")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	// pprof profiler via HTTP
Jan Chaloupka 005d87
+	fs.AddGroup("profiling")
Jan Chaloupka 005d87
 	fs.BoolVar(&cfg.EnablePprof, "enable-pprof", false, "Enable runtime profiling data via HTTP server. Address is at client URL + \"/debug/pprof/\"")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
 	// additional metrics
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.Metrics, "metrics", cfg.Metrics, "Set level of detail for exported metrics, specify 'extensive' to include histogram metrics")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
-	// auth
Jan Chaloupka 005d87
+	fs.AddGroup("auth")
Jan Chaloupka 005d87
 	fs.StringVar(&cfg.AuthToken, "auth-token", cfg.AuthToken, "Specify auth token specific options.")
Jan Chaloupka 005d87
 
Jan Chaloupka 005d87
+	fs.GenMan()
Jan Chaloupka 005d87
+	os.Exit(0)
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
 	// ignored
Jan Chaloupka 005d87
 	for _, f := range cfg.ignored {
Jan Chaloupka 005d87
 		fs.Var(&flags.IgnoredFlag{Name: f}, f, "")
Jan Chaloupka 005d87
diff --git a/etcdmain/fake_flagset.go b/etcdmain/fake_flagset.go
Jan Chaloupka 005d87
new file mode 100644
Jan Chaloupka 005d87
index 0000000..71f230b
Jan Chaloupka 005d87
--- /dev/null
Jan Chaloupka 005d87
+++ b/etcdmain/fake_flagset.go
Jan Chaloupka 005d87
@@ -0,0 +1,157 @@
Jan Chaloupka 005d87
+package etcdmain
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+import (
Jan Chaloupka 005d87
+	"flag"
Jan Chaloupka 005d87
+	"fmt"
Jan Chaloupka 005d87
+	"strconv"
Jan Chaloupka 005d87
+	"strings"
Jan Chaloupka 005d87
+	"time"
Jan Chaloupka 005d87
+)
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+type flagInfo struct {
Jan Chaloupka 005d87
+	value fmt.Stringer
Jan Chaloupka 005d87
+	name  string
Jan Chaloupka 005d87
+	usage string
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+type stringValue string
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (s *stringValue) String() string { return string(*s) }
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+type uintValue uint
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+type uint64Value uint64
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+type int64Value int64
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+type durationValue time.Duration
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (d *durationValue) String() string { return (*time.Duration)(d).String() }
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+type boolValue bool
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+type FakeFlagSet struct {
Jan Chaloupka 005d87
+	fs        *flag.FlagSet
Jan Chaloupka 005d87
+	flags     map[string][]flagInfo
Jan Chaloupka 005d87
+	groups    []string
Jan Chaloupka 005d87
+	lastGroup string
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func InitFlagSet(fs *flag.FlagSet) *FakeFlagSet {
Jan Chaloupka 005d87
+	return &FakeFlagSet{
Jan Chaloupka 005d87
+		fs:    fs,
Jan Chaloupka 005d87
+		flags: make(map[string][]flagInfo),
Jan Chaloupka 005d87
+	}
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) AddGroup(name string) {
Jan Chaloupka 005d87
+	fs.flags[name] = nil
Jan Chaloupka 005d87
+	fs.groups = append(fs.groups, name)
Jan Chaloupka 005d87
+	fs.lastGroup = name
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) Var(value flag.Value, name string, usage string) {
Jan Chaloupka 005d87
+	fs.flags[fs.lastGroup] = append(fs.flags[fs.lastGroup], flagInfo{
Jan Chaloupka 005d87
+		value: value,
Jan Chaloupka 005d87
+		name:  name,
Jan Chaloupka 005d87
+		usage: usage,
Jan Chaloupka 005d87
+	})
Jan Chaloupka 005d87
+	fs.fs.Var(value, name, usage)
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) StringVar(p *string, name string, value string, usage string) {
Jan Chaloupka 005d87
+	fs.flags[fs.lastGroup] = append(fs.flags[fs.lastGroup], flagInfo{
Jan Chaloupka 005d87
+		value: (*stringValue)(&value),
Jan Chaloupka 005d87
+		name:  name,
Jan Chaloupka 005d87
+		usage: usage,
Jan Chaloupka 005d87
+	})
Jan Chaloupka 005d87
+	fs.fs.StringVar(p, name, value, usage)
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+// -- int Value
Jan Chaloupka 005d87
+type intValue int
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) UintVar(p *uint, name string, value uint, usage string) {
Jan Chaloupka 005d87
+	fs.flags[fs.lastGroup] = append(fs.flags[fs.lastGroup], flagInfo{
Jan Chaloupka 005d87
+		value: (*uintValue)(&value),
Jan Chaloupka 005d87
+		name:  name,
Jan Chaloupka 005d87
+		usage: usage,
Jan Chaloupka 005d87
+	})
Jan Chaloupka 005d87
+	fs.fs.UintVar(p, name, value, usage)
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
Jan Chaloupka 005d87
+	fs.flags[fs.lastGroup] = append(fs.flags[fs.lastGroup], flagInfo{
Jan Chaloupka 005d87
+		value: (*uint64Value)(&value),
Jan Chaloupka 005d87
+		name:  name,
Jan Chaloupka 005d87
+		usage: usage,
Jan Chaloupka 005d87
+	})
Jan Chaloupka 005d87
+	fs.fs.Uint64Var(p, name, value, usage)
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) IntVar(p *int, name string, value int, usage string) {
Jan Chaloupka 005d87
+	fs.flags[fs.lastGroup] = append(fs.flags[fs.lastGroup], flagInfo{
Jan Chaloupka 005d87
+		value: (*intValue)(&value),
Jan Chaloupka 005d87
+		name:  name,
Jan Chaloupka 005d87
+		usage: usage,
Jan Chaloupka 005d87
+	})
Jan Chaloupka 005d87
+	fs.fs.IntVar(p, name, value, usage)
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) Int64Var(p *int64, name string, value int64, usage string) {
Jan Chaloupka 005d87
+	fs.flags[fs.lastGroup] = append(fs.flags[fs.lastGroup], flagInfo{
Jan Chaloupka 005d87
+		value: (*int64Value)(&value),
Jan Chaloupka 005d87
+		name:  name,
Jan Chaloupka 005d87
+		usage: usage,
Jan Chaloupka 005d87
+	})
Jan Chaloupka 005d87
+	fs.fs.Int64Var(p, name, value, usage)
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
Jan Chaloupka 005d87
+	fs.flags[fs.lastGroup] = append(fs.flags[fs.lastGroup], flagInfo{
Jan Chaloupka 005d87
+		value: (*durationValue)(&value),
Jan Chaloupka 005d87
+		name:  name,
Jan Chaloupka 005d87
+		usage: usage,
Jan Chaloupka 005d87
+	})
Jan Chaloupka 005d87
+	fs.fs.DurationVar(p, name, value, usage)
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) BoolVar(p *bool, name string, value bool, usage string) {
Jan Chaloupka 005d87
+	fs.flags[fs.lastGroup] = append(fs.flags[fs.lastGroup], flagInfo{
Jan Chaloupka 005d87
+		value: (*boolValue)(&value),
Jan Chaloupka 005d87
+		name:  name,
Jan Chaloupka 005d87
+		usage: usage,
Jan Chaloupka 005d87
+	})
Jan Chaloupka 005d87
+	fs.fs.BoolVar(p, name, value, usage)
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
+
Jan Chaloupka 005d87
+func (fs *FakeFlagSet) GenMan() {
Jan Chaloupka 005d87
+	fmt.Printf(".TH \"ETCD\" \"1\" \" etcd User Manuals\" \"Etcd contributors\" \"Nov 2017\"  \"\"\n")
Jan Chaloupka 005d87
+	fmt.Printf(".SH NAME:\netcd - Distributed reliable key-value store for the most critical data of a distributed system\n\n")
Jan Chaloupka 005d87
+	fmt.Printf(".SH USAGE:\netcd [flags]\n\n")
Jan Chaloupka 005d87
+	fmt.Printf(".SH DESCRIPTION:\nEtcd is a distributed key-value store designed to reliably and quickly preserve and provide access to critical data. It enables reliable distributed coordination through distributed locking, leader elections, and write barriers. An etcd cluster is intended for high availability and permanent data storage and retrieval.\n\n")
Jan Chaloupka 005d87
+	fmt.Printf(".SH GENERAL OPTIONS\n\n")
Jan Chaloupka 005d87
+	for _, group := range fs.groups {
Jan Chaloupka 005d87
+		fmt.Printf(".I %v flags\n\n", strings.Title(group))
Jan Chaloupka 005d87
+		for _, flag := range fs.flags[group] {
Jan Chaloupka 005d87
+			var flagstr string
Jan Chaloupka 005d87
+			if len(flag.name) == 1 {
Jan Chaloupka 005d87
+				flagstr = "-" + flag.name
Jan Chaloupka 005d87
+			} else {
Jan Chaloupka 005d87
+				flagstr = "--" + flag.name
Jan Chaloupka 005d87
+			}
Jan Chaloupka 005d87
+			fmt.Printf(".RS\n\\fB%v %v\\fP\n      %v\n\n.RE\n", flagstr, flag.value.String(), flag.usage)
Jan Chaloupka 005d87
+		}
Jan Chaloupka 005d87
+	}
Jan Chaloupka 005d87
+	fmt.Printf(".SH SEE ALSO:\n\\fBetcdctl(1)\\fP, \\fBetcdctl2(1)\\fP, \\fBetcdctl3(1)\\fP\n\n")
Jan Chaloupka 005d87
+}
Jan Chaloupka 005d87
-- 
Jan Chaloupka 005d87
2.7.5
Jan Chaloupka 005d87