mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
ctlv3: add 'endpoint hashkv' command
Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
This commit is contained in:
parent
9982cd0528
commit
5176b63fa0
@ -641,6 +641,49 @@ Get the status for all endpoints in the cluster associated with the default endp
|
|||||||
+------------------------+------------------+----------------+---------+-----------+-----------+------------+
|
+------------------------+------------------+----------------+---------+-----------+-----------+------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### ENDPOINT HASHKV
|
||||||
|
|
||||||
|
ENDPOINT HASHKV fetches the hash of the key-value store of an endpoint.
|
||||||
|
|
||||||
|
#### Output
|
||||||
|
|
||||||
|
##### Simple format
|
||||||
|
|
||||||
|
Prints a humanized table of each endpoint URL and KV history hash.
|
||||||
|
|
||||||
|
##### JSON format
|
||||||
|
|
||||||
|
Prints a line of JSON encoding each endpoint URL and KV history hash.
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
|
||||||
|
Get the hash for the default endpoint:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./etcdctl endpoint hashkv
|
||||||
|
# 127.0.0.1:2379, 1084519789
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the status for the default endpoint as JSON:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./etcdctl -w json endpoint hashkv
|
||||||
|
# [{"Endpoint":"127.0.0.1:2379","Hash":{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":1,"raft_term":3},"hash":1084519789,"compact_revision":-1}}]
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the status for all endpoints in the cluster associated with the default endpoint:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./etcdctl -w table endpoint --cluster hashkv
|
||||||
|
+------------------------+------------+
|
||||||
|
| ENDPOINT | HASH |
|
||||||
|
+------------------------+------------+
|
||||||
|
| http://127.0.0.1:12379 | 1084519789 |
|
||||||
|
| http://127.0.0.1:22379 | 1084519789 |
|
||||||
|
| http://127.0.0.1:32379 | 1084519789 |
|
||||||
|
+------------------------+------------+
|
||||||
|
```
|
||||||
|
|
||||||
### ALARM \<subcommand\>
|
### ALARM \<subcommand\>
|
||||||
|
|
||||||
Provides alarm related commands
|
Provides alarm related commands
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var epClusterEndpoints bool
|
var epClusterEndpoints bool
|
||||||
|
var epHashKVRev int64
|
||||||
|
|
||||||
// NewEndpointCommand returns the cobra command for "endpoint".
|
// NewEndpointCommand returns the cobra command for "endpoint".
|
||||||
func NewEndpointCommand() *cobra.Command {
|
func NewEndpointCommand() *cobra.Command {
|
||||||
@ -39,6 +40,7 @@ func NewEndpointCommand() *cobra.Command {
|
|||||||
ec.PersistentFlags().BoolVar(&epClusterEndpoints, "cluster", false, "use all endpoints from the cluster member list")
|
ec.PersistentFlags().BoolVar(&epClusterEndpoints, "cluster", false, "use all endpoints from the cluster member list")
|
||||||
ec.AddCommand(newEpHealthCommand())
|
ec.AddCommand(newEpHealthCommand())
|
||||||
ec.AddCommand(newEpStatusCommand())
|
ec.AddCommand(newEpStatusCommand())
|
||||||
|
ec.AddCommand(newEpHashKVCommand())
|
||||||
|
|
||||||
return ec
|
return ec
|
||||||
}
|
}
|
||||||
@ -64,6 +66,16 @@ The items in the lists are endpoint, ID, version, db size, is leader, raft term,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newEpHashKVCommand() *cobra.Command {
|
||||||
|
hc := &cobra.Command{
|
||||||
|
Use: "hashkv",
|
||||||
|
Short: "Prints the KV history hash for each endpoint in --endpoints",
|
||||||
|
Run: epHashKVCommandFunc,
|
||||||
|
}
|
||||||
|
hc.PersistentFlags().Int64Var(&epHashKVRev, "rev", 0, "maximum revision to hash (default: all revisions)")
|
||||||
|
return hc
|
||||||
|
}
|
||||||
|
|
||||||
// epHealthCommandFunc executes the "endpoint-health" command.
|
// epHealthCommandFunc executes the "endpoint-health" command.
|
||||||
func epHealthCommandFunc(cmd *cobra.Command, args []string) {
|
func epHealthCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
flags.SetPflagsFromEnv("ETCDCTL", cmd.InheritedFlags())
|
flags.SetPflagsFromEnv("ETCDCTL", cmd.InheritedFlags())
|
||||||
@ -151,6 +163,35 @@ func epStatusCommandFunc(cmd *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type epHashKV struct {
|
||||||
|
Ep string `json:"Endpoint"`
|
||||||
|
Resp *v3.HashKVResponse `json:"HashKV"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func epHashKVCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
|
c := mustClientFromCmd(cmd)
|
||||||
|
|
||||||
|
hashList := []epHashKV{}
|
||||||
|
var err error
|
||||||
|
for _, ep := range endpointsFromCluster(cmd) {
|
||||||
|
ctx, cancel := commandCtx(cmd)
|
||||||
|
resp, serr := c.HashKV(ctx, ep, epHashKVRev)
|
||||||
|
cancel()
|
||||||
|
if serr != nil {
|
||||||
|
err = serr
|
||||||
|
fmt.Fprintf(os.Stderr, "Failed to get the hash of endpoint %s (%v)\n", ep, serr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hashList = append(hashList, epHashKV{Ep: ep, Resp: resp})
|
||||||
|
}
|
||||||
|
|
||||||
|
display.EndpointHashKV(hashList)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ExitWithError(ExitError, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func endpointsFromCluster(cmd *cobra.Command) []string {
|
func endpointsFromCluster(cmd *cobra.Command) []string {
|
||||||
if !epClusterEndpoints {
|
if !epClusterEndpoints {
|
||||||
endpoints, err := cmd.Flags().GetStringSlice("endpoints")
|
endpoints, err := cmd.Flags().GetStringSlice("endpoints")
|
||||||
|
@ -43,6 +43,7 @@ type printer interface {
|
|||||||
MemberList(v3.MemberListResponse)
|
MemberList(v3.MemberListResponse)
|
||||||
|
|
||||||
EndpointStatus([]epStatus)
|
EndpointStatus([]epStatus)
|
||||||
|
EndpointHashKV([]epHashKV)
|
||||||
MoveLeader(leader, target uint64, r v3.MoveLeaderResponse)
|
MoveLeader(leader, target uint64, r v3.MoveLeaderResponse)
|
||||||
|
|
||||||
Alarm(v3.AlarmResponse)
|
Alarm(v3.AlarmResponse)
|
||||||
@ -146,6 +147,7 @@ func newPrinterUnsupported(n string) printer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *printerUnsupported) EndpointStatus([]epStatus) { p.p(nil) }
|
func (p *printerUnsupported) EndpointStatus([]epStatus) { p.p(nil) }
|
||||||
|
func (p *printerUnsupported) EndpointHashKV([]epHashKV) { p.p(nil) }
|
||||||
func (p *printerUnsupported) DBStatus(dbstatus) { p.p(nil) }
|
func (p *printerUnsupported) DBStatus(dbstatus) { p.p(nil) }
|
||||||
|
|
||||||
func (p *printerUnsupported) MoveLeader(leader, target uint64, r v3.MoveLeaderResponse) { p.p(nil) }
|
func (p *printerUnsupported) MoveLeader(leader, target uint64, r v3.MoveLeaderResponse) { p.p(nil) }
|
||||||
@ -184,6 +186,17 @@ func makeEndpointStatusTable(statusList []epStatus) (hdr []string, rows [][]stri
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeEndpointHashKVTable(hashList []epHashKV) (hdr []string, rows [][]string) {
|
||||||
|
hdr = []string{"endpoint", "hash"}
|
||||||
|
for _, h := range hashList {
|
||||||
|
rows = append(rows, []string{
|
||||||
|
h.Ep,
|
||||||
|
fmt.Sprint(h.Resp.Hash),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func makeDBStatusTable(ds dbstatus) (hdr []string, rows [][]string) {
|
func makeDBStatusTable(ds dbstatus) (hdr []string, rows [][]string) {
|
||||||
hdr = []string{"hash", "revision", "total keys", "total size"}
|
hdr = []string{"hash", "revision", "total keys", "total size"}
|
||||||
rows = append(rows, []string{
|
rows = append(rows, []string{
|
||||||
|
@ -146,6 +146,15 @@ func (p *fieldsPrinter) EndpointStatus(eps []epStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *fieldsPrinter) EndpointHashKV(hs []epHashKV) {
|
||||||
|
for _, h := range hs {
|
||||||
|
p.hdr(h.Resp.Header)
|
||||||
|
fmt.Printf("\"Endpoint\" : %q\n", h.Ep)
|
||||||
|
fmt.Println(`"Hash" :`, h.Resp.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *fieldsPrinter) Alarm(r v3.AlarmResponse) {
|
func (p *fieldsPrinter) Alarm(r v3.AlarmResponse) {
|
||||||
p.hdr(r.Header)
|
p.hdr(r.Header)
|
||||||
for _, a := range r.Alarms {
|
for _, a := range r.Alarms {
|
||||||
|
@ -29,6 +29,7 @@ func newJSONPrinter() printer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *jsonPrinter) EndpointStatus(r []epStatus) { printJSON(r) }
|
func (p *jsonPrinter) EndpointStatus(r []epStatus) { printJSON(r) }
|
||||||
|
func (p *jsonPrinter) EndpointHashKV(r []epHashKV) { printJSON(r) }
|
||||||
func (p *jsonPrinter) DBStatus(r dbstatus) { printJSON(r) }
|
func (p *jsonPrinter) DBStatus(r dbstatus) { printJSON(r) }
|
||||||
|
|
||||||
func printJSON(v interface{}) {
|
func printJSON(v interface{}) {
|
||||||
|
@ -136,6 +136,13 @@ func (s *simplePrinter) EndpointStatus(statusList []epStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *simplePrinter) EndpointHashKV(hashList []epHashKV) {
|
||||||
|
_, rows := makeEndpointHashKVTable(hashList)
|
||||||
|
for _, row := range rows {
|
||||||
|
fmt.Println(strings.Join(row, ", "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *simplePrinter) DBStatus(ds dbstatus) {
|
func (s *simplePrinter) DBStatus(ds dbstatus) {
|
||||||
_, rows := makeDBStatusTable(ds)
|
_, rows := makeDBStatusTable(ds)
|
||||||
for _, row := range rows {
|
for _, row := range rows {
|
||||||
|
@ -44,6 +44,16 @@ func (tp *tablePrinter) EndpointStatus(r []epStatus) {
|
|||||||
table.SetAlignment(tablewriter.ALIGN_RIGHT)
|
table.SetAlignment(tablewriter.ALIGN_RIGHT)
|
||||||
table.Render()
|
table.Render()
|
||||||
}
|
}
|
||||||
|
func (tp *tablePrinter) EndpointHashKV(r []epHashKV) {
|
||||||
|
hdr, rows := makeEndpointHashKVTable(r)
|
||||||
|
table := tablewriter.NewWriter(os.Stdout)
|
||||||
|
table.SetHeader(hdr)
|
||||||
|
for _, row := range rows {
|
||||||
|
table.Append(row)
|
||||||
|
}
|
||||||
|
table.SetAlignment(tablewriter.ALIGN_RIGHT)
|
||||||
|
table.Render()
|
||||||
|
}
|
||||||
func (tp *tablePrinter) DBStatus(r dbstatus) {
|
func (tp *tablePrinter) DBStatus(r dbstatus) {
|
||||||
hdr, rows := makeDBStatusTable(r)
|
hdr, rows := makeDBStatusTable(r)
|
||||||
table := tablewriter.NewWriter(os.Stdout)
|
table := tablewriter.NewWriter(os.Stdout)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user