mirror of
https://github.com/kubesphere/kubekey.git
synced 2025-12-26 01:22:51 +00:00
fix: delete node nil pointer panic
Signed-off-by: 24sama <jacksama@foxmail.com>
This commit is contained in:
parent
f7036b0b7a
commit
d25eab880c
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
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,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/kubesphere/kubekey/pkg/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/task"
|
||||
)
|
||||
|
||||
type ModifyConfigModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (m *ModifyConfigModule) Init() {
|
||||
m.Name = "ModifyConfigModule"
|
||||
m.Desc = "Modify the KubeKey config file"
|
||||
|
||||
modify := &task.LocalTask{
|
||||
Name: "ModifyConfig",
|
||||
Desc: "Modify the KubeKey config file",
|
||||
Action: new(ModifyConfig),
|
||||
}
|
||||
|
||||
m.Tasks = []task.Interface{
|
||||
modify,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
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,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kubesphere/kubekey/pkg/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/connector"
|
||||
"github.com/pkg/errors"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type ModifyConfig struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (m *ModifyConfig) Execute(runtime connector.Runtime) error {
|
||||
fp, _ := filepath.Abs(m.KubeConf.Arg.FilePath)
|
||||
cmd0 := fmt.Sprintf("cat %s | grep %s | wc -l", fp, m.KubeConf.Arg.NodeName)
|
||||
nodeNameNum, err0 := exec.Command("/bin/sh", "-c", cmd0).CombinedOutput()
|
||||
if err0 != nil {
|
||||
return errors.Wrap(err0, "Failed to get node num")
|
||||
}
|
||||
|
||||
host := &connector.BaseHost{Name: m.KubeConf.Arg.NodeName}
|
||||
if string(nodeNameNum) == "2\n" {
|
||||
cmd := fmt.Sprintf("sed -i /%s/d %s", m.KubeConf.Arg.NodeName, fp)
|
||||
_ = exec.Command("/bin/sh", "-c", cmd).Run()
|
||||
runtime.DeleteHost(host)
|
||||
} else if string(nodeNameNum) == "1\n" {
|
||||
cmd := fmt.Sprintf("sed -i /%s/d %s", m.KubeConf.Arg.NodeName, fp)
|
||||
_ = exec.Command("/bin/sh", "-c", cmd).Run()
|
||||
runtime.DeleteHost(host)
|
||||
|
||||
var newNodeName []string
|
||||
for i := 0; i < len(runtime.GetHostsByRole(common.Worker)); i++ {
|
||||
name := runtime.GetHostsByRole(common.Worker)[i].GetName()
|
||||
if m.KubeConf.Arg.NodeName == name {
|
||||
continue
|
||||
} else {
|
||||
newNodeName = append(newNodeName, name)
|
||||
}
|
||||
}
|
||||
var connNodeName []string
|
||||
for j := 0; j < len(newNodeName); j++ {
|
||||
t := j
|
||||
nodename1 := newNodeName[t]
|
||||
for t+1 < len(newNodeName) && IsAdjoin(newNodeName[t], newNodeName[t+1]) {
|
||||
t++
|
||||
}
|
||||
if t == j {
|
||||
connNodeName = append(connNodeName, nodename1)
|
||||
} else {
|
||||
connNodeName = append(connNodeName, Merge(nodename1, newNodeName[t]))
|
||||
j = t
|
||||
}
|
||||
}
|
||||
cmd1 := fmt.Sprintf("sed -i -n '1,/worker/p;/controlPlaneEndpoint/,$p' %s", fp)
|
||||
_ = exec.Command("/bin/sh", "-c", cmd1).Run()
|
||||
for k := 0; k < len(connNodeName); k++ {
|
||||
workPar := connNodeName[k]
|
||||
workPar1 := fmt.Sprintf("%s", workPar)
|
||||
cmd2 := fmt.Sprintf("sed -i '/worker/a\\ \\ \\ \\ \\- %s' %s", workPar1, fp)
|
||||
_ = exec.Command("/bin/sh", "-c", cmd2).Run()
|
||||
}
|
||||
} else {
|
||||
return errors.New("Please check the node name in the config-sample.yaml or only support to delete worker")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Merge(name1, name2 string) (endName string) {
|
||||
par1, par2 := SplitNum(name1)
|
||||
_, par4 := SplitNum(name2)
|
||||
endName = fmt.Sprintf("%s[%s:%s]", par1, strconv.Itoa(par2), strconv.Itoa(par4))
|
||||
return endName
|
||||
}
|
||||
func IsAdjoin(name1, name2 string) bool {
|
||||
IsAd := false
|
||||
par1, par2 := SplitNum(name1)
|
||||
par3, par4 := SplitNum(name2)
|
||||
if par1 == par3 && par4 == par2+1 {
|
||||
IsAd = true
|
||||
}
|
||||
return IsAd
|
||||
}
|
||||
|
||||
func SplitNum(nodeName string) (name string, num int) {
|
||||
nodeLen := len(nodeName)
|
||||
i := nodeLen - 1
|
||||
for ; nodeLen > 0; i-- {
|
||||
if !unicode.IsDigit(rune(nodeName[i])) {
|
||||
num, _ := strconv.Atoi(nodeName[i+1:])
|
||||
name := nodeName[:i+1]
|
||||
return name, num
|
||||
}
|
||||
}
|
||||
return "", 0
|
||||
}
|
||||
|
|
@ -17,12 +17,14 @@
|
|||
package os
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/kubesphere/kubekey/pkg/bootstrap/os/templates"
|
||||
"github.com/kubesphere/kubekey/pkg/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/action"
|
||||
"github.com/kubesphere/kubekey/pkg/core/prepare"
|
||||
"github.com/kubesphere/kubekey/pkg/core/task"
|
||||
"github.com/kubesphere/kubekey/pkg/core/util"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type ConfigureOSModule struct {
|
||||
|
|
@ -91,15 +93,19 @@ func (c *ClearOSEnvironmentModule) Init() {
|
|||
Name: "ResetNetworkConfig",
|
||||
Desc: "Reset os network config",
|
||||
Hosts: c.Runtime.GetHostsByRole(common.K8s),
|
||||
Prepare: new(DeleteNode),
|
||||
Action: new(ResetNetworkConfig),
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
uninstallETCD := &task.RemoteTask{
|
||||
Name: "UninstallETCD",
|
||||
Desc: "Uninstall etcd",
|
||||
Hosts: c.Runtime.GetHostsByRole(common.ETCD),
|
||||
Prepare: new(EtcdTypeIsKubeKey),
|
||||
Name: "UninstallETCD",
|
||||
Desc: "Uninstall etcd",
|
||||
Hosts: c.Runtime.GetHostsByRole(common.ETCD),
|
||||
Prepare: &prepare.PrepareCollection{
|
||||
new(EtcdTypeIsKubeKey),
|
||||
new(DeleteNode),
|
||||
},
|
||||
Action: new(UninstallETCD),
|
||||
Parallel: true,
|
||||
}
|
||||
|
|
@ -108,6 +114,7 @@ func (c *ClearOSEnvironmentModule) Init() {
|
|||
Name: "RemoveFiles",
|
||||
Desc: "Remove cluster files",
|
||||
Hosts: c.Runtime.GetHostsByRole(common.K8s),
|
||||
Prepare: new(DeleteNode),
|
||||
Action: new(RemoveFiles),
|
||||
Parallel: true,
|
||||
}
|
||||
|
|
@ -116,6 +123,7 @@ func (c *ClearOSEnvironmentModule) Init() {
|
|||
Name: "DaemonReload",
|
||||
Desc: "Systemd daemon reload",
|
||||
Hosts: c.Runtime.GetHostsByRole(common.K8s),
|
||||
Prepare: new(DeleteNode),
|
||||
Action: new(DaemonReload),
|
||||
Parallel: true,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,3 +46,21 @@ func (e *EtcdTypeIsKubeKey) PreCheck(_ connector.Runtime) (bool, error) {
|
|||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
type DeleteNode struct {
|
||||
common.KubePrepare
|
||||
}
|
||||
|
||||
func (d *DeleteNode) PreCheck(runtime connector.Runtime) (bool, error) {
|
||||
nodeName, ok := d.PipelineCache.Get("dstNode")
|
||||
if !ok {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
host := runtime.RemoteHost()
|
||||
if host.GetName() == nodeName {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,11 +22,12 @@ import (
|
|||
"strings"
|
||||
|
||||
osrelease "github.com/dominodatalab/os-release"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kubesphere/kubekey/pkg/bootstrap/os/repository"
|
||||
"github.com/kubesphere/kubekey/pkg/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/connector"
|
||||
"github.com/kubesphere/kubekey/pkg/utils"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type NodeConfigureOS struct {
|
||||
|
|
@ -214,6 +215,9 @@ func (d *DaemonReload) Execute(runtime connector.Runtime) error {
|
|||
if _, err := runtime.GetRunner().SudoCmd("systemctl daemon-reload && exit 0", false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "systemctl daemon-reload failed")
|
||||
}
|
||||
|
||||
// try to restart the cotainerd after /etc/cni has been removed
|
||||
_, _ = runtime.GetRunner().SudoCmd("systemctl restart containerd", false)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
|
||||
"github.com/kubesphere/kubekey/pkg/bootstrap/os"
|
||||
"github.com/kubesphere/kubekey/pkg/certs/templates"
|
||||
"github.com/kubesphere/kubekey/pkg/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/action"
|
||||
|
|
@ -200,10 +201,13 @@ func (u *UninstallAutoRenewCertsModule) Init() {
|
|||
u.Desc = "UnInstall auto renew control-plane certs"
|
||||
|
||||
uninstall := &task.RemoteTask{
|
||||
Name: "UnInstallAutoRenewCerts",
|
||||
Desc: "UnInstall auto renew control-plane certs",
|
||||
Hosts: u.Runtime.GetHostsByRole(common.Master),
|
||||
Prepare: new(AutoRenewCertsEnabled),
|
||||
Name: "UnInstallAutoRenewCerts",
|
||||
Desc: "UnInstall auto renew control-plane certs",
|
||||
Hosts: u.Runtime.GetHostsByRole(common.Master),
|
||||
Prepare: &prepare.PrepareCollection{
|
||||
new(AutoRenewCertsEnabled),
|
||||
new(os.DeleteNode),
|
||||
},
|
||||
Action: new(UninstallAutoRenewCerts),
|
||||
Parallel: true,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,14 @@ package connector
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kubesphere/kubekey/pkg/core/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/logger"
|
||||
"github.com/kubesphere/kubekey/pkg/core/util"
|
||||
"github.com/pkg/errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type BaseRuntime struct {
|
||||
|
|
@ -122,7 +124,14 @@ func (b *BaseRuntime) GetIgnoreErr() bool {
|
|||
}
|
||||
|
||||
func (b *BaseRuntime) GetAllHosts() []Host {
|
||||
return b.allHosts
|
||||
hosts := make([]Host, 0, 0)
|
||||
for i := range b.allHosts {
|
||||
if b.allHosts[i] == nil || b.HostIsDeprecated(b.allHosts[i]) {
|
||||
continue
|
||||
}
|
||||
hosts = append(hosts, b.allHosts[i])
|
||||
}
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (b *BaseRuntime) SetAllHosts(hosts []Host) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ package kubernetes
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kubesphere/kubekey/pkg/binaries"
|
||||
"github.com/kubesphere/kubekey/pkg/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/action"
|
||||
|
|
@ -25,8 +29,6 @@ import (
|
|||
"github.com/kubesphere/kubekey/pkg/core/task"
|
||||
"github.com/kubesphere/kubekey/pkg/images"
|
||||
"github.com/kubesphere/kubekey/pkg/kubernetes/templates"
|
||||
"github.com/pkg/errors"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type StatusModule struct {
|
||||
|
|
@ -358,11 +360,11 @@ func (c *CompareConfigAndClusterInfoModule) Init() {
|
|||
c.Desc = "Compare config and cluster nodes info"
|
||||
|
||||
check := &task.RemoteTask{
|
||||
Name: "FindDifferences",
|
||||
Desc: "Find the differences between config and cluster node info",
|
||||
Name: "FindNode",
|
||||
Desc: "Find information about nodes that are expected to be deleted",
|
||||
Hosts: c.Runtime.GetHostsByRole(common.Master),
|
||||
Prepare: new(common.OnlyFirstMaster),
|
||||
Action: new(FindDifferences),
|
||||
Action: new(FindNode),
|
||||
}
|
||||
|
||||
c.Tasks = []task.Interface{
|
||||
|
|
|
|||
|
|
@ -20,13 +20,22 @@ import (
|
|||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/kubesphere/kubekey/pkg/etcd"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kubesphere/kubekey/pkg/etcd"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kubeerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
kube "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
kubekeyv1alpha2 "github.com/kubesphere/kubekey/apis/kubekey/v1alpha2"
|
||||
"github.com/kubesphere/kubekey/pkg/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/action"
|
||||
|
|
@ -42,13 +51,6 @@ import (
|
|||
"github.com/kubesphere/kubekey/pkg/plugins/dns"
|
||||
dnsTemplates "github.com/kubesphere/kubekey/pkg/plugins/dns/templates"
|
||||
"github.com/kubesphere/kubekey/pkg/utils"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kubeerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
kube "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
type GetClusterStatus struct {
|
||||
|
|
@ -478,15 +480,14 @@ func (k *KubeadmReset) Execute(runtime connector.Runtime) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type FindDifferences struct {
|
||||
type FindNode struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (f *FindDifferences) Execute(runtime connector.Runtime) error {
|
||||
var node string
|
||||
func (f *FindNode) Execute(runtime connector.Runtime) error {
|
||||
var resArr []string
|
||||
res, err := runtime.GetRunner().Cmd(
|
||||
"sudo -E /usr/local/bin/kubectl get nodes | grep -v NAME | grep -v 'master' | awk '{print $1}'",
|
||||
"sudo -E /usr/local/bin/kubectl get nodes | grep -v NAME | grep -v 'master\\|control-plane' | awk '{print $1}'",
|
||||
true)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "kubectl get nodes failed")
|
||||
|
|
@ -498,19 +499,23 @@ func (f *FindDifferences) Execute(runtime connector.Runtime) error {
|
|||
resArr = strings.Split(res, "\r\n")
|
||||
}
|
||||
|
||||
var workerNameStr string
|
||||
workerName := make(map[string]struct{})
|
||||
for j := 0; j < len(runtime.GetHostsByRole(common.Worker)); j++ {
|
||||
workerNameStr += runtime.GetHostsByRole(common.Worker)[j].GetName()
|
||||
workerName[runtime.GetHostsByRole(common.Worker)[j].GetName()] = struct{}{}
|
||||
}
|
||||
|
||||
var node string
|
||||
for i := 0; i < len(resArr); i++ {
|
||||
if strings.Contains(workerNameStr, resArr[i]) {
|
||||
continue
|
||||
} else {
|
||||
if _, ok := workerName[resArr[i]]; ok && resArr[i] == f.KubeConf.Arg.NodeName {
|
||||
node = resArr[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if node == "" {
|
||||
return errors.New("Please check the node name in the config-sample.yaml or only support to delete a worker")
|
||||
}
|
||||
|
||||
f.PipelineCache.Set("dstNode", node)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@
|
|||
package pipelines
|
||||
|
||||
import (
|
||||
"github.com/kubesphere/kubekey/pkg/bootstrap/config"
|
||||
"github.com/kubesphere/kubekey/pkg/bootstrap/confirm"
|
||||
"github.com/kubesphere/kubekey/pkg/bootstrap/os"
|
||||
"github.com/kubesphere/kubekey/pkg/bootstrap/precheck"
|
||||
"github.com/kubesphere/kubekey/pkg/certs"
|
||||
"github.com/kubesphere/kubekey/pkg/common"
|
||||
"github.com/kubesphere/kubekey/pkg/core/module"
|
||||
"github.com/kubesphere/kubekey/pkg/core/pipeline"
|
||||
|
|
@ -30,9 +31,10 @@ func DeleteNodePipeline(runtime *common.KubeRuntime) error {
|
|||
m := []module.Module{
|
||||
&precheck.GreetingsModule{},
|
||||
&confirm.DeleteNodeConfirmModule{},
|
||||
&config.ModifyConfigModule{},
|
||||
&kubernetes.CompareConfigAndClusterInfoModule{},
|
||||
&kubernetes.DeleteKubeNodeModule{},
|
||||
&os.ClearOSEnvironmentModule{},
|
||||
&certs.UninstallAutoRenewCertsModule{},
|
||||
}
|
||||
|
||||
p := pipeline.Pipeline{
|
||||
|
|
|
|||
Loading…
Reference in New Issue