From cd971a510119f28b093ace6316f00ebd9cacfa2b Mon Sep 17 00:00:00 2001 From: yuzhibotao <52073478+yuzhibotao@users.noreply.github.com> Date: Tue, 17 Nov 2020 11:48:18 +0800 Subject: [PATCH 1/2] Import configuration when migrating a cluster from Ansible (#766) Co-authored-by: SIGSEGV Co-authored-by: Lonng Co-authored-by: Allen Zhong --- components/cluster/command/import.go | 5 + go.mod | 1 + go.sum | 2 + pkg/cluster/ansible/import.go | 165 ++++++++++++++++++++++++- pkg/cluster/ansible/import_test.go | 157 ++++++++++++++++++++--- pkg/cluster/spec/server_config.go | 66 +++++++--- pkg/cluster/spec/server_config_test.go | 82 ++++++++++-- pkg/cluster/spec/spec_test.go | 49 +++++++- pkg/cluster/spec/tikv.go | 12 +- pkg/set/any_set.go | 90 ++++++++++++++ pkg/set/any_set_test.go | 32 +++++ pkg/set/string_set_test.go | 6 +- 12 files changed, 610 insertions(+), 57 deletions(-) create mode 100644 pkg/set/any_set.go create mode 100644 pkg/set/any_set_test.go diff --git a/components/cluster/command/import.go b/components/cluster/command/import.go index 4063fd6cb4..58e8463479 100644 --- a/components/cluster/command/import.go +++ b/components/cluster/command/import.go @@ -128,6 +128,11 @@ func newImportCmd() *cobra.Command { return err } + // copy config detail to meta file + if err = ansible.LoadConfig(clsName, clsMeta); err != nil { + return err + } + if err = spec.SaveClusterMeta(clsName, clsMeta); err != nil { return err } diff --git a/go.mod b/go.mod index bfeea173d8..7ac8dd8635 100644 --- a/go.mod +++ b/go.mod @@ -79,6 +79,7 @@ require ( gopkg.in/mattn/go-runewidth.v0 v0.0.4 // indirect gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect gopkg.in/yaml.v2 v2.2.8 + gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 honnef.co/go/tools v0.0.1-2020.1.4 // indirect sigs.k8s.io/yaml v1.2.0 // indirect software.sslmate.com/src/go-pkcs12 v0.0.0-20200619203921-c9ed90bd32dc diff --git a/go.sum b/go.sum index e60e089def..71f33b3a6f 100644 --- a/go.sum +++ b/go.sum @@ -1194,6 +1194,8 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/cluster/ansible/import.go b/pkg/cluster/ansible/import.go index af5005226e..b44780d1b7 100644 --- a/pkg/cluster/ansible/import.go +++ b/pkg/cluster/ansible/import.go @@ -18,11 +18,14 @@ import ( "io" "os" "path/filepath" + "reflect" "strconv" + "github.com/BurntSushi/toml" "github.com/pingcap/errors" "github.com/pingcap/tiup/pkg/cluster/spec" "github.com/pingcap/tiup/pkg/logger/log" + "github.com/pingcap/tiup/pkg/set" "github.com/relex/aini" ) @@ -81,11 +84,20 @@ func parseInventoryFile(invFile io.Reader) (string, *spec.ClusterMeta, *aini.Inv clsMeta.Topology.GlobalOptions.DeployDir = grp.Vars["deploy_dir"] // deploy_dir and data_dir of monitored need to be set, otherwise they will be // subdirs of deploy_dir in global options - clsMeta.Topology.MonitoredOptions.DeployDir = clsMeta.Topology.GlobalOptions.DeployDir - clsMeta.Topology.MonitoredOptions.DataDir = filepath.Join( - clsMeta.Topology.MonitoredOptions.DeployDir, - "data", - ) + allSame := uniqueVar("deploy_dir", inventory.Groups["monitored_servers"].Hosts) + if len(allSame) == 1 { + clsMeta.Topology.MonitoredOptions.DeployDir = allSame[0] + clsMeta.Topology.MonitoredOptions.DataDir = filepath.Join( + clsMeta.Topology.MonitoredOptions.DeployDir, + "data", + ) + } else { + clsMeta.Topology.MonitoredOptions.DeployDir = clsMeta.Topology.GlobalOptions.DeployDir + clsMeta.Topology.MonitoredOptions.DataDir = filepath.Join( + clsMeta.Topology.MonitoredOptions.DeployDir, + "data", + ) + } if grp.Vars["process_supervision"] != "systemd" { return "", nil, inventory, errors.New("only support cluster deployed with systemd") @@ -100,6 +112,7 @@ func parseInventoryFile(invFile io.Reader) (string, *spec.ClusterMeta, *aini.Inv } else { return "", nil, inventory, errors.New("no available host in the inventory file") } + return clsName, clsMeta, inventory, err } @@ -113,3 +126,145 @@ func SSHKeyPath() string { return fmt.Sprintf("%s/.ssh/id_rsa", homeDir) } + +func uniqueVar(key string, hosts map[string]*aini.Host) []string { + vars := set.NewStringSet() + for _, h := range hosts { + vars.Insert(h.Vars[key]) + } + return vars.Slice() +} + +// parse config files +func parseConfigFile(cfgfile string) (map[string]interface{}, error) { + srvConfigs := make(map[string]interface{}) + if _, err := toml.DecodeFile(cfgfile, &srvConfigs); err != nil { + return nil, errors.Annotate(err, "decode toml file") + } + return spec.FlattenMap(srvConfigs), nil +} + +func diffConfigs(configs []map[string]interface{}) (global map[string]interface{}, locals []map[string]interface{}) { + global = make(map[string]interface{}) + keySet := set.NewStringSet() + + // parse all configs from file + for _, config := range configs { + locals = append(locals, config) + for k := range config { + keySet.Insert(k) + } + } + + // summary global config + for k := range keySet { + valSet := set.NewAnySet(reflect.DeepEqual) + for _, config := range locals { + valSet.Insert(config[k]) + } + if len(valSet.Slice()) > 1 { + // this key can't be put into global + continue + } + global[k] = valSet.Slice()[0] + } + + // delete global config from local + for _, config := range locals { + for k := range global { + delete(config, k) + } + } + + return +} + +// LoadConfig files to clusterMeta, include tidbservers, tikvservers, pdservers pumpservers and drainerservers +func LoadConfig(clsName string, cls *spec.ClusterMeta) error { + // deal with tidb config + configs := []map[string]interface{}{} + for _, srv := range cls.Topology.TiDBServers { + prefixkey := spec.ComponentTiDB + fname := spec.ClusterPath(clsName, spec.AnsibleImportedConfigPath, fmt.Sprintf("%s-%s-%d.toml", prefixkey, srv.Host, srv.Port)) + if config, err := parseConfigFile(fname); err == nil { + configs = append(configs, config) + } else { + return err + } + } + global, locals := diffConfigs(configs) + cls.Topology.ServerConfigs.TiDB = global + for i, local := range locals { + cls.Topology.TiDBServers[i].Config = local + } + + // deal with tikv config + configs = []map[string]interface{}{} + for _, srv := range cls.Topology.TiKVServers { + prefixkey := spec.ComponentTiKV + fname := spec.ClusterPath(clsName, spec.AnsibleImportedConfigPath, fmt.Sprintf("%s-%s-%d.toml", prefixkey, srv.Host, srv.Port)) + if config, err := parseConfigFile(fname); err == nil { + configs = append(configs, config) + } else { + return err + } + } + global, locals = diffConfigs(configs) + cls.Topology.ServerConfigs.TiKV = global + for i, local := range locals { + cls.Topology.TiKVServers[i].Config = local + } + + // deal with pd config + configs = []map[string]interface{}{} + for _, srv := range cls.Topology.PDServers { + prefixkey := spec.ComponentPD + fname := spec.ClusterPath(clsName, spec.AnsibleImportedConfigPath, fmt.Sprintf("%s-%s-%d.toml", prefixkey, srv.Host, srv.ClientPort)) + if config, err := parseConfigFile(fname); err == nil { + configs = append(configs, config) + } else { + return err + } + } + global, locals = diffConfigs(configs) + cls.Topology.ServerConfigs.PD = global + for i, local := range locals { + cls.Topology.PDServers[i].Config = local + } + + // deal with pump config + configs = []map[string]interface{}{} + for _, srv := range cls.Topology.PumpServers { + prefixkey := spec.ComponentPump + fname := spec.ClusterPath(clsName, spec.AnsibleImportedConfigPath, fmt.Sprintf("%s-%s-%d.toml", prefixkey, srv.Host, srv.Port)) + if config, err := parseConfigFile(fname); err == nil { + configs = append(configs, config) + } else { + return err + } + } + global, locals = diffConfigs(configs) + cls.Topology.ServerConfigs.Pump = global + for i, local := range locals { + cls.Topology.PumpServers[i].Config = local + } + + // deal with drainer config + configs = []map[string]interface{}{} + for _, srv := range cls.Topology.Drainers { + prefixkey := spec.ComponentDrainer + fname := spec.ClusterPath(clsName, spec.AnsibleImportedConfigPath, fmt.Sprintf("%s-%s-%d.toml", prefixkey, srv.Host, srv.Port)) + if config, err := parseConfigFile(fname); err == nil { + configs = append(configs, config) + } else { + return err + } + } + global, locals = diffConfigs(configs) + cls.Topology.ServerConfigs.Drainer = global + for i, local := range locals { + cls.Topology.Drainers[i].Config = local + } + + return nil +} diff --git a/pkg/cluster/ansible/import_test.go b/pkg/cluster/ansible/import_test.go index 018db032ca..a334c3cb0f 100644 --- a/pkg/cluster/ansible/import_test.go +++ b/pkg/cluster/ansible/import_test.go @@ -19,12 +19,13 @@ import ( "os" "path/filepath" "sort" + "strings" "testing" "github.com/creasty/defaults" . "github.com/pingcap/check" "github.com/pingcap/tiup/pkg/cluster/spec" - "gopkg.in/yaml.v2" + "gopkg.in/yaml.v3" ) type ansSuite struct { @@ -36,6 +37,67 @@ func TestAnsible(t *testing.T) { TestingT(t) } +func (s *ansSuite) TestMonitoredDeployDir(c *C) { + r := strings.NewReader(` +[monitored_servers] +172.16.10.1 +172.16.10.2 +172.16.10.3 + +[all:vars] +process_supervision = systemd + `) + + _, clsMeta, _, err := parseInventoryFile(r) + c.Assert(err, IsNil) + c.Assert(clsMeta.Topology.MonitoredOptions.DeployDir, Equals, "") + + r = strings.NewReader(` +[monitored_servers] +172.16.10.1 +172.16.10.2 +172.16.10.3 + +[all:vars] +deploy_dir = /data1/deploy +process_supervision = systemd + `) + + _, clsMeta, _, err = parseInventoryFile(r) + c.Assert(err, IsNil) + c.Assert(clsMeta.Topology.MonitoredOptions.DeployDir, Equals, "/data1/deploy") + + r = strings.NewReader(` +[monitored_servers] +172.16.10.1 deploy_dir=/data/deploy +172.16.10.2 deploy_dir=/data/deploy +172.16.10.3 deploy_dir=/data/deploy + +[all:vars] +deploy_dir = /data1/deploy +process_supervision = systemd + `) + + _, clsMeta, _, err = parseInventoryFile(r) + c.Assert(err, IsNil) + c.Assert(clsMeta.Topology.MonitoredOptions.DeployDir, Equals, "/data/deploy") + + r = strings.NewReader(` +[monitored_servers] +172.16.10.1 deploy_dir=/data/deploy1 +172.16.10.2 deploy_dir=/data/deploy2 +172.16.10.3 deploy_dir=/data/deploy3 + +[all:vars] +deploy_dir = /data1/deploy +process_supervision = systemd + `) + + _, clsMeta, _, err = parseInventoryFile(r) + c.Assert(err, IsNil) + c.Assert(clsMeta.Topology.MonitoredOptions.DeployDir, Equals, "/data1/deploy") +} + func (s *ansSuite) TestParseInventoryFile(c *C) { dir := "test-data" invData, err := os.Open(filepath.Join(dir, "inventory.ini")) @@ -50,21 +112,21 @@ func (s *ansSuite) TestParseInventoryFile(c *C) { c.Assert(clsMeta.User, Equals, "tiops") expected := []byte(`global: - user: tiops - deploy_dir: /home/tiopsimport/ansible-deploy + user: tiops + deploy_dir: /home/tiopsimport/ansible-deploy monitored: - deploy_dir: /home/tiopsimport/ansible-deploy - data_dir: /home/tiopsimport/ansible-deploy/data + deploy_dir: /home/tiopsimport/ansible-deploy + data_dir: /home/tiopsimport/ansible-deploy/data server_configs: - tidb: - binlog.enable: true - tikv: {} - pd: {} - tiflash: {} - tiflash-learner: {} - pump: {} - drainer: {} - cdc: {} + tidb: + binlog.enable: true + tikv: {} + pd: {} + tiflash: {} + tiflash-learner: {} + pump: {} + drainer: {} + cdc: {} tidb_servers: [] tikv_servers: [] tiflash_servers: [] @@ -73,7 +135,6 @@ monitoring_servers: [] `) topo, err := yaml.Marshal(clsMeta.Topology) - fmt.Printf("Got initial topo:\n%s\n", topo) c.Assert(err, IsNil) c.Assert(topo, DeepEquals, expected) } @@ -108,10 +169,8 @@ func (s *ansSuite) TestParseGroupVars(c *C) { sortClusterMeta(&metaFull) sortClusterMeta(&expected) - actual, err := yaml.Marshal(metaFull) + _, err = yaml.Marshal(metaFull) c.Assert(err, IsNil) - fmt.Printf("Got initial meta:\n%s\n", actual) - c.Assert(metaFull, DeepEquals, expected) } @@ -147,3 +206,65 @@ func sortClusterMeta(clsMeta *spec.ClusterMeta) { return clsMeta.Topology.Alertmanagers[i].Host < clsMeta.Topology.Alertmanagers[j].Host }) } + +func withTempFile(content string, fn func(string)) { + file, err := ioutil.TempFile("/tmp", "topology-test") + if err != nil { + panic(fmt.Sprintf("create temp file: %s", err)) + } + defer os.Remove(file.Name()) + + _, err = file.WriteString(content) + if err != nil { + panic(fmt.Sprintf("write temp file: %s", err)) + } + file.Close() + + fn(file.Name()) +} + +func (s *ansSuite) TestParseConfig(c *C) { + // base test + withTempFile(` +a = true + +[b] +c = 1 +d = "\"" +`, func(file string) { + m, err := parseConfigFile(file) + c.Assert(err, IsNil) + c.Assert(m["x"], IsNil) + c.Assert(m["a"], Equals, true) + c.Assert(m["b.c"], Equals, int64(1)) + c.Assert(m["b.d"], Equals, "\"") + }) +} + +func (s *ansSuite) TestDiffConfig(c *C) { + global, locals := diffConfigs([]map[string]interface{}{ + { + "a": true, + "b": 1, + "foo.bar": 1, + }, + { + "a": true, + "b": 2, + "foo.bar": 1, + }, + { + "a": true, + "b": 3, + "foo.bar": 1, + }, + }) + + c.Assert(global["a"], NotNil) + c.Assert(global["b"], IsNil) + c.Assert(global["a"], Equals, true) + c.Assert(global["foo.bar"], Equals, 1) + c.Assert(locals[0]["b"], Equals, 1) + c.Assert(locals[1]["b"], Equals, 2) + c.Assert(locals[2]["b"], Equals, 3) +} diff --git a/pkg/cluster/spec/server_config.go b/pkg/cluster/spec/server_config.go index 0d1de10da3..f657d59eda 100644 --- a/pkg/cluster/spec/server_config.go +++ b/pkg/cluster/spec/server_config.go @@ -70,12 +70,12 @@ func strKeyMap(val interface{}) interface{} { return val } -func flattenKey(key string, val interface{}) (string, interface{}) { +func foldKey(key string, val interface{}) (string, interface{}) { parts := strings.SplitN(key, ".", 2) if len(parts) == 1 { return key, strKeyMap(val) } - subKey, subVal := flattenKey(parts[1], val) + subKey, subVal := foldKey(parts[1], val) return parts[0], map[string]interface{}{ subKey: strKeyMap(subVal), } @@ -99,19 +99,52 @@ func patch(origin map[string]interface{}, key string, val interface{}) { } } -func flattenMap(ms map[string]interface{}) map[string]interface{} { +// FoldMap convert single layer map to multi-layer +func FoldMap(ms map[string]interface{}) map[string]interface{} { + // we flatten map first to deal with the case like: + // a.b: + // c.d: xxx + ms = FlattenMap(ms) result := map[string]interface{}{} for k, v := range ms { - key, val := flattenKey(k, v) + key, val := foldKey(k, v) patch(result, key, val) } return result } +// FlattenMap convert mutil-layer map to single layer +func FlattenMap(ms map[string]interface{}) map[string]interface{} { + result := map[string]interface{}{} + for k, v := range ms { + var sub map[string]interface{} + + if m, ok := v.(map[string]interface{}); ok { + sub = FlattenMap(m) + } else if m, ok := v.(map[interface{}]interface{}); ok { + fixM := map[string]interface{}{} + for k, v := range m { + if sk, ok := k.(string); ok { + fixM[sk] = v + } + } + sub = FlattenMap(fixM) + } else { + result[k] = v + continue + } + + for sk, sv := range sub { + result[k+"."+sk] = sv + } + } + return result +} + func merge(orig map[string]interface{}, overwrites ...map[string]interface{}) (map[string]interface{}, error) { - lhs := flattenMap(orig) + lhs := FoldMap(orig) for _, overwrite := range overwrites { - rhs := flattenMap(overwrite) + rhs := FoldMap(overwrite) for k, v := range rhs { patch(lhs, k, v) } @@ -124,6 +157,7 @@ func GetValueFromPath(m map[string]interface{}, p string) interface{} { ss := strings.Split(p, ".") searchMap := make(map[interface{}]interface{}) + m = FoldMap(m) for k, v := range m { searchMap[k] = v } @@ -140,19 +174,15 @@ func searchValue(m map[interface{}]interface{}, ss []string) interface{} { return m[ss[0]] } - if m[strings.Join(ss, ".")] != nil { - return m[strings.Join(ss, ".")] - } - - for i := l - 1; i > 0; i-- { - key := strings.Join(ss[:i], ".") - if m[key] == nil { - continue + key := ss[0] + if pm, ok := m[key].(map[interface{}]interface{}); ok { + return searchValue(pm, ss[1:]) + } else if pm, ok := m[key].(map[string]interface{}); ok { + searchMap := make(map[interface{}]interface{}) + for k, v := range pm { + searchMap[k] = v } - if pm, ok := m[key].(map[interface{}]interface{}); ok { - return searchValue(pm, ss[i:]) - } - return nil + return searchValue(searchMap, ss[1:]) } return nil diff --git a/pkg/cluster/spec/server_config_test.go b/pkg/cluster/spec/server_config_test.go index ab390934ea..a6dbd5613b 100644 --- a/pkg/cluster/spec/server_config_test.go +++ b/pkg/cluster/spec/server_config_test.go @@ -41,15 +41,13 @@ func (s *configSuite) TestGetValueFromPath(c *check.C) { server_configs: tidb: a.b.c.d: 1 - a: - b: - c: - d: 2 a.b: c.e: 3 a.b.c: f: 4 - h.i.j.k: [1, 2, 3] + h.i.j.k: [1, 2, 4] + e: + f: true `) topo := new(Specification) @@ -58,7 +56,77 @@ server_configs: c.Assert(err, check.IsNil) c.Assert(GetValueFromPath(topo.ServerConfigs.TiDB, "a.b.c.d"), check.Equals, 1) - c.Assert(GetValueFromPath(topo.ServerConfigs.TiDB, "a.b.c.e"), check.Equals, nil) + c.Assert(GetValueFromPath(topo.ServerConfigs.TiDB, "a.b.c.e"), check.Equals, 3) c.Assert(GetValueFromPath(topo.ServerConfigs.TiDB, "a.b.c.f"), check.Equals, 4) - c.Assert(GetValueFromPath(topo.ServerConfigs.TiDB, "h.i.j.k"), check.DeepEquals, []interface{}{1, 2, 3}) + c.Assert(GetValueFromPath(topo.ServerConfigs.TiDB, "h.i.j.k"), check.DeepEquals, []interface{}{1, 2, 4}) + c.Assert(GetValueFromPath(topo.ServerConfigs.TiDB, "e.f"), check.Equals, true) +} + +func (s *configSuite) TestFlattenMap(c *check.C) { + var ( + m map[string]interface{} + r map[string]interface{} + ) + + m = map[string]interface{}{ + "a": 1, + "b": map[string]interface{}{ + "c": 2, + }, + "d.e": 3, + "f.g": map[string]interface{}{ + "h": 4, + "i": 5, + }, + "j": []int{6, 7}, + } + r = FlattenMap(m) + c.Assert(r["a"], check.Equals, 1) + c.Assert(r["b.c"], check.Equals, 2) + c.Assert(r["d.e"], check.Equals, 3) + c.Assert(r["f.g.h"], check.Equals, 4) + c.Assert(r["f.g.i"], check.Equals, 5) + c.Assert(r["j"], check.DeepEquals, []int{6, 7}) +} + +func (s *configSuite) TestFoldMap(c *check.C) { + var ( + m map[string]interface{} + r map[string]interface{} + ) + + m = map[string]interface{}{ + "a": 1, + "b.c": 2, + "b.d": 3, + "e.f": map[string]interface{}{ + "g.h": 4, + }, + "i": map[string]interface{}{ + "j.k": 5, + "l": 6, + }, + } + + r = FoldMap(m) + c.Assert(r, check.DeepEquals, map[string]interface{}{ + "a": 1, + "b": map[string]interface{}{ + "c": 2, + "d": 3, + }, + "e": map[string]interface{}{ + "f": map[string]interface{}{ + "g": map[string]interface{}{ + "h": 4, + }, + }, + }, + "i": map[string]interface{}{ + "j": map[string]interface{}{ + "k": 5, + }, + "l": 6, + }, + }) } diff --git a/pkg/cluster/spec/spec_test.go b/pkg/cluster/spec/spec_test.go index e40f9c2f67..eb91fbb7a2 100644 --- a/pkg/cluster/spec/spec_test.go +++ b/pkg/cluster/spec/spec_test.go @@ -171,7 +171,7 @@ tidb_servers: }, }, } - got := flattenMap(topo.ServerConfigs.TiDB) + got := FoldMap(topo.ServerConfigs.TiDB) c.Assert(got, DeepEquals, expected) buf := &bytes.Buffer{} err = toml.NewEncoder(buf).Encode(expected) @@ -199,7 +199,7 @@ tidb_servers: }, }, } - got = flattenMap(topo.TiDBServers[0].Config) + got = FoldMap(topo.TiDBServers[0].Config) c.Assert(err, IsNil) c.Assert(got, DeepEquals, expected) @@ -213,7 +213,7 @@ tidb_servers: }, }, } - got = flattenMap(topo.TiDBServers[1].Config) + got = FoldMap(topo.TiDBServers[1].Config) c.Assert(err, IsNil) c.Assert(got, DeepEquals, expected) } @@ -243,7 +243,7 @@ tikv_servers: }, }, } - got := flattenMap(topo.TiKVServers[0].Config) + got := FoldMap(topo.TiKVServers[0].Config) c.Assert(err, IsNil) c.Assert(got, DeepEquals, expected) } @@ -471,6 +471,47 @@ item7 = 700 c.Assert(string(merge2), DeepEquals, expected) } +func (s *metaSuiteTopo) TestTiKVLabels(c *C) { + spec := Specification{} + err := yaml.Unmarshal([]byte(` +tikv_servers: + - host: 172.16.5.138 + config: + server.labels: + dc: dc1 + zone: zone1 + host: host1 +`), &spec) + c.Assert(err, IsNil) + labels, err := spec.TiKVServers[0].Labels() + c.Assert(err, IsNil) + c.Assert(labels, DeepEquals, map[string]string{ + "dc": "dc1", + "zone": "zone1", + "host": "host1", + }) + + spec = Specification{} + err = yaml.Unmarshal([]byte(` +tikv_servers: + - host: 172.16.5.138 + config: + server.labels.dc: dc1 + server.labels.zone: zone1 + server.labels.host: host1 +`), &spec) + c.Assert(err, IsNil) + /* + labels, err = spec.TiKVServers[0].Labels() + c.Assert(err, IsNil) + c.Assert(labels, DeepEquals, map[string]string{ + "dc": "dc1", + "zone": "zone1", + "host": "host1", + }) + */ +} + func (s *metaSuiteTopo) TestLocationLabels(c *C) { spec := Specification{} diff --git a/pkg/cluster/spec/tikv.go b/pkg/cluster/spec/tikv.go index e11251aa8f..8019dc6ea2 100644 --- a/pkg/cluster/spec/tikv.go +++ b/pkg/cluster/spec/tikv.go @@ -124,8 +124,16 @@ func (s TiKVSpec) IsImported() bool { func (s TiKVSpec) Labels() (map[string]string, error) { lbs := make(map[string]string) - if serverLbs := GetValueFromPath(s.Config, "server.labels"); serverLbs != nil { - for k, v := range serverLbs.(map[interface{}]interface{}) { + if serverLabels := GetValueFromPath(s.Config, "server.labels"); serverLabels != nil { + m := map[interface{}]interface{}{} + if sm, ok := serverLabels.(map[string]interface{}); ok { + for k, v := range sm { + m[k] = v + } + } else if im, ok := serverLabels.(map[interface{}]interface{}); ok { + m = im + } + for k, v := range m { key, ok := k.(string) if !ok { return nil, errors.Errorf("TiKV label name %v is not a string, check the instance: %s:%d", k, s.Host, s.GetMainPort()) diff --git a/pkg/set/any_set.go b/pkg/set/any_set.go new file mode 100644 index 0000000000..2815d9cacc --- /dev/null +++ b/pkg/set/any_set.go @@ -0,0 +1,90 @@ +// Copyright 2020 PingCAP, Inc. +// +// 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, +// See the License for the specific language governing permissions and +// limitations under the License. + +package set + +// AnySet is a set stores interface{} +type AnySet struct { + eq func(a interface{}, b interface{}) bool + slice []interface{} +} + +// NewAnySet builds a AnySet +func NewAnySet(eq func(a interface{}, b interface{}) bool, aa ...interface{}) *AnySet { + slice := []interface{}{} +out: + for _, a := range aa { + for _, b := range slice { + if eq(a, b) { + continue out + } + } + slice = append(slice, a) + } + return &AnySet{eq, slice} +} + +// Exist checks whether `val` exists in `s`. +func (s *AnySet) Exist(val interface{}) bool { + for _, a := range s.slice { + if s.eq(a, val) { + return true + } + } + return false +} + +// Insert inserts `val` into `s`. +func (s *AnySet) Insert(val interface{}) { + if !s.Exist(val) { + s.slice = append(s.slice, val) + } +} + +// Intersection returns the intersection of two sets +func (s *AnySet) Intersection(rhs *AnySet) *AnySet { + newSet := NewAnySet(s.eq) + for elt := range rhs.slice { + if s.Exist(elt) { + newSet.Insert(elt) + } + } + return newSet +} + +// Remove removes `val` from `s` +func (s *AnySet) Remove(val interface{}) { + for i, a := range s.slice { + if s.eq(a, val) { + s.slice = append(s.slice[:i], s.slice[i+1:]...) + return + } + } +} + +// Difference returns the difference of two sets +func (s *AnySet) Difference(rhs *AnySet) *AnySet { + newSet := NewAnySet(s.eq) + diffSet := NewAnySet(s.eq, rhs.slice...) + for elt := range s.slice { + if !diffSet.Exist(elt) { + newSet.Insert(elt) + } + } + return newSet +} + +// Slice converts the set to a slice +func (s *AnySet) Slice() []interface{} { + return append([]interface{}{}, s.slice...) +} diff --git a/pkg/set/any_set_test.go b/pkg/set/any_set_test.go new file mode 100644 index 0000000000..fbca880cba --- /dev/null +++ b/pkg/set/any_set_test.go @@ -0,0 +1,32 @@ +// Copyright 2020 PingCAP, Inc. +// +// 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, +// See the License for the specific language governing permissions and +// limitations under the License. + +package set + +import ( + "reflect" + + "github.com/pingcap/check" +) + +func (s *setTestSuite) TestAnySet(c *check.C) { + set := NewAnySet(reflect.DeepEqual) + set.Insert(true) + set.Insert(9527) + + c.Assert(set.slice[0], check.DeepEquals, true) + c.Assert(set.Slice()[0], check.DeepEquals, true) + + c.Assert(set.slice[1], check.DeepEquals, 9527) + c.Assert(set.Slice()[1], check.DeepEquals, 9527) +} diff --git a/pkg/set/string_set_test.go b/pkg/set/string_set_test.go index eec5da0b55..1af63c8be9 100644 --- a/pkg/set/string_set_test.go +++ b/pkg/set/string_set_test.go @@ -20,15 +20,15 @@ import ( "github.com/pingcap/check" ) -var _ = check.Suite(&stringSetTestSuite{}) +var _ = check.Suite(&setTestSuite{}) -type stringSetTestSuite struct{} +type setTestSuite struct{} func TestNewStringSet(t *testing.T) { check.TestingT(t) } -func (s *stringSetTestSuite) TestStringSet(c *check.C) { +func (s *setTestSuite) TestStringSet(c *check.C) { set := NewStringSet() vals := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"} for i := range vals { From f9591eb9be013fb74a2626bdf873b5238e926e31 Mon Sep 17 00:00:00 2001 From: 9547 Date: Tue, 17 Nov 2020 12:32:53 +0800 Subject: [PATCH 2/2] feat(node_exporter): add --collector.buddyinfo (#904) --- pkg/cluster/embed/autogen_pkger.go | 2 +- templates/scripts/run_node_exporter.sh.tpl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/cluster/embed/autogen_pkger.go b/pkg/cluster/embed/autogen_pkger.go index e574df3297..60af7d427a 100644 --- a/pkg/cluster/embed/autogen_pkger.go +++ b/pkg/cluster/embed/autogen_pkger.go @@ -33,7 +33,7 @@ func init() { autogenFiles["/templates/scripts/run_dm-worker.sh.tpl"] = "IyEvYmluL2Jhc2gKc2V0IC1lCgojIFdBUk5JTkc6IFRoaXMgZmlsZSB3YXMgYXV0by1nZW5lcmF0ZWQuIERvIG5vdCBlZGl0IQojICAgICAgICAgIEFsbCB5b3VyIGVkaXQgbWlnaHQgYmUgb3ZlcndyaXR0ZW4hCkRFUExPWV9ESVI9e3suRGVwbG95RGlyfX0KCmNkICIke0RFUExPWV9ESVJ9IiB8fCBleGl0IDEKCnt7LSBkZWZpbmUgIk1hc3Rlckxpc3QifX0KICB7ey0gcmFuZ2UgJGlkeCwgJG1hc3RlciA6PSAufX0KICAgIHt7LSBpZiBlcSAkaWR4IDB9fQogICAgICB7ey0gJG1hc3Rlci5JUH19Ont7JG1hc3Rlci5Qb3J0fX0KICAgIHt7LSBlbHNlIC19fQogICAgICAse3skbWFzdGVyLklQfX06e3skbWFzdGVyLlBvcnR9fQogICAge3stIGVuZH19CiAge3stIGVuZH19Cnt7LSBlbmR9fQoKe3stIGlmIC5OdW1hTm9kZX19CmV4ZWMgbnVtYWN0bCAtLWNwdW5vZGViaW5kPXt7Lk51bWFOb2RlfX0gLS1tZW1iaW5kPXt7Lk51bWFOb2RlfX0gYmluL2RtLXdvcmtlci9kbS13b3JrZXIgXAp7ey0gZWxzZX19CmV4ZWMgYmluL2RtLXdvcmtlci9kbS13b3JrZXIgXAp7ey0gZW5kfX0KICAgIC0tbmFtZT0ie3suTmFtZX19IiBcCiAgICAtLXdvcmtlci1hZGRyPSIwLjAuMC4wOnt7LlBvcnR9fSIgXAogICAgLS1hZHZlcnRpc2UtYWRkcj0ie3suSVB9fTp7ey5Qb3J0fX0iIFwKICAgIC0tbG9nLWZpbGU9Int7LkxvZ0Rpcn19L2RtLXdvcmtlci5sb2ciIFwKICAgIC0tam9pbj0ie3t0ZW1wbGF0ZSAiTWFzdGVyTGlzdCIgLkVuZHBvaW50c319IiBcCiAgICAtLWNvbmZpZz1jb25mL2RtLXdvcmtlci50b21sID4+ICJ7ey5Mb2dEaXJ9fS9kbS13b3JrZXJfc3Rkb3V0LmxvZyIgMj4+ICJ7ey5Mb2dEaXJ9fS9kbS13b3JrZXJfc3RkZXJyLmxvZyIK" autogenFiles["/templates/scripts/run_drainer.sh.tpl"] = "IyEvYmluL2Jhc2gKc2V0IC1lCgojIFdBUk5JTkc6IFRoaXMgZmlsZSB3YXMgYXV0by1nZW5lcmF0ZWQuIERvIG5vdCBlZGl0IQojICAgICAgICAgIEFsbCB5b3VyIGVkaXQgbWlnaHQgYmUgb3ZlcndyaXR0ZW4hCkRFUExPWV9ESVI9e3suRGVwbG95RGlyfX0KCmNkICIke0RFUExPWV9ESVJ9IiB8fCBleGl0IDEKCnt7LSBkZWZpbmUgIlBETGlzdCJ9fQogIHt7LSByYW5nZSAkaWR4LCAkcGQgOj0gLn19CiAgICB7ey0gaWYgZXEgJGlkeCAwfX0KICAgICAge3stICRwZC5TY2hlbWV9fTovL3t7JHBkLklQfX06e3skcGQuQ2xpZW50UG9ydH19CiAgICB7ey0gZWxzZSAtfX0KICAgICAgLHt7LSAkcGQuU2NoZW1lfX06Ly97eyRwZC5JUH19Ont7JHBkLkNsaWVudFBvcnR9fQogICAge3stIGVuZH19CiAge3stIGVuZH19Cnt7LSBlbmR9fQoKe3stIGlmIC5OdW1hTm9kZX19CmV4ZWMgbnVtYWN0bCAtLWNwdW5vZGViaW5kPXt7Lk51bWFOb2RlfX0gLS1tZW1iaW5kPXt7Lk51bWFOb2RlfX0gYmluL2RyYWluZXIgXAp7ey0gZWxzZX19CmV4ZWMgYmluL2RyYWluZXIgXAp7ey0gZW5kfX0KICAgIC0tbm9kZS1pZD0ie3suTm9kZUlEfX0iIFwKICAgIC0tYWRkcj0ie3suSVB9fTp7ey5Qb3J0fX0iIFwKICAgIC0tcGQtdXJscz0ie3t0ZW1wbGF0ZSAiUERMaXN0IiAuRW5kcG9pbnRzfX0iIFwKICAgIC0tZGF0YS1kaXI9Int7LkRhdGFEaXJ9fSIgXAogICAgLS1sb2ctZmlsZT0ie3suTG9nRGlyfX0vZHJhaW5lci5sb2ciIFwKICAgIC0tY29uZmlnPWNvbmYvZHJhaW5lci50b21sIFwKICAgIC0taW5pdGlhbC1jb21taXQtdHM9Int7LkNvbW1pdFRzfX0iIDI+PiAie3suTG9nRGlyfX0vZHJhaW5lcl9zdGRlcnIubG9nIgo=" autogenFiles["/templates/scripts/run_grafana.sh.tpl"] = "IyEvYmluL2Jhc2gKc2V0IC1lCgojIFdBUk5JTkc6IFRoaXMgZmlsZSB3YXMgYXV0by1nZW5lcmF0ZWQuIERvIG5vdCBlZGl0IQojICAgICAgICAgIEFsbCB5b3VyIGVkaXQgbWlnaHQgYmUgb3ZlcndyaXR0ZW4hCkRFUExPWV9ESVI9e3suRGVwbG95RGlyfX0KY2QgIiR7REVQTE9ZX0RJUn0iIHx8IGV4aXQgMQoKTEFORz1lbl9VUy5VVEYtOCBcCnt7LSBpZiAuTnVtYU5vZGV9fQpleGVjIG51bWFjdGwgLS1jcHVub2RlYmluZD17ey5OdW1hTm9kZX19IC0tbWVtYmluZD17ey5OdW1hTm9kZX19IGJpbi9iaW4vZ3JhZmFuYS1zZXJ2ZXIgXAp7ey0gZWxzZX19CmV4ZWMgYmluL2Jpbi9ncmFmYW5hLXNlcnZlciBcCnt7LSBlbmR9fQogICAgLS1ob21lcGF0aD0ie3suRGVwbG95RGlyfX0vYmluIiBcCiAgICAtLWNvbmZpZz0ie3suRGVwbG95RGlyfX0vY29uZi9ncmFmYW5hLmluaSIK" - autogenFiles["/templates/scripts/run_node_exporter.sh.tpl"] = "IyEvYmluL2Jhc2gKc2V0IC1lCgojIFdBUk5JTkc6IFRoaXMgZmlsZSB3YXMgYXV0by1nZW5lcmF0ZWQuIERvIG5vdCBlZGl0IQojICAgICAgICAgIEFsbCB5b3VyIGVkaXQgbWlnaHQgYmUgb3ZlcndyaXR0ZW4hCkRFUExPWV9ESVI9e3suRGVwbG95RGlyfX0KY2QgIiR7REVQTE9ZX0RJUn0iIHx8IGV4aXQgMQoKZXhlYyA+ID4odGVlIC1pIC1hICJ7ey5Mb2dEaXJ9fS9ub2RlX2V4cG9ydGVyLmxvZyIpCmV4ZWMgMj4mMQoKe3stIGlmIC5OdW1hTm9kZX19CmV4ZWMgbnVtYWN0bCAtLWNwdW5vZGViaW5kPXt7Lk51bWFOb2RlfX0gLS1tZW1iaW5kPXt7Lk51bWFOb2RlfX0gYmluL25vZGVfZXhwb3J0ZXIvbm9kZV9leHBvcnRlciBcCnt7LSBlbHNlfX0KZXhlYyBiaW4vbm9kZV9leHBvcnRlci9ub2RlX2V4cG9ydGVyIFwKe3stIGVuZH19CiAgICAtLXdlYi5saXN0ZW4tYWRkcmVzcz0iOnt7LlBvcnR9fSIgXAogICAgLS1jb2xsZWN0b3IudGNwc3RhdCBcCiAgICAtLWNvbGxlY3Rvci5zeXN0ZW1kIFwKICAgIC0tY29sbGVjdG9yLm1vdW50c3RhdHMgXAogICAgLS1jb2xsZWN0b3IubWVtaW5mb19udW1hIFwKICAgIC0tY29sbGVjdG9yLmludGVycnVwdHMgXAogICAgLS1jb2xsZWN0b3Iudm1zdGF0LmZpZWxkcz0iXi4qIiBcCiAgICAtLWxvZy5sZXZlbD0iaW5mbyIK" + autogenFiles["/templates/scripts/run_node_exporter.sh.tpl"] = "IyEvYmluL2Jhc2gKc2V0IC1lCgojIFdBUk5JTkc6IFRoaXMgZmlsZSB3YXMgYXV0by1nZW5lcmF0ZWQuIERvIG5vdCBlZGl0IQojICAgICAgICAgIEFsbCB5b3VyIGVkaXQgbWlnaHQgYmUgb3ZlcndyaXR0ZW4hCkRFUExPWV9ESVI9e3suRGVwbG95RGlyfX0KY2QgIiR7REVQTE9ZX0RJUn0iIHx8IGV4aXQgMQoKZXhlYyA+ID4odGVlIC1pIC1hICJ7ey5Mb2dEaXJ9fS9ub2RlX2V4cG9ydGVyLmxvZyIpCmV4ZWMgMj4mMQoKe3stIGlmIC5OdW1hTm9kZX19CmV4ZWMgbnVtYWN0bCAtLWNwdW5vZGViaW5kPXt7Lk51bWFOb2RlfX0gLS1tZW1iaW5kPXt7Lk51bWFOb2RlfX0gYmluL25vZGVfZXhwb3J0ZXIvbm9kZV9leHBvcnRlciBcCnt7LSBlbHNlfX0KZXhlYyBiaW4vbm9kZV9leHBvcnRlci9ub2RlX2V4cG9ydGVyIFwKe3stIGVuZH19CiAgICAtLXdlYi5saXN0ZW4tYWRkcmVzcz0iOnt7LlBvcnR9fSIgXAogICAgLS1jb2xsZWN0b3IudGNwc3RhdCBcCiAgICAtLWNvbGxlY3Rvci5zeXN0ZW1kIFwKICAgIC0tY29sbGVjdG9yLm1vdW50c3RhdHMgXAogICAgLS1jb2xsZWN0b3IubWVtaW5mb19udW1hIFwKICAgIC0tY29sbGVjdG9yLmludGVycnVwdHMgXAogICAgLS1jb2xsZWN0b3IuYnVkZHlpbmZvIFwKICAgIC0tY29sbGVjdG9yLnZtc3RhdC5maWVsZHM9Il4uKiIgXAogICAgLS1sb2cubGV2ZWw9ImluZm8iCg==" autogenFiles["/templates/scripts/run_pd.sh.tpl"] = "IyEvYmluL2Jhc2gKc2V0IC1lCgojIFdBUk5JTkc6IFRoaXMgZmlsZSB3YXMgYXV0by1nZW5lcmF0ZWQuIERvIG5vdCBlZGl0IQojICAgICAgICAgIEFsbCB5b3VyIGVkaXQgbWlnaHQgYmUgb3ZlcndyaXR0ZW4hCkRFUExPWV9ESVI9e3suRGVwbG95RGlyfX0KCmNkICIke0RFUExPWV9ESVJ9IiB8fCBleGl0IDEKCnt7LSBkZWZpbmUgIlBETGlzdCJ9fQogIHt7LSByYW5nZSAkaWR4LCAkcGQgOj0gLn19CiAgICB7ey0gaWYgZXEgJGlkeCAwfX0KICAgICAge3stICRwZC5OYW1lfX09e3skcGQuU2NoZW1lfX06Ly97eyRwZC5JUH19Ont7JHBkLlBlZXJQb3J0fX0KICAgIHt7LSBlbHNlIC19fQogICAgICAse3stICRwZC5OYW1lfX09e3skcGQuU2NoZW1lfX06Ly97eyRwZC5JUH19Ont7JHBkLlBlZXJQb3J0fX0KICAgIHt7LSBlbmR9fQogIHt7LSBlbmR9fQp7ey0gZW5kfX0KCnt7LSBpZiAuTnVtYU5vZGV9fQpleGVjIG51bWFjdGwgLS1jcHVub2RlYmluZD17ey5OdW1hTm9kZX19IC0tbWVtYmluZD17ey5OdW1hTm9kZX19IGJpbi9wZC1zZXJ2ZXIgXAp7ey0gZWxzZX19CmV4ZWMgYmluL3BkLXNlcnZlciBcCnt7LSBlbmR9fQogICAgLS1uYW1lPSJ7ey5OYW1lfX0iIFwKICAgIC0tY2xpZW50LXVybHM9Int7LlNjaGVtZX19Oi8ve3suTGlzdGVuSG9zdH19Ont7LkNsaWVudFBvcnR9fSIgXAogICAgLS1hZHZlcnRpc2UtY2xpZW50LXVybHM9Int7LlNjaGVtZX19Oi8ve3suSVB9fTp7ey5DbGllbnRQb3J0fX0iIFwKICAgIC0tcGVlci11cmxzPSJ7ey5TY2hlbWV9fTovL3t7LklQfX06e3suUGVlclBvcnR9fSIgXAogICAgLS1hZHZlcnRpc2UtcGVlci11cmxzPSJ7ey5TY2hlbWV9fTovL3t7LklQfX06e3suUGVlclBvcnR9fSIgXAogICAgLS1kYXRhLWRpcj0ie3suRGF0YURpcn19IiBcCiAgICAtLWluaXRpYWwtY2x1c3Rlcj0ie3t0ZW1wbGF0ZSAiUERMaXN0IiAuRW5kcG9pbnRzfX0iIFwKICAgIC0tY29uZmlnPWNvbmYvcGQudG9tbCBcCiAgICAtLWxvZy1maWxlPSJ7ey5Mb2dEaXJ9fS9wZC5sb2ciIDI+PiAie3suTG9nRGlyfX0vcGRfc3RkZXJyLmxvZyIKICAK" autogenFiles["/templates/scripts/run_pd_scale.sh.tpl"] = "IyEvYmluL2Jhc2gKc2V0IC1lCgojIFdBUk5JTkc6IFRoaXMgZmlsZSB3YXMgYXV0by1nZW5lcmF0ZWQuIERvIG5vdCBlZGl0IQojICAgICAgICAgIEFsbCB5b3VyIGVkaXQgbWlnaHQgYmUgb3ZlcndyaXR0ZW4hCkRFUExPWV9ESVI9e3suRGVwbG95RGlyfX0KCmNkICIke0RFUExPWV9ESVJ9IiB8fCBleGl0IDEKCnt7LSBkZWZpbmUgIlBETGlzdCJ9fQogIHt7LSByYW5nZSAkaWR4LCAkcGQgOj0gLn19CiAgICB7ey0gaWYgZXEgJGlkeCAwfX0KICAgICAge3stICRwZC5TY2hlbWV9fTovL3t7JHBkLklQfX06e3skcGQuQ2xpZW50UG9ydH19CiAgICB7ey0gZWxzZSAtfX0KICAgICAgLHt7LSAkcGQuU2NoZW1lfX06Ly97eyRwZC5JUH19Ont7JHBkLkNsaWVudFBvcnR9fQogICAge3stIGVuZH19CiAge3stIGVuZH19Cnt7LSBlbmR9fQoKe3stIGlmIC5OdW1hTm9kZX19CmV4ZWMgbnVtYWN0bCAtLWNwdW5vZGViaW5kPXt7Lk51bWFOb2RlfX0gLS1tZW1iaW5kPXt7Lk51bWFOb2RlfX0gYmluL3BkLXNlcnZlciBcCnt7LSBlbHNlfX0KZXhlYyBiaW4vcGQtc2VydmVyIFwKe3stIGVuZH19CiAgICAtLW5hbWU9Int7Lk5hbWV9fSIgXAogICAgLS1jbGllbnQtdXJscz0ie3suU2NoZW1lfX06Ly97ey5MaXN0ZW5Ib3N0fX06e3suQ2xpZW50UG9ydH19IiBcCiAgICAtLWFkdmVydGlzZS1jbGllbnQtdXJscz0ie3suU2NoZW1lfX06Ly97ey5JUH19Ont7LkNsaWVudFBvcnR9fSIgXAogICAgLS1wZWVyLXVybHM9Int7LlNjaGVtZX19Oi8ve3suSVB9fTp7ey5QZWVyUG9ydH19IiBcCiAgICAtLWFkdmVydGlzZS1wZWVyLXVybHM9Int7LlNjaGVtZX19Oi8ve3suSVB9fTp7ey5QZWVyUG9ydH19IiBcCiAgICAtLWRhdGEtZGlyPSJ7ey5EYXRhRGlyfX0iIFwKICAgIC0tam9pbj0ie3t0ZW1wbGF0ZSAiUERMaXN0IiAuRW5kcG9pbnRzfX0iIFwKICAgIC0tY29uZmlnPWNvbmYvcGQudG9tbCBcCiAgICAtLWxvZy1maWxlPSJ7ey5Mb2dEaXJ9fS9wZC5sb2ciIDI+PiAie3suTG9nRGlyfX0vcGRfc3RkZXJyLmxvZyIKICAK" autogenFiles["/templates/scripts/run_prometheus.sh.tpl"] = "IyEvYmluL2Jhc2gKc2V0IC1lCgpERVBMT1lfRElSPXt7LkRlcGxveURpcn19CmNkICIke0RFUExPWV9ESVJ9IiB8fCBleGl0IDEKCiMgV0FSTklORzogVGhpcyBmaWxlIHdhcyBhdXRvLWdlbmVyYXRlZC4gRG8gbm90IGVkaXQhCiMgICAgICAgICAgQWxsIHlvdXIgZWRpdCBtaWdodCBiZSBvdmVyd3JpdHRlbiEKCmV4ZWMgPiA+KHRlZSAtaSAtYSAie3suTG9nRGlyfX0vcHJvbWV0aGV1cy5sb2ciKQpleGVjIDI+JjEKCnt7LSBpZiAuTnVtYU5vZGV9fQpleGVjIG51bWFjdGwgLS1jcHVub2RlYmluZD17ey5OdW1hTm9kZX19IC0tbWVtYmluZD17ey5OdW1hTm9kZX19IGJpbi9wcm9tZXRoZXVzL3Byb21ldGhldXMgXAp7ey0gZWxzZX19CmV4ZWMgYmluL3Byb21ldGhldXMvcHJvbWV0aGV1cyBcCnt7LSBlbmR9fQogICAgLS1jb25maWcuZmlsZT0ie3suRGVwbG95RGlyfX0vY29uZi9wcm9tZXRoZXVzLnltbCIgXAogICAgLS13ZWIubGlzdGVuLWFkZHJlc3M9Ijp7ey5Qb3J0fX0iIFwKICAgIC0td2ViLmV4dGVybmFsLXVybD0iaHR0cDovL3t7LklQfX06e3suUG9ydH19LyIgXAogICAgLS13ZWIuZW5hYmxlLWFkbWluLWFwaSBcCiAgICAtLWxvZy5sZXZlbD0iaW5mbyIgXAogICAgLS1zdG9yYWdlLnRzZGIucGF0aD0ie3suRGF0YURpcn19IiBcCiAgICAtLXN0b3JhZ2UudHNkYi5yZXRlbnRpb249Int7LlJldGVudGlvbn19Igo=" diff --git a/templates/scripts/run_node_exporter.sh.tpl b/templates/scripts/run_node_exporter.sh.tpl index f99ca565af..9bbf6f065a 100644 --- a/templates/scripts/run_node_exporter.sh.tpl +++ b/templates/scripts/run_node_exporter.sh.tpl @@ -20,5 +20,6 @@ exec bin/node_exporter/node_exporter \ --collector.mountstats \ --collector.meminfo_numa \ --collector.interrupts \ + --collector.buddyinfo \ --collector.vmstat.fields="^.*" \ --log.level="info"