diff --git a/components/dm/command/scale_in.go b/components/dm/command/scale_in.go index ba19051924..a56510b345 100644 --- a/components/dm/command/scale_in.go +++ b/components/dm/command/scale_in.go @@ -114,7 +114,7 @@ func ScaleInDMCluster( continue } instCount[instance.GetHost()]-- - if err := operator.StopAndDestroyInstance(getter, topo, instance, options, instCount[instance.GetHost()] == 0, publicKeyPath); err != nil { + if err := operator.StopAndDestroyInstance(getter, topo, instance, options, instCount[instance.GetHost()] == 0); err != nil { log.Warnf("failed to stop/destroy %s: %v", component.Name(), err) } } @@ -169,7 +169,7 @@ func ScaleInDMCluster( instCount[instance.GetHost()]-- if instCount[instance.GetHost()] == 0 { - if err := operator.DeletePublicKey(getter, instance.GetHost(), publicKeyPath); err != nil { + if err := operator.DeletePublicKey(getter, instance.GetHost()); err != nil { return errors.Annotatef(err, "failed to delete public key") } } diff --git a/pkg/cluster/manager.go b/pkg/cluster/manager.go index ea511413f1..c3785c0d5a 100644 --- a/pkg/cluster/manager.go +++ b/pkg/cluster/manager.go @@ -381,7 +381,7 @@ func (m *Manager) DestroyCluster(clusterName string, gOpt operator.Options, dest }, tlsCfg) }). Func("DestroyCluster", func(ctx *task.Context) error { - return operator.Destroy(ctx, topo, ctx.PublicKeyPath, destroyOpt) + return operator.Destroy(ctx, topo, destroyOpt) }). Build() diff --git a/pkg/cluster/operation/destroy.go b/pkg/cluster/operation/destroy.go index e6e4d3871e..8e3e4c4321 100644 --- a/pkg/cluster/operation/destroy.go +++ b/pkg/cluster/operation/destroy.go @@ -56,7 +56,6 @@ func Cleanup( func Destroy( getter ExecutorGetter, cluster spec.Topology, - publicKeyPath string, options Options, ) error { coms := cluster.ComponentsByStopOrder() @@ -96,7 +95,7 @@ func Destroy( // after all things done, try to remove SSH public key for host := range instCount { - if err := DeletePublicKey(getter, host, publicKeyPath); err != nil { + if err := DeletePublicKey(getter, host); err != nil { return nil } } @@ -107,7 +106,7 @@ func Destroy( // StopAndDestroyInstance stop and destroy the instance, // if this instance is the host's last one, and the host has monitor deployed, // we need to destroy the monitor, either -func StopAndDestroyInstance(getter ExecutorGetter, cluster spec.Topology, instance spec.Instance, options Options, destroyNode bool, publicKeyPath string) error { +func StopAndDestroyInstance(getter ExecutorGetter, cluster spec.Topology, instance spec.Instance, options Options, destroyNode bool) error { ignoreErr := options.Force compName := instance.ComponentName() @@ -144,7 +143,7 @@ func StopAndDestroyInstance(getter ExecutorGetter, cluster spec.Topology, instan } } - if err := DeletePublicKey(getter, instance.GetHost(), publicKeyPath); err != nil { + if err := DeletePublicKey(getter, instance.GetHost()); err != nil { if !ignoreErr { return errors.Annotatef(err, "failed to delete public key") } @@ -196,17 +195,20 @@ func DeleteGlobalDirs(getter ExecutorGetter, host string, options *spec.GlobalOp } // DeletePublicKey deletes the SSH public key from host -func DeletePublicKey(getter ExecutorGetter, host, pubKeyPath string) error { +func DeletePublicKey(getter ExecutorGetter, host string) error { e := getter.Get(host) log.Infof("Delete public key %s", host) + _, pubKeyPath := getter.GetSSHKeySet() publicKey, err := ioutil.ReadFile(pubKeyPath) if err != nil { return perrs.Trace(err) } + pubKey := string(bytes.TrimSpace(publicKey)) pubKey = strings.ReplaceAll(pubKey, "/", "\\/") pubKeysFile := executor.FindSSHAuthorizedKeysFile(e) + // delete the public key with Linux `sed` toolkit c := module.ShellModuleConfig{ Command: fmt.Sprintf("sed -i '/%s/d' %s", pubKey, pubKeysFile), UseShell: false, @@ -518,7 +520,7 @@ func DestroyClusterTombstone( for _, instance := range instances { instCount[instance.GetHost()]-- - err := StopAndDestroyInstance(getter, cluster, instance, options, instCount[instance.GetHost()] == 0, publicKey) + err := StopAndDestroyInstance(getter, cluster, instance, options, instCount[instance.GetHost()] == 0) if err != nil { return errors.AddStack(err) } diff --git a/pkg/cluster/operation/operation.go b/pkg/cluster/operation/operation.go index 645a80269c..46b63073f4 100644 --- a/pkg/cluster/operation/operation.go +++ b/pkg/cluster/operation/operation.go @@ -120,4 +120,6 @@ func FilterInstance(instances []spec.Instance, nodes set.StringSet) (res []spec. // ExecutorGetter get the executor by host. type ExecutorGetter interface { Get(host string) (e executor.Executor) + // GetSSHKeySet gets the SSH private and public key path + GetSSHKeySet() (privateKeyPath, publicKeyPath string) } diff --git a/pkg/cluster/operation/scale_in.go b/pkg/cluster/operation/scale_in.go index f6dc4b3e45..5e4a5fb838 100644 --- a/pkg/cluster/operation/scale_in.go +++ b/pkg/cluster/operation/scale_in.go @@ -153,7 +153,7 @@ func ScaleInCluster( } instCount[instance.GetHost()]-- - if err := StopAndDestroyInstance(getter, cluster, instance, options, instCount[instance.GetHost()] == 0, publicKeyPath); err != nil { + if err := StopAndDestroyInstance(getter, cluster, instance, options, instCount[instance.GetHost()] == 0); err != nil { log.Warnf("failed to stop/destroy %s: %v", compName, err) } @@ -226,7 +226,7 @@ func ScaleInCluster( if !asyncOfflineComps.Exist(instance.ComponentName()) { instCount[instance.GetHost()]-- - if err := StopAndDestroyInstance(getter, cluster, instance, options, instCount[instance.GetHost()] == 0, publicKeyPath); err != nil { + if err := StopAndDestroyInstance(getter, cluster, instance, options, instCount[instance.GetHost()] == 0); err != nil { return err } } else { diff --git a/pkg/cluster/task/action.go b/pkg/cluster/task/action.go index 11b5a8c5a9..d46d46716a 100644 --- a/pkg/cluster/task/action.go +++ b/pkg/cluster/task/action.go @@ -58,7 +58,7 @@ func (c *ClusterOperate) Execute(ctx *Context) error { } operator.PrintClusterStatus(ctx, c.spec) case operator.DestroyOperation: - err := operator.Destroy(ctx, c.spec, ctx.PublicKeyPath, c.options) + err := operator.Destroy(ctx, c.spec, c.options) if err != nil { return errors.Annotate(err, "failed to destroy") } diff --git a/pkg/cluster/task/task.go b/pkg/cluster/task/task.go index 11f8da2ab9..abea809da8 100644 --- a/pkg/cluster/task/task.go +++ b/pkg/cluster/task/task.go @@ -56,7 +56,7 @@ type ( checkResults map[string][]*operator.CheckResult } - // The public/private key is used to access remote server via the user `tidb` + // The private/public key is used to access remote server via the user `tidb` PrivateKeyPath string PublicKeyPath string } @@ -95,7 +95,7 @@ func NewContext() *Context { } } -// Get implements operation ExecutorGetter interface. +// Get implements the operation.ExecutorGetter interface. func (ctx *Context) Get(host string) (e executor.Executor) { ctx.exec.Lock() e, ok := ctx.exec.executors[host] @@ -107,6 +107,11 @@ func (ctx *Context) Get(host string) (e executor.Executor) { return } +// GetSSHKeySet implements the operation.ExecutorGetter interface. +func (ctx *Context) GetSSHKeySet() (privateKeyPath, publicKeyPath string) { + return ctx.PrivateKeyPath, ctx.PublicKeyPath +} + // GetExecutor get the executor. func (ctx *Context) GetExecutor(host string) (e executor.Executor, ok bool) { // Mock point for unit test