github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/infrastructure/tasks/tasks.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package tasks
    21  
    22  import (
    23  	"fmt"
    24  	"strings"
    25  
    26  	kubekeyapiv1alpha2 "github.com/kubesphere/kubekey/v3/cmd/kk/apis/kubekey/v1alpha2"
    27  	"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/bootstrap/os"
    28  	"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/common"
    29  	"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/connector"
    30  	"github.com/kubesphere/kubekey/v3/cmd/kk/pkg/core/logger"
    31  	"github.com/kubesphere/kubekey/v3/util/osrelease"
    32  
    33  	cfgcore "github.com/1aal/kubeblocks/pkg/configuration/core"
    34  )
    35  
    36  type InstallDependenciesTask struct {
    37  	common.KubeAction
    38  	pkg []string
    39  }
    40  
    41  var dependenciesPkg = []string{"socat", "conntrack", "ipset", "ebtables", "chrony", "iptables", "curl", "ipvsadm"}
    42  
    43  func (i *InstallDependenciesTask) Execute(runtime connector.Runtime) (err error) {
    44  	host := runtime.RemoteHost()
    45  	release, ok := host.GetCache().Get(os.Release)
    46  	if !ok {
    47  		return cfgcore.MakeError("failed to get os release.")
    48  	}
    49  
    50  	r := release.(*osrelease.Data)
    51  	installCommand, err := checkRepositoryInstallerCommand(r, runtime)
    52  	if err != nil {
    53  		return err
    54  	}
    55  	depPkg := strings.Join(append(i.pkg, dependenciesPkg...), " ")
    56  	stdout, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("%s %s", installCommand, depPkg), true)
    57  	logger.Log.Info(stdout)
    58  	return err
    59  }
    60  
    61  type UpdateNodeTask struct {
    62  	common.KubeAction
    63  }
    64  
    65  func (i *UpdateNodeTask) Execute(runtime connector.Runtime) (err error) {
    66  	host := runtime.RemoteHost()
    67  	if host.GetArch() != "" {
    68  		return nil
    69  	}
    70  
    71  	stdout, err := runtime.GetRunner().Cmd("uname -m", false)
    72  	if err != nil {
    73  		return err
    74  	}
    75  	host.SetArch(parseNodeArchitecture(stdout))
    76  	updateClusterSpecHost(i.KubeConf.Cluster, host)
    77  	return nil
    78  }
    79  
    80  func updateClusterSpecHost(clusterSpec *kubekeyapiv1alpha2.ClusterSpec, host connector.Host) {
    81  	for i := range clusterSpec.Hosts {
    82  		h := &clusterSpec.Hosts[i]
    83  		if h.Name == host.GetName() {
    84  			h.Arch = host.GetArch()
    85  		}
    86  	}
    87  }
    88  
    89  func parseNodeArchitecture(stdout string) string {
    90  	switch strings.TrimSpace(stdout) {
    91  	default:
    92  		return "amd64"
    93  	case "x86_64":
    94  		return "amd64"
    95  	case "arm64", "arm":
    96  		return "arm64"
    97  	case "aarch64", "aarch32":
    98  		return "arm"
    99  	}
   100  }
   101  
   102  func checkRepositoryInstallerCommand(osData *osrelease.Data, runtime connector.Runtime) (string, error) {
   103  	const (
   104  		debianCommand = "apt install -y"
   105  		rhelCommand   = "yum install -y"
   106  	)
   107  
   108  	isDebianCore := func() bool {
   109  		checkDeb, err := runtime.GetRunner().SudoCmd("which apt", false)
   110  		return err == nil && strings.Contains(checkDeb, "bin")
   111  	}
   112  	isRhelCore := func() bool {
   113  		checkDeb, err := runtime.GetRunner().SudoCmd("which yum", false)
   114  		return err == nil && strings.Contains(checkDeb, "bin")
   115  	}
   116  
   117  	switch strings.ToLower(osData.ID) {
   118  	case "ubuntu", "debian":
   119  		return debianCommand, nil
   120  	case "centos", "rhel":
   121  		return rhelCommand, nil
   122  	}
   123  
   124  	switch {
   125  	default:
   126  		return "", cfgcore.MakeError("failed to check apt or yum.")
   127  	case isRhelCore():
   128  		return rhelCommand, nil
   129  	case isDebianCore():
   130  		return debianCommand, nil
   131  	}
   132  }