-
Notifications
You must be signed in to change notification settings - Fork 125
/
store.go
110 lines (98 loc) · 3.01 KB
/
store.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright 2024 PingCAP, Inc. Licensed under Apache-2.0.
package pdtopo
import (
"context"
"strings"
"github.com/pingcap/log"
"go.uber.org/zap"
"github.com/pingcap/tidb-dashboard/util/client/pdclient"
"github.com/pingcap/tidb-dashboard/util/netutil"
"github.com/pingcap/tidb-dashboard/util/topo"
)
// GetStoreInstances returns TiKV info and TiFlash info.
func GetStoreInstances(ctx context.Context, pdAPI *pdclient.APIClient) ([]topo.TiKVStoreInfo, []topo.TiFlashStoreInfo, error) {
stores, err := pdAPI.HLGetStores(ctx)
if err != nil {
return nil, nil, err
}
tiKVStores := make([]pdclient.GetStoresResponseStore, 0, len(stores))
tiFlashStores := make([]pdclient.GetStoresResponseStore, 0, len(stores))
for _, store := range stores {
isTiFlash := false
for _, label := range store.Labels {
if label.Key == "engine" && label.Value == "tiflash" {
isTiFlash = true
}
}
if isTiFlash {
tiFlashStores = append(tiFlashStores, store)
} else {
tiKVStores = append(tiKVStores, store)
}
}
siTiKV := buildStoreTopology(tiKVStores)
storesTiKV := make([]topo.TiKVStoreInfo, 0, len(siTiKV))
for _, si := range siTiKV {
storesTiKV = append(storesTiKV, topo.TiKVStoreInfo(si))
}
siTiFlash := buildStoreTopology(tiFlashStores)
storesTiFlash := make([]topo.TiFlashStoreInfo, 0, len(siTiFlash))
for _, si := range siTiFlash {
storesTiFlash = append(storesTiFlash, topo.TiFlashStoreInfo(si))
}
return storesTiKV, storesTiFlash, nil
}
func buildStoreTopology(stores []pdclient.GetStoresResponseStore) []topo.StoreInfo {
nodes := make([]topo.StoreInfo, 0, len(stores))
for _, v := range stores {
hostname, port, err := netutil.ParseHostAndPortFromAddress(v.Address)
if err != nil {
log.Warn("Failed to parse store address", zap.Any("store", v))
continue
}
_, statusPort, err := netutil.ParseHostAndPortFromAddress(v.StatusAddress)
if err != nil {
log.Warn("Failed to parse store status address", zap.Any("store", v))
continue
}
// In current TiKV, it's version may not start with 'v',
// so we may need to add a prefix 'v' for it.
version := strings.Trim(v.Version, "\n ")
if !strings.HasPrefix(version, "v") {
version = "v" + version
}
node := topo.StoreInfo{
Version: version,
IP: hostname,
Port: port,
GitHash: v.GitHash,
DeployPath: v.DeployPath,
Status: parseStoreState(v.StateName),
StatusPort: statusPort,
Labels: map[string]string{},
StartTimestamp: v.StartTimestamp,
}
for _, v := range v.Labels {
node.Labels[v.Key] = v.Value
}
nodes = append(nodes, node)
}
return nodes
}
func parseStoreState(state string) topo.CompStatus {
state = strings.Trim(strings.ToLower(state), "\n ")
switch state {
case "up":
return topo.CompStatusUp
case "tombstone":
return topo.CompStatusTombstone
case "offline":
return topo.CompStatusLeaving
case "down":
return topo.CompStatusDown
case "disconnected":
return topo.CompStatusUnreachable
default:
return topo.CompStatusUnreachable
}
}