Files
Olares/cli/pkg/bootstrap/patch/tasks.go

315 lines
10 KiB
Go

package patch
import (
"fmt"
"strings"
"github.com/beclab/Olares/cli/pkg/utils"
"github.com/pkg/errors"
"github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/core/util"
)
type EnableSSHTask struct {
common.KubeAction
}
func (t *EnableSSHTask) Execute(runtime connector.Runtime) error {
stdout, _ := runtime.GetRunner().SudoCmd("systemctl is-active ssh", false, false)
if stdout != "active" {
if _, err := runtime.GetRunner().SudoCmd("systemctl enable --now ssh", false, false); err != nil {
return err
}
}
return nil
}
type PatchTask struct {
common.KubeAction
}
func (t *PatchTask) Execute(runtime connector.Runtime) error {
var cmd string
var debianFrontend = "DEBIAN_FRONTEND=noninteractive"
var pre_reqs = "apt-transport-https ca-certificates curl cifs-utils"
if _, err := util.GetCommand(common.CommandGPG); err != nil {
pre_reqs = pre_reqs + " gnupg "
}
if _, err := util.GetCommand(common.CommandSudo); err != nil {
pre_reqs = pre_reqs + " sudo "
}
if _, err := util.GetCommand(common.CommandUpdatePciids); err != nil {
pre_reqs = pre_reqs + " pciutils "
}
if _, err := util.GetCommand(common.CommandIptables); err != nil {
pre_reqs = pre_reqs + " iptables "
}
if _, err := util.GetCommand(common.CommandIp6tables); err != nil {
pre_reqs = pre_reqs + " iptables "
}
if _, err := util.GetCommand(common.CommandIpset); err != nil {
pre_reqs = pre_reqs + " ipset "
}
if _, err := util.GetCommand(common.CommandNmcli); err != nil {
pre_reqs = pre_reqs + " network-manager "
}
pre_reqs += " conntrack socat apache2-utils net-tools make gcc bison flex tree unzip "
var systemInfo = runtime.GetSystemInfo()
var platformFamily = systemInfo.GetOsPlatformFamily()
var aptToolAvailable bool
if _, err := util.GetCommand("add-apt-repository"); err == nil {
aptToolAvailable = true
} else {
if _, err := runtime.GetRunner().SudoCmd("apt install -y software-properties-common", false, true); err == nil {
aptToolAvailable = true
} else {
logger.Infof("software-properties-common not available, try to update apt sources ourself")
}
}
var pkgManager = systemInfo.GetPkgManager()
switch platformFamily {
case common.Debian:
sourceType := "deb"
repoURL := "https://deb.debian.org/debian"
suite := systemInfo.GetDebianVersionCode()
components := []string{"contrib", "non-free"}
if aptToolAvailable {
cmd := fmt.Sprintf("add-apt-repository '%s %s %s %s' -y", sourceType, repoURL, suite, strings.Join(components, " "))
if _, err := runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
return err
}
} else {
err := utils.AddAptSource(sourceType, repoURL, suite, components)
if err != nil {
return err
}
}
if systemInfo.IsDebianVersionEqual(connector.Debian13) {
pre_reqs += " systemd-timesyncd "
} else {
pre_reqs += " ntpdate "
}
fallthrough
case common.Ubuntu:
if systemInfo.IsUbuntu() {
if !systemInfo.IsPveOrPveLxc() && !systemInfo.IsRaspbian() {
if _, err := runtime.GetRunner().SudoCmd("add-apt-repository universe -y", false, true); err != nil {
logger.Errorf("add os repo error %v", err)
return err
}
if _, err := runtime.GetRunner().SudoCmd("add-apt-repository multiverse -y", false, true); err != nil {
logger.Errorf("add os repo error %v", err)
return err
}
}
pre_reqs += " ntpdate "
}
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("%s update -qq", pkgManager), false, true); err != nil {
logger.Errorf("update os error %v", err)
return err
}
logger.Debug("apt update success")
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("%s install -y -qq %s", pkgManager, pre_reqs), false, true); err != nil {
logger.Errorf("install deps %s error %v", pre_reqs, err)
return err
}
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("%s %s install -y %s", debianFrontend, pkgManager, cmd), false, true); err != nil {
logger.Errorf("install deps %s error %v", cmd, err)
return err
}
if _, err := runtime.GetRunner().SudoCmd("update-pciids", false, true); err != nil {
return fmt.Errorf("failed to update-pciids: %v", err)
}
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("%s %s install -y openssh-server", debianFrontend, pkgManager), false, true); err != nil {
logger.Errorf("install deps %s error %v", cmd, err)
return err
}
case common.CentOs, common.Fedora, common.RHEl:
cmd = "conntrack socat httpd-tools ntpdate net-tools make gcc openssh-server"
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("%s install -y %s", pkgManager, cmd), false, true); err != nil {
logger.Errorf("install deps %s error %v", cmd, err)
return err
}
}
return nil
}
type CorrectHostname struct {
common.KubeAction
}
func (t *CorrectHostname) Execute(runtime connector.Runtime) error {
hostName := runtime.GetSystemInfo().GetHostname()
if !utils.ContainsUppercase(hostName) {
return nil
}
hostname := strings.ToLower(hostName)
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("hostnamectl set-hostname %s", hostname), false, false); err != nil {
return err
}
runtime.GetSystemInfo().SetHostname(hostname)
return nil
}
type RaspbianCheckTask struct {
common.KubeAction
}
func (t *RaspbianCheckTask) Execute(runtime connector.Runtime) error {
// if util.IsExist(common.RaspbianCmdlineFile) || util.IsExist(common.RaspbianFirmwareFile) {
systemInfo := runtime.GetSystemInfo()
if systemInfo.IsRaspbian() {
if _, err := util.GetCommand(common.CommandIptables); err != nil {
_, err = runtime.GetRunner().SudoCmd("apt install -y iptables", false, false)
if err != nil {
logger.Errorf("%s install iptables error %v", common.Raspbian, err)
return err
}
_, err = runtime.GetRunner().Cmd("systemctl disable --user gvfs-udisks2-volume-monitor", false, true)
if err != nil {
logger.Errorf("%s exec error %v", common.Raspbian, err)
return err
}
_, err = runtime.GetRunner().Cmd("systemctl stop --user gvfs-udisks2-volume-monitor", false, true)
if err != nil {
logger.Errorf("%s exec error %v", common.Raspbian, err)
return err
}
if !systemInfo.CgroupCpuEnabled() || !systemInfo.CgroupMemoryEnabled() {
return fmt.Errorf("cpu or memory cgroups disabled, please edit /boot/cmdline.txt or /boot/firmware/cmdline.txt and reboot to enable it")
}
}
}
return nil
}
type DisableLocalDNSTask struct {
common.KubeAction
}
func (t *DisableLocalDNSTask) Execute(runtime connector.Runtime) error {
switch runtime.GetSystemInfo().GetOsPlatformFamily() {
case common.Ubuntu, common.Debian:
stdout, _ := runtime.GetRunner().SudoCmd("systemctl is-active systemd-resolved", false, false)
if stdout == "active" {
_, _ = runtime.GetRunner().SudoCmd("systemctl stop systemd-resolved.service", false, true)
_, _ = runtime.GetRunner().SudoCmd("systemctl disable systemd-resolved.service", false, true)
if utils.IsExist("/usr/bin/systemd-resolve") {
_, _ = runtime.GetRunner().SudoCmd("mv /usr/bin/systemd-resolve /usr/bin/systemd-resolve.bak", false, true)
}
ok, err := utils.IsSymLink("/etc/resolv.conf")
if err != nil {
logger.Errorf("check /etc/resolv.conf error %v", err)
return err
}
if ok {
if _, err := runtime.GetRunner().SudoCmd("unlink /etc/resolv.conf && touch /etc/resolv.conf", false, true); err != nil {
logger.Errorf("unlink /etc/resolv.conf error %v", err)
return err
}
}
if err = t.configResolvConf(runtime); err != nil {
logger.Errorf("config /etc/resolv.conf error %v", err)
return err
}
} else {
if _, err := runtime.GetRunner().SudoCmd("cat /etc/resolv.conf > /etc/resolv.conf.bak", false, true); err != nil {
logger.Errorf("backup /etc/resolv.conf error %v", err)
return err
}
httpCode, _ := utils.GetHttpStatus("https://www.apple.com")
if httpCode != 200 {
if err := t.configResolvConf(runtime); err != nil {
logger.Errorf("config /etc/resolv.conf error %v", err)
return err
}
}
}
}
sysInfo := runtime.GetSystemInfo()
localIp := sysInfo.GetLocalIp()
hostname := sysInfo.GetHostname()
if stdout, _ := runtime.GetRunner().SudoCmd("hostname -i &>/dev/null", false, true); stdout == "" {
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("echo %s %s >> /etc/hosts", localIp, hostname), false, true); err != nil {
return errors.Wrap(err, "failed to set hostname mapping")
}
}
if runtime.GetSystemInfo().IsWsl() {
_, _ = runtime.GetRunner().SudoCmd("chattr +i /etc/hosts /etc/resolv.conf", false, false)
}
return nil
}
func (t *DisableLocalDNSTask) configResolvConf(runtime connector.Runtime) error {
var err error
var cmd string
var secondNameserverOp string
overrideOp := ">"
appendOp := ">>"
var internalDNS string
if util.IsOnAliyunECS() {
internalDNS = "100.100.10.12"
} else if util.IsOnAWSEC2() {
internalDNS = "169.254.169.253"
} else if util.IsOnTencentCVM() {
internalDNS = "183.60.83.19"
}
if internalDNS != "" {
secondNameserverOp = appendOp
cmd = fmt.Sprintf("echo 'nameserver %s' > /etc/resolv.conf", internalDNS)
if _, err = runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
logger.Errorf("exec %s error %v", cmd, err)
return err
}
} else {
secondNameserverOp = overrideOp
}
primaryDNSServer, secondaryDNSServer := "1.1.1.1", "114.114.114.114"
if strings.Contains(t.KubeConf.Arg.RegistryMirrors, common.OlaresRegistryMirrorHost) || strings.Contains(t.KubeConf.Arg.RegistryMirrors, common.OlaresRegistryMirrorHostLegacy) {
primaryDNSServer, secondaryDNSServer = secondaryDNSServer, primaryDNSServer
}
cmd = fmt.Sprintf("echo 'nameserver %s' %s /etc/resolv.conf", primaryDNSServer, secondNameserverOp)
if _, err = runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
logger.Errorf("exec %s error %v", cmd, err)
return err
}
cmd = fmt.Sprintf("echo 'nameserver %s' >> /etc/resolv.conf", secondaryDNSServer)
if _, err = runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
logger.Errorf("exec %s error %v", cmd, err)
return err
}
return nil
}