From 32d6f106264eb7779d5485fa037f4d0500eef7ca Mon Sep 17 00:00:00 2001 From: Allen Zhong Date: Mon, 14 Dec 2020 19:51:26 +0800 Subject: [PATCH] cluster: refine log_dir handling on `clean` (part 1) (#981) * cluster: make experimental features more visiblely marked * cluster: not deleting anythin if data dir is under log dir Co-authored-by: Ti Prow Robot <71242396+ti-community-prow-bot@users.noreply.github.com> --- components/cluster/command/clean.go | 7 +++++-- components/cluster/command/deploy.go | 2 +- components/cluster/command/root.go | 4 ++-- components/cluster/command/scale_out.go | 2 +- components/dm/command/root.go | 6 ++++-- pkg/cluster/operation/destroy.go | 8 ++++++-- pkg/set/string_set.go | 8 ++++++++ 7 files changed, 27 insertions(+), 10 deletions(-) diff --git a/components/cluster/command/clean.go b/components/cluster/command/clean.go index 560a47d99f..568c911edb 100644 --- a/components/cluster/command/clean.go +++ b/components/cluster/command/clean.go @@ -24,8 +24,11 @@ func newCleanCmd() *cobra.Command { cmd := &cobra.Command{ Use: "clean ", - Short: "Cleanup a specified cluster", - Long: `Cleanup a specified cluster without destroying it (experimental). + Short: "(EXPERIMENTAL) Cleanup a specified cluster", + Long: `EXPERIMENTAL: This is an experimental feature, things may or may not work, +please backup your data before process. + +Cleanup a specified cluster without destroying it. You can retain some nodes and roles data when cleanup the cluster, eg: $ tiup cluster clean --all $ tiup cluster clean --log diff --git a/components/cluster/command/deploy.go b/components/cluster/command/deploy.go index 0b1339356c..eb47fda4fd 100644 --- a/components/cluster/command/deploy.go +++ b/components/cluster/command/deploy.go @@ -82,7 +82,7 @@ func newDeploy() *cobra.Command { } cmd.Flags().StringVarP(&opt.User, "user", "u", utils.CurrentUser(), "The user name to login via SSH. The user must has root (or sudo) privilege.") - cmd.Flags().BoolVarP(&opt.SkipCreateUser, "skip-create-user", "", false, "Skip creating the user specified in topology (experimental).") + cmd.Flags().BoolVarP(&opt.SkipCreateUser, "skip-create-user", "", false, "(EXPERIMENTAL) Skip creating the user specified in topology.") cmd.Flags().StringVarP(&opt.IdentityFile, "identity_file", "i", opt.IdentityFile, "The path of the SSH identity file. If specified, public key authentication will be used.") cmd.Flags().BoolVarP(&opt.UsePassword, "password", "p", false, "Use password of target hosts. If specified, password authentication will be used.") cmd.Flags().BoolVarP(&opt.IgnoreConfigCheck, "ignore-config-check", "", opt.IgnoreConfigCheck, "Ignore the config check result") diff --git a/components/cluster/command/root.go b/components/cluster/command/root.go index 6f4f5a64e8..43ee2016e7 100644 --- a/components/cluster/command/root.go +++ b/components/cluster/command/root.go @@ -136,8 +136,8 @@ func init() { // start/stop operations is 90s, the default value of this argument is better be longer than that rootCmd.PersistentFlags().Uint64Var(&gOpt.OptTimeout, "wait-timeout", 120, "Timeout in seconds to wait for an operation to complete, ignored for operations that don't fit.") rootCmd.PersistentFlags().BoolVarP(&skipConfirm, "yes", "y", false, "Skip all confirmations and assumes 'yes'") - rootCmd.PersistentFlags().BoolVar(&gOpt.NativeSSH, "native-ssh", gOpt.NativeSSH, "Use the native SSH client installed on local system instead of the build-in one (experimental).") - rootCmd.PersistentFlags().StringVar((*string)(&gOpt.SSHType), "ssh", "", "(experimental) The executor type: 'builtin', 'system', 'none'.") + rootCmd.PersistentFlags().BoolVar(&gOpt.NativeSSH, "native-ssh", gOpt.NativeSSH, "(EXPERIMENTAL) Use the native SSH client installed on local system instead of the build-in one.") + rootCmd.PersistentFlags().StringVar((*string)(&gOpt.SSHType), "ssh", "", "(EXPERIMENTAL) The executor type: 'builtin', 'system', 'none'.") _ = rootCmd.PersistentFlags().MarkHidden("native-ssh") rootCmd.AddCommand( diff --git a/components/cluster/command/scale_out.go b/components/cluster/command/scale_out.go index a0edcf8195..3ed60f91bd 100644 --- a/components/cluster/command/scale_out.go +++ b/components/cluster/command/scale_out.go @@ -64,7 +64,7 @@ func newScaleOutCmd() *cobra.Command { } cmd.Flags().StringVarP(&opt.User, "user", "u", utils.CurrentUser(), "The user name to login via SSH. The user must has root (or sudo) privilege.") - cmd.Flags().BoolVarP(&opt.SkipCreateUser, "skip-create-user", "", false, "Skip creating the user specified in topology (experimental).") + cmd.Flags().BoolVarP(&opt.SkipCreateUser, "skip-create-user", "", false, "(EXPERIMENTAL) Skip creating the user specified in topology.") cmd.Flags().StringVarP(&opt.IdentityFile, "identity_file", "i", opt.IdentityFile, "The path of the SSH identity file. If specified, public key authentication will be used.") cmd.Flags().BoolVarP(&opt.UsePassword, "password", "p", false, "Use password of target hosts. If specified, password authentication will be used.") cmd.Flags().BoolVarP(&opt.NoLabels, "no-labels", "", false, "Don't check TiKV labels") diff --git a/components/dm/command/root.go b/components/dm/command/root.go index 22b461b01d..e0cf76dea2 100644 --- a/components/dm/command/root.go +++ b/components/dm/command/root.go @@ -64,8 +64,10 @@ func init() { } rootCmd = &cobra.Command{ - Use: cliutil.OsArgs0(), - Short: "Deploy a DM cluster (experimental)", + Use: cliutil.OsArgs0(), + Short: "(EXPERIMENTAL) Deploy a DM cluster", + Long: `EXPERIMENTAL: This is an experimental feature, things may or may not work, +please backup your data before process.`, SilenceUsage: true, SilenceErrors: true, Version: version.NewTiUPVersion().String(), diff --git a/pkg/cluster/operation/destroy.go b/pkg/cluster/operation/destroy.go index 610c4d703c..af60af70da 100644 --- a/pkg/cluster/operation/destroy.go +++ b/pkg/cluster/operation/destroy.go @@ -308,19 +308,23 @@ func CleanupComponent(getter ExecutorGetter, instances []spec.Instance, cls spec log.Infof("Cleanup instance %s", ins.GetHost()) delFiles := set.NewStringSet() + dataPaths := set.NewStringSet() + logPaths := set.NewStringSet() if options.CleanupData && len(ins.DataDir()) > 0 { for _, dataDir := range strings.Split(ins.DataDir(), ",") { - delFiles.Insert(path.Join(dataDir, "*")) + dataPaths.Insert(path.Join(dataDir, "*")) } } if options.CleanupLog && len(ins.LogDir()) > 0 { for _, logDir := range strings.Split(ins.LogDir(), ",") { - delFiles.Insert(path.Join(logDir, "*")) + logPaths.Insert(path.Join(logDir, "*.log")) } } + delFiles.Join(logPaths).Join(dataPaths) + log.Debugf("Deleting paths on %s: %s", ins.GetHost(), strings.Join(delFiles.Slice(), " ")) c := module.ShellModuleConfig{ Command: fmt.Sprintf("rm -rf %s;", strings.Join(delFiles.Slice(), " ")), diff --git a/pkg/set/string_set.go b/pkg/set/string_set.go index beac72f24a..a8784e5353 100644 --- a/pkg/set/string_set.go +++ b/pkg/set/string_set.go @@ -36,6 +36,14 @@ func (s StringSet) Insert(val string) { s[val] = struct{}{} } +// Join add all elements of `add` to `s`. +func (s StringSet) Join(add StringSet) StringSet { + for elt := range add { + s.Insert(elt) + } + return s +} + // Intersection returns the intersection of two sets func (s StringSet) Intersection(rhs StringSet) StringSet { newSet := NewStringSet()