Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support use local file or directory as config for monitor components #712

Merged
merged 41 commits into from
Aug 28, 2020
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
3c791cb
Support config file for alertmanager
lucklove Aug 24, 2020
aaa706a
Support rules directory for prometheus
lucklove Aug 24, 2020
c3dbf3e
Support config file for grafana
lucklove Aug 25, 2020
8e20e58
Tidy go.mod
lucklove Aug 25, 2020
52f62f6
Fix check
lucklove Aug 25, 2020
4407113
Add unit test for grafana init dashboards
lucklove Aug 25, 2020
dedca50
Add Integration Testing
lucklove Aug 25, 2020
819810b
make tidy
lucklove Aug 26, 2020
32d0689
Remove useless file
lucklove Aug 26, 2020
2b6dfff
typo
lucklove Aug 26, 2020
a8a01dc
Debug test
lucklove Aug 26, 2020
ef364e8
Adjust prometheus default config place
lucklove Aug 26, 2020
7e9f5e1
Merge remote-tracking branch 'upstream/master' into config-file
lucklove Aug 26, 2020
3a6f25e
debug
lucklove Aug 26, 2020
ca67340
Fix
lucklove Aug 26, 2020
4b37e56
Fix test
lucklove Aug 26, 2020
f6ec11d
Fix test
lucklove Aug 26, 2020
3706e17
Fix test
lucklove Aug 26, 2020
452a961
Debug
lucklove Aug 26, 2020
45c59fb
Simplify test
lucklove Aug 26, 2020
7e3fb7e
Fix bash
lucklove Aug 26, 2020
c3c3cc8
Update pkg/cluster/spec/instance.go
lucklove Aug 27, 2020
c0ba5e8
Address comment
lucklove Aug 27, 2020
09adfbb
Merge branch 'master' into config-file
lucklove Aug 27, 2020
55cb207
Update pkg/cluster/spec/alertmanager.go
lucklove Aug 27, 2020
8f9f361
Add licence
lucklove Aug 27, 2020
356c473
Merge branch 'config-file' of https://github.com/lucklove/tiup into c…
lucklove Aug 27, 2020
df46c0a
Relative path detect
lucklove Aug 27, 2020
c9a9b8e
Fix skip field
lucklove Aug 27, 2020
e19625d
Add test
lucklove Aug 27, 2020
8504d70
Adjust style
lucklove Aug 27, 2020
aafafb0
Update components/dm/spec/grafana.go
lucklove Aug 27, 2020
179e9d8
Update pkg/cluster/spec/grafana.go
lucklove Aug 27, 2020
230866c
Update components/dm/spec/prometheus.go
lucklove Aug 27, 2020
40ab2c0
Fix check
lucklove Aug 27, 2020
f70046b
Merge branch 'config-file' of https://github.com/lucklove/tiup into c…
lucklove Aug 27, 2020
1636708
Merge branch 'master' into config-file
july2993 Aug 27, 2020
b8123c8
Fix test
lucklove Aug 27, 2020
df03bd5
Fix style
lucklove Aug 27, 2020
c717bf2
Filter files
lucklove Aug 27, 2020
478d3a3
Fix
lucklove Aug 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions components/dm/spec/alertmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@ func (i *AlertManagerInstance) InitConfig(e executor.Executor, clusterName, clus
return err
}

// If the user specific a local config file, we should overwrite the default one with it
if spec.ConfigFilePath != "" {
lucklove marked this conversation as resolved.
Show resolved Hide resolved
name := filepath.Base(spec.ConfigFilePath)
dst := filepath.Join(paths.Deploy, "conf", name)
if err := i.TransferLocalConfigFile(e, spec.ConfigFilePath, dst); err != nil {
return errors.Annotate(err, "transfer alertmanager config failed")
}
}

return nil
}

Expand Down
121 changes: 79 additions & 42 deletions components/dm/spec/grafana.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ func (i *GrafanaInstance) InitConfig(e executor.Executor, clusterName, clusterVe
return err
}

if err := i.initDashboards(e, i.InstanceSpec.(GrafanaSpec), paths); err != nil {
return errors.Annotate(err, "initial dashboards")
}

var dirs []string

// provisioningDir Must same as in grafana.ini.tpl
Expand Down Expand Up @@ -145,6 +149,28 @@ func (i *GrafanaInstance) InitConfig(e executor.Executor, clusterName, clusterVe
return e.Transfer(fp, dst, false)
}

func (i *GrafanaInstance) initDashboards(e executor.Executor, spec GrafanaSpec, paths meta.DirPaths) error {
dashboardsDir := filepath.Join(paths.Deploy, "dashboards")
// To make this step idempotent, we need cleanup old dashboards first
if _, stderr, err := e.Execute(fmt.Sprintf("rm -f %s/*", dashboardsDir), false); err != nil {
return errors.Annotatef(err, "cleanup old dashboards: %s", string(stderr))
}
lucklove marked this conversation as resolved.
Show resolved Hide resolved

if spec.DashboardDir != "" {
if err := i.TransferLocalConfigDir(e, spec.DashboardDir, dashboardsDir); err != nil {
return errors.Annotate(err, "transfer dashboards failed")
}
return nil
}

// Use the default ones
lucklove marked this conversation as resolved.
Show resolved Hide resolved
cmd := fmt.Sprintf("cp %[1]s/bin/*.json %[1]s/dashboards/", paths.Deploy)
if _, _, err := e.Execute(cmd, false); err != nil {
return errors.Annotatef(err, "execute command failed: %s", err)
}
return nil
}

// ScaleConfig deploy temporary config on scaling
func (i *GrafanaInstance) ScaleConfig(e executor.Executor, topo spec.Topology,
clusterName string, clusterVersion string, deployUser string, paths meta.DirPaths) error {
Expand Down Expand Up @@ -174,57 +200,68 @@ func (i *GrafanaInstance) Deploy(t *task.Builder, srcPath string, deployDir stri
).Func("Dashboards", func(ctx *task.Context) error {
e := ctx.Get(i.GetHost())

tmp := filepath.Join(deployDir, "_tiup_tmp")
_, stderr, err := e.Execute(fmt.Sprintf("mkdir -p %s", tmp), false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
return i.installDashboards(e, deployDir, clusterName, clusterVersion)
})
}

srcPath := task.PackagePath(ComponentDMMaster, clusterVersion, i.OS(), i.Arch())
dstPath := filepath.Join(tmp, filepath.Base(srcPath))
err = e.Transfer(srcPath, dstPath, false)
if err != nil {
return errors.AddStack(err)
}
func (i *GrafanaInstance) installDashboards(e executor.Executor, deployDir, clusterName, clusterVersion string) error {
tmp := filepath.Join(deployDir, "_tiup_tmp")
lucklove marked this conversation as resolved.
Show resolved Hide resolved
_, stderr, err := e.Execute(fmt.Sprintf("mkdir -p %s", tmp), false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

cmd := fmt.Sprintf(`tar --no-same-owner -zxf %s -C %s && rm %s`, dstPath, tmp, dstPath)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
srcPath := task.PackagePath(ComponentDMMaster, clusterVersion, i.OS(), i.Arch())
dstPath := filepath.Join(tmp, filepath.Base(srcPath))
err = e.Transfer(srcPath, dstPath, false)
if err != nil {
return errors.AddStack(err)
}

// copy dm-master/scripts/*.json
targetDir := filepath.Join(deployDir, "dashboards")
_, stderr, err = e.Execute(fmt.Sprintf("mkdir -p %s", targetDir), false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
cmd := fmt.Sprintf(`tar --no-same-owner -zxf %s -C %s && rm %s`, dstPath, tmp, dstPath)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

cmd = fmt.Sprintf("cp %s/dm-master/scripts/*json %s", tmp, targetDir)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
// copy dm-master/scripts/*.json
targetDir := filepath.Join(deployDir, "dashboards")
_, stderr, err = e.Execute(fmt.Sprintf("mkdir -p %s", targetDir), false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

for _, cmd := range []string{
`find %s -type f -exec sed -i "s/\${DS_.*-CLUSTER}/%s/g" {} \;`,
`find %s -type f -exec sed -i "s/DS_.*-CLUSTER/%s/g" {} \;`,
`find %s -type f -exec sed -i "s/test-cluster/%s/g" {} \;`,
`find %s -type f -exec sed -i "s/Test-Cluster/%s/g" {} \;`,
} {
cmd := fmt.Sprintf(cmd, targetDir, clusterName)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
}
cmd = fmt.Sprintf("cp %s/dm-master/scripts/*.json %s", tmp, targetDir)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

cmd = fmt.Sprintf("rm -rf %s", tmp)
for _, cmd := range []string{
`find %s -type f -exec sed -i "s/\${DS_.*-CLUSTER}/%s/g" {} \;`,
`find %s -type f -exec sed -i "s/DS_.*-CLUSTER/%s/g" {} \;`,
`find %s -type f -exec sed -i "s/test-cluster/%s/g" {} \;`,
`find %s -type f -exec sed -i "s/Test-Cluster/%s/g" {} \;`,
} {
cmd := fmt.Sprintf(cmd, targetDir, clusterName)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
}

return nil
})
cmd = fmt.Sprintf("rm -rf %s", tmp)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

// backup *.json for later reload (in case that the user change dashboard_dir)
cmd = fmt.Sprintf("cp %s/*.json %s", targetDir, filepath.Join(deployDir, "bin"))
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
lucklove marked this conversation as resolved.
Show resolved Hide resolved
}

return nil
}
58 changes: 58 additions & 0 deletions components/dm/spec/grafana_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// 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 spec
lucklove marked this conversation as resolved.
Show resolved Hide resolved

import (
"io/ioutil"
"os"
"path"
"path/filepath"
"testing"

"github.com/pingcap/tiup/pkg/cluster/executor"
"github.com/pingcap/tiup/pkg/meta"
"github.com/stretchr/testify/assert"
)

func TestLocalDashboards(t *testing.T) {
deployDir, err := ioutil.TempDir("", "tiup-*")
assert.Nil(t, err)
defer os.RemoveAll(deployDir)
localDir, err := filepath.Abs("./testdata/dashboards")
assert.Nil(t, err)

topo := new(Topology)
topo.Grafana = append(topo.Grafana, GrafanaSpec{
Host: "127.0.0.1",
Port: 3000,
DashboardDir: localDir,
})

comp := GrafanaComponent{topo}
ints := comp.Instances()

assert.Equal(t, len(ints), 1)
grafanaInstance := ints[0].(*GrafanaInstance)

e := &executor.Local{}
err = grafanaInstance.initDashboards(e, topo.Grafana[0], meta.DirPaths{Deploy: deployDir})
assert.Nil(t, err)

assert.FileExists(t, path.Join(deployDir, "dashboards", "tidb.json"))
fs, err := ioutil.ReadDir(localDir)
assert.Nil(t, err)
for _, f := range fs {
assert.FileExists(t, path.Join(deployDir, "dashboards", f.Name()))
}
}
97 changes: 68 additions & 29 deletions components/dm/spec/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,40 @@ func (i *MonitorInstance) InitConfig(e executor.Executor, clusterName, clusterVe
cfig.AddAlertmanager(alertmanager.Host, uint64(alertmanager.WebPort))
}

if err := i.initRules(e, spec, paths); err != nil {
return errors.AddStack(err)
}

if err := cfig.ConfigToFile(fp); err != nil {
return err
}
dst = filepath.Join(paths.Deploy, "conf", "prometheus.yml")
return e.Transfer(fp, dst, false)
}

func (i *MonitorInstance) initRules(e executor.Executor, spec PrometheusSpec, paths meta.DirPaths) error {
confDir := filepath.Join(paths.Deploy, "conf")
// To make this step idempotent, we need cleanup old rules first
if _, stderr, err := e.Execute(fmt.Sprintf("rm -f %s/*.rules.yml", confDir), false); err != nil {
return errors.Annotatef(err, "cleanup old rules: %s", string(stderr))
}

// If the user specify a rule directory, we should use the rules specified
if spec.RuleDir != "" {
if err := i.TransferLocalConfigDir(e, spec.RuleDir, confDir); err != nil {
return errors.Annotate(err, "transfer prometheus rules failed")
}
return nil
}

// Use the default ones
cmd := fmt.Sprintf("cp %[1]s/bin/prometheus/*.rules.yml %[1]s/conf/", paths.Deploy)
if _, _, err := e.Execute(cmd, false); err != nil {
return errors.Annotatef(err, "execute command failed: %s", err)
}
return nil
}

// ScaleConfig deploy temporary config on scaling
func (i *MonitorInstance) ScaleConfig(e executor.Executor, topo spec.Topology,
clusterName string, clusterVersion string, deployUser string, paths meta.DirPaths) error {
Expand Down Expand Up @@ -151,39 +178,51 @@ func (i *MonitorInstance) Deploy(t *task.Builder, srcPath string, deployDir stri
).Func("CopyRulesYML", func(ctx *task.Context) error {
e := ctx.Get(i.GetHost())

tmp := filepath.Join(deployDir, "_tiup_tmp")
_, stderr, err := e.Execute(fmt.Sprintf("mkdir -p %s", tmp), false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
return i.installRules(e, deployDir, clusterVersion)
})
}

srcPath := task.PackagePath(ComponentDMMaster, clusterVersion, i.OS(), i.Arch())
dstPath := filepath.Join(tmp, filepath.Base(srcPath))
func (i *MonitorInstance) installRules(e executor.Executor, deployDir, clusterVersion string) error {
tmp := filepath.Join(deployDir, "_tiup_tmp")
_, stderr, err := e.Execute(fmt.Sprintf("mkdir -p %s", tmp), false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

err = e.Transfer(srcPath, dstPath, false)
if err != nil {
return errors.AddStack(err)
}
srcPath := task.PackagePath(ComponentDMMaster, clusterVersion, i.OS(), i.Arch())
dstPath := filepath.Join(tmp, filepath.Base(srcPath))

cmd := fmt.Sprintf(`tar --no-same-owner -zxf %s -C %s && rm %s`, dstPath, tmp, dstPath)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
err = e.Transfer(srcPath, dstPath, false)
if err != nil {
return errors.AddStack(err)
}

// copy dm-master/conf/*.rules.yml
cmd = fmt.Sprintf("cp %s/dm-master/conf/*rules.yml %s", tmp, filepath.Join(deployDir, "conf"))
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
cmd := fmt.Sprintf(`tar --no-same-owner -zxf %s -C %s && rm %s`, dstPath, tmp, dstPath)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

cmd = fmt.Sprintf("rm -rf %s", tmp)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}
// copy dm-master/conf/*.rules.yml
targetDir := filepath.Join(deployDir, "conf")
cmd = fmt.Sprintf("cp %s/dm-master/conf/*.rules.yml %s", tmp, targetDir)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

return nil
})
cmd = fmt.Sprintf("rm -rf %s", tmp)
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

// backup *.rules.yml for later reload (in case that the user change rule_dir)
cmd = fmt.Sprintf("cp %s/*.rules.yml %s", targetDir, filepath.Join(deployDir, "bin", "prometheus"))
_, stderr, err = e.Execute(cmd, false)
if err != nil {
return errors.Annotatef(err, "stderr: %s", string(stderr))
}

return nil
}
3 changes: 3 additions & 0 deletions components/dm/spec/testdata/dashboards/tidb.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"desc": "this is a dummy test file"
}
6 changes: 5 additions & 1 deletion components/dm/spec/topology_dm.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,11 @@ func (topo *Topology) Validate() error {
return err
}

return topo.dirConflictsDetect()
if err := topo.dirConflictsDetect(); err != nil {
return err
}

return spec.RelativePathDetect(topo, isSkipField)
}

// BaseTopo implements Topology interface.
Expand Down
Loading