Files
ProjectOctopus/agent-go/a_executor/BaseFunction.go
2024-09-27 14:34:09 +08:00

2644 lines
60 KiB
Go
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package a_executor
import (
"fmt"
"net"
"os"
"strings"
"wdd.io/agent-go/a_agent"
"wdd.io/agent-go/a_executor/beans"
)
var OctopusAgentInstallPrefix = "/root/wdd/"
type BaseFunc interface {
// Command 返回基础函数的命令行
Command(baseFuncName string, funcArgs ...string) []string
// Exec 执行命令行,只返回正确结果 || 错误,日志
Exec(baseFuncName string, funcArgs ...string) (bool, []string)
}
type AgentOsOperator struct {
InstallCommandPrefix []string `json:"install_command_prefix",comment:"apt-get install or yum install"`
RemoveCommandPrefix []string `json:"remove_command_prefix",comment:"apt-get remove or yum remove"`
CanAccessInternet bool `json:"can_access_internet",comment:"是否可以访问公网"`
IsOsTypeUbuntu bool `json:"is_os_type_ubuntu",comment:"主机操作系统是否为debian系列"`
IsOsTypeCentOS bool `json:"is_os_type_centos",comment:"主机操作系统是否为centos系列"`
IsOsTypeEuler bool `json:"is_os_type_euler",comment:"主机操作系统是否为国产欧拉系列"`
IsAgentInnerWall bool `json:"is_agent_inner_wall",comment:"主机是否身处国内"`
AgentArch string `json:"agent_arch",comment:"主机的CPU架构可选为amd64 arm64"`
AgentOSReleaseCode string `json:"agent_os_release_code",comment:"主机操作系统的发行版代号, focal之类的"`
AgentServerInfo *a_agent.AgentServerInfo `json:"agent_server_info"`
// 离线下载URL地址
OssOfflinePrefix string `comment:"必须要用 / 结尾"`
}
func (op *AgentOsOperator) Exec(baseFuncName string, funcArgs ...string) (bool, []string) {
resultOk := false
var errorLog []string
switch baseFuncName {
case "shutdownFirewall":
resultOk, errorLog = op.shutdownFirewallExec()
break
case "MODIFY_SYSCONFIG":
resultOk, errorLog = op.modifySystemConfigExec()
break
case "modifyHostname":
resultOk, errorLog = op.modifyHostnameExec(funcArgs)
break
case "enableSwap":
resultOk, errorLog = op.enableSwapExec()
break
case "disableSwap":
resultOk, errorLog = op.disableSwapExec()
break
case "DISABLE_SELINUX":
resultOk, errorLog = op.disableSELinuxExec()
break
case "installDocker":
resultOk, errorLog = op.installDockerExec(funcArgs)
break
case "installDockerByOffline":
resultOk, errorLog = op.InstallDockerBastion()
break
case "removeDocker":
resultOk, errorLog = op.removeDockerExec()
break
case "removeDockerCompose":
resultOk, errorLog = op.removeDockerComposeExec()
break
case "installDockerCompose":
resultOk, errorLog = op.installDockerComposeExec()
break
case "installDefaultSSHKey":
resultOk, errorLog = op.installDefaultSSHKeyExec(funcArgs)
break
case "modifyDockerConfig":
resultOk, errorLog = op.modifyDockerConfigExec(funcArgs)
break
case "installHelm":
resultOk, errorLog = op.installHelmExec()
break
case "installNfsOnline":
resultOk, errorLog = op.installNfsOnlineExec()
break
case "installNfsServerOnline":
resultOk, errorLog = op.installNfsServerOnlineExec()
break
case "installHarbor":
resultOk, errorLog = op.installHarborExec()
break
case "chronyToMaster":
resultOk, errorLog = op.chronyToMasterExec(funcArgs)
break
case "installZSH":
resultOk, errorLog = op.installZSHExec()
break
case "modifySshPort":
resultOk, errorLog = op.modifySshPortExec(funcArgs)
break
case "openBBR":
resultOk, errorLog = op.openBBRExec()
break
default:
resultOk, errorLog = op.okExec(funcArgs)
}
return resultOk, errorLog
}
func (op *AgentOsOperator) Command(baseFuncName string, funcArgs ...string) []string {
var multiLineCommand [][]string
switch baseFuncName {
case "shutdownFirewall":
multiLineCommand = op.shutdownFirewall()
break
case "modifyHostname":
multiLineCommand = op.modifyHostname(funcArgs)
break
case "enableSwap":
multiLineCommand = op.enableSwap()
break
case "disableSwap":
multiLineCommand = op.disableSwap()
break
case "installDocker":
multiLineCommand = op.installDocker(funcArgs)
break
case "removeDocker":
multiLineCommand = op.removeDocker()
break
case "removeDockerCompose":
multiLineCommand = op.removeDockerCompose()
break
case "installDockerCompose":
multiLineCommand = op.installDockerCompose()
break
case "modifyDockerConfig":
multiLineCommand = op.modifyDockerConfig(funcArgs)
break
case "installHelm":
multiLineCommand = op.installHelm()
break
case "installHarbor":
multiLineCommand = op.installHarbor()
break
case "chronyToPublicNTP":
multiLineCommand = op.chronyToPublicNTP()
break
case "chronyToMaster":
multiLineCommand = op.chronyToMaster(funcArgs)
break
case "installZSH":
multiLineCommand = op.installZSH()
break
case "modifySshPort":
multiLineCommand = op.modifySshPort(funcArgs)
break
case "openBBR":
multiLineCommand = op.openBBR()
break
default:
multiLineCommand = op.ok(funcArgs)
}
log.DebugF("multiLineCommand are => %v", multiLineCommand)
var result []string
// exec the command here
for _, singleLineCommand := range multiLineCommand {
singleCommandResult, _ := FormatAllCommandExecutor(singleLineCommand)
result = append(result, "")
result = append(result, singleCommandResult...)
// debug usage
log.DebugF("exec result are => %v", result)
for _, logLine := range result {
fmt.Println(logLine)
}
}
// 归一化处理
return result
}
func (op *AgentOsOperator) shutdownFirewall() [][]string {
shutdownFunc := [][]string{
{"systemctl", "stop", "firewalld"},
{"systemctl", "disable", "firewalld"},
}
if !op.IsOsTypeUbuntu {
shutdownFunc = append(shutdownFunc, []string{
"sed",
"-i",
"s/SELINUX=enforcing/SELINUX=disabled/g",
"/etc/selinux/config",
})
}
return shutdownFunc
}
func (op *AgentOsOperator) DisableFirewallBastion() (bool, []string) {
return op.shutdownFirewallExec()
}
func (op *AgentOsOperator) shutdownFirewallExec() (bool, []string) {
shutdownFunc := [][]string{
{"systemctl", "stop", "firewalld"},
{"systemctl", "disable", "firewalld"},
{"systemctl", "stop", "ufw"},
{"systemctl", "disable", "ufw"},
{"iptables", "-F"},
}
// 忽略错误
AllCompleteExecutor(shutdownFunc)
// centos
return true, []string{
"[shutdownFirewallExec] - 关闭防火墙成功!",
}
}
func (op *AgentOsOperator) modifyHostname(args []string) [][]string {
return [][]string{}
}
func (op *AgentOsOperator) modifyHostnameExec(args []string) (bool, []string) {
ok, resultLog := AllCommandExecutor([]string{
"hostnamectl",
"set-hostname",
args[0],
})
return ok, resultLog
}
func (op *AgentOsOperator) modifySystemConfigExec() (bool, []string) {
return op.ModifySysConfigBastion()
}
func (op *AgentOsOperator) ModifySysConfigBastion() (bool, []string) {
sysctlConfigFile := "/etc/sysctl.d/wdd-k8s.conf"
if !BasicAppendOverwriteContentToFile(beans.SysctlConfig, sysctlConfigFile) {
return false, []string{
"[ModifySysConfigBastion] - error appending sysctl config to sysctl.d !",
}
}
AllCommandExecutor([]string{
"sysctl",
"-p",
sysctlConfigFile,
})
return true, []string{
"[ModifySysConfigBastion] - success !",
}
}
func (op *AgentOsOperator) enableSwap() [][]string {
enableSwapFunc := [][]string{
{
"cp",
"-f",
"/etc/fstab_back",
"/etc/fstab",
},
{
"cat",
"/etc/fstab",
},
}
return enableSwapFunc
}
func (op *AgentOsOperator) enableSwapExec() (bool, []string) {
return true, nil
}
func (op *AgentOsOperator) disableSwap() [][]string {
disableSwapFunc := [][]string{
{
"swapoff",
"-a",
},
{
"cp",
"-f",
"/etc/fstab",
"/etc/fstab_back",
},
{
"sed",
"-i",
"/swap/d",
"/etc/fstab",
},
}
return disableSwapFunc
}
func (op *AgentOsOperator) disableSwapExec() (bool, []string) {
// 备份文件存在pass
if !BasicFileExists("/etc/fstab_back_wdd") {
AllCommandExecutor([]string{
"cp",
"-f",
"/etc/fstab",
"/etc/fstab_back_wdd",
})
}
// 执行关闭操作
AllCompleteExecutor([][]string{
{
"swapoff",
"-a",
},
{
"sed",
"-i",
"/swap/d",
"/etc/fstab",
},
})
return true, nil
}
func (op *AgentOsOperator) DisableSwapBastion() (bool, []string) {
return op.disableSwapExec()
}
func (op *AgentOsOperator) disableSELinuxExec() (bool, []string) {
if op.IsOsTypeUbuntu {
return true, []string{
"[disableSELinuxExec] - os is ubuntu, success",
}
}
// delete contend
BasicFindAndDeleteContendLineInFile("SELINUX=enforcing", "/etc/selinux/config")
BasicFindAndDeleteContendLineInFile("SELINUX=permissive", "/etc/selinux/config")
BasicFindAndDeleteContendLineInFile("SELINUX=disabled", "/etc/selinux/config")
BasicAppendContentToFile("SELINUX=disabled", "/etc/selinux/config")
// shutdown
AllCommandExecutor([]string{
"setenforce",
"0",
})
return true, []string{
"[disableSELinuxExec] - success",
}
}
func (op *AgentOsOperator) DisableSelinuxBastion() (bool, []string) {
return op.disableSELinuxExec()
}
func (op *AgentOsOperator) installDefaultSSHKeyExec(funcArgs []string) (bool, []string) {
// ssh-keygen -t ed25519 -C "wdd@cmii.com"
// ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa -b 4096
BasicCreateFolder("/root/.ssh/")
// check key exists
if BasicFileExistAndNotNull("/root/.ssh/id_ed25519") {
if BasicFileExistAndNotNull("/root/.ssh/id_ed25519.pub") {
if BasicGrepItemInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
return true, nil
}
}
}
// download standard private and public key
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+"id_ed25519_private_key", "", "", "", "/root/.ssh/id_ed25519")
if !ok {
return false, resultLog
}
ok, resultLog = BasicDownloadFile(op.OssOfflinePrefix+"id_ed25519_public_key.pub", "", "", "", "/root/.ssh/id_ed25519.pub")
if !ok {
return false, resultLog
}
// write into authorized_keys
if !BasicAppendSourceToFile("/root/.ssh/id_ed25519.pub", "/root/.ssh/authorized_keys") {
return false, []string{
"[installDefaultSSHKeyExec] - error appending ssh key to authorized_keys !",
}
}
AllCommandExecutor([]string{
"chmod",
"600",
"/root/.ssh/id_ed25519",
})
// check
if BasicGrepItemInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
return true, []string{
"[installDefaultSSHKeyExec] - authorized_keys contain the ssh-pub key !",
}
}
return false, []string{
"[installDefaultSSHKeyExec] - authorized_keys don't contain the ssh-pub key !",
}
}
func (op *AgentOsOperator) InstallDefaultSshBastion() (bool, []string) {
// ssh-keygen -t ed25519 -C "wdd@cmii.com"
// ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa -b 4096
BasicCreateFolder("/root/.ssh/")
// check key exists
if BasicFileExistAndNotNull("/root/.ssh/id_ed25519") {
if BasicFileExistAndNotNull("/root/.ssh/id_ed25519.pub") {
if BasicGrepItemInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
return true, nil
}
}
}
// download standard private and public key
if !BasicAppendOverwriteContentToFile(beans.Ed25519PrivateKey, "/root/.ssh/id_ed25519") {
return false, []string{
"[installDefaultSSHKeyExec] - error appending private ssh key to authorized_keys !",
}
}
if !BasicAppendOverwriteContentToFile(beans.Ed25519PublicKey, "/root/.ssh/id_ed25519.pub") {
return false, []string{
"[installDefaultSSHKeyExec] - error appending public ssh key to authorized_keys !",
}
}
// write into authorized_keys
if !BasicAppendSourceToFile("/root/.ssh/id_ed25519.pub", "/root/.ssh/authorized_keys") {
return false, []string{
"[installDefaultSSHKeyExec] - error appending ssh key to authorized_keys !",
}
}
AllCommandExecutor([]string{
"chmod",
"600",
"/root/.ssh/id_ed25519",
})
// check
if BasicGrepItemInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
log.Info("installDefaultSSHKeyExec - authorized_keys contain the ssh-pub key !")
return true, []string{
"[InstallDefaultSshBastion] - install success !",
}
}
return false, []string{
"[installDefaultSSHKeyExec] - authorized_keys don't contain the ssh-pub key !",
}
}
func (op *AgentOsOperator) removeDocker() [][]string {
removeDockerLine := append(op.RemoveCommandPrefix, []string{
"docker-ce",
"docker.io",
"docker-ce-cli", //"docker",
//"docker-common",
//"docker-latest",
//"docker-latest-logrotate",
//"docker-logrotate",
//"docker-selinux",
//"docker-engine-selinux",
//"docker-engine",
//"kubelet",
//"kubeadm",
//"kubectl",
//"docker-client",
//"docker-client-latest",
}...)
removeDockerFunc := [][]string{
removeDockerLine,
}
return removeDockerFunc
}
func (op *AgentOsOperator) removeDockerExec() (bool, []string) {
if !BasicCommandExistByPath("docker") {
return true, []string{
"[removeDockerExec] - docker is not installed !",
}
}
dockerServiceStopCommand := [][]string{
{
"systemctl",
"stop",
"docker.service",
},
{
"systemctl",
"stop",
"docker.socket",
},
{
"systemctl",
"disable",
"docker.service",
},
}
ok, l := AllCompleteExecutor(dockerServiceStopCommand)
if !ok {
log.Error("[removeDockerExec] - 停止docker服务失败")
return false, l
}
dockerStaff := []string{
"docker-ce",
"docker.io",
"docker-ce-cli",
"docker",
"docker-common",
"docker-latest",
"docker-latest-logrotate",
"docker-logrotate",
"docker-selinux",
"docker-engine-selinux",
"docker-engine",
"kubelet",
"kubeadm",
"kubectl",
"docker-client",
"docker-client-latest",
}
for _, staff := range dockerStaff {
removeCommand := append(op.RemoveCommandPrefix, staff)
AllCommandExecutor(removeCommand)
}
_ = os.Remove(beans.DockerServiceFile)
_ = os.Remove(beans.DockerDaemonService)
_ = os.Remove(beans.DockerSocketFile)
AllCommandExecutor([]string{
"systemctl",
"daemon-reload",
})
return true, []string{
"[removeDockerExec] - docker remove success !",
}
}
func (op *AgentOsOperator) RemoveDockerBastion() (bool, []string) {
return op.removeDockerExec()
}
func (op *AgentOsOperator) installDocker(args []string) [][]string {
// remove docker all staff
installDockerFunc := op.removeDocker()
if op.IsOsTypeUbuntu {
//
installFirstLine := append(op.InstallCommandPrefix, []string{
"apt-transport-https",
"ca-certificates",
"curl",
"gnupg-agent",
"software-properties-common",
}...)
if op.IsAgentInnerWall {
// inner gfw
installDockerFunc = append(installDockerFunc, [][]string{
installFirstLine,
{
"curl",
"-o",
"/etc/apt/keyrings/docker-utsc.gpg",
"https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg",
},
{
"apt-key",
"add",
"/etc/apt/keyrings/docker-utsc.gpg",
},
{
"add-apt-repository",
"deb [arch=" + op.AgentArch + "] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu " + op.AgentOSReleaseCode + " stable",
},
}...)
} else {
// outside world
installDockerFunc = append(installDockerFunc, [][]string{
installFirstLine,
{
"curl",
"-o",
"/etc/apt/keyrings/docker.gpg",
"https://download.docker.com/linux/ubuntu/gpg ",
},
{
"apt-key",
"add",
"/etc/apt/keyrings/docker.gpg",
},
{
"add-apt-repository",
"deb [arch=" + op.AgentArch + "] https://download.docker.com/linux/ubuntu " + op.AgentOSReleaseCode + " stable",
},
}...)
}
// look for specific docker-version to install
installDockerFunc = append(installDockerFunc, []string{"apt-get", "update"})
var specificDockerVersion string
// hard code here 5:20.10.10~3-0~ubuntu-focal
if strings.HasPrefix(args[0], "19") {
specificDockerVersion = "5:19.03.15~3-0~ubuntu-" + op.AgentOSReleaseCode
} else {
specificDockerVersion = "5:20.10.10~3-0~ubuntu-" + op.AgentOSReleaseCode
}
installDockerFunc = append(installDockerFunc, append(op.InstallCommandPrefix, "docker-ce="+specificDockerVersion, "docker-ce-cli="+specificDockerVersion, "containerd.io", "docker-compose-plugin"))
} else {
installFirstLine := append(op.InstallCommandPrefix, []string{
"yum-utils",
"device-mapper-persistent-data",
"lvm2",
}...)
if op.IsAgentInnerWall {
// inner gfw
installDockerFunc = append(installDockerFunc, [][]string{
installFirstLine,
{
"yum-config-manager",
"--add-repo",
"https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo",
},
{
"sed ",
"-i ",
"'s/download.docker.com/mirrors.ustc.edu.cn\\/docker-ce/g' ",
"/etc/yum.repos.d/docker-ce.repo",
},
{},
}...)
} else {
// outside world
}
}
return installDockerFunc
}
func (op *AgentOsOperator) installDockerExec(args []string) (bool, []string) {
BasicCreateFolder(OctopusAgentInstallPrefix)
op.removeDockerExec()
if op.IsOsTypeUbuntu {
if !op.CanAccessInternet {
// offline version
log.InfoF("[installDockerExec] - can not access to internet, installing by offline !")
return op.InstallDockerBastion()
}
installDependencyCommand := append(op.InstallCommandPrefix, []string{
"apt-transport-https",
"ca-certificates",
"curl",
"gnupg",
"software-properties-common",
}...)
ok, l := AllCommandExecutor(installDependencyCommand)
if !ok {
//
return false, l
}
dockerGPGFilePath := "/etc/apt/keyrings/docker.gpg"
dockerAPTFilePath := "/etc/apt/sources.list.d/docker.list"
dockerGPGSource := "https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg"
dockerAPTSource := "https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu"
executor, resultLog := AllCompleteExecutor([][]string{
{
"rm",
"-rf",
dockerGPGFilePath,
},
{
"rm",
"-rf",
dockerAPTFilePath,
},
{
"mkdir",
"-p",
"/etc/apt/keyrings",
},
{
"install",
"-m",
"0755",
"-d",
"/etc/apt/keyrings",
},
})
if !executor {
return false, append(resultLog, "创建docker-key gpg文件失败")
}
// 安装镜像的证书
if !op.IsAgentInnerWall {
// outside world
dockerGPGSource = "https://download.docker.com/linux/ubuntu/gpg"
dockerAPTSource = "https://download.docker.com/linux/ubuntu"
}
ok, l2 := PipelineCommandExecutor([][]string{
{
"curl",
"-fsSL",
dockerGPGSource,
},
{
"gpg",
"--dearmor",
"-o",
dockerGPGFilePath,
},
})
if !ok {
return false, append(l2, "下载docker gpg文件失败", dockerGPGSource, dockerAPTSource)
}
if !BasicFileExistAndNotNull(dockerGPGFilePath) {
return false, []string{"添加gpg失败"}
}
resultOk, log2 := AllCompleteExecutor([][]string{
{
"chmod",
"a+r",
dockerGPGFilePath,
}, //{
// "add-apt-repository",
// "deb [arch=" + op.AgentArch + " signed-by=" + dockerGPGFilePath + " ] " + dockerAPTSource + " " + op.AgentOSReleaseCode + " stable",
//},
})
if !resultOk {
return false, append(log2, "添加APT源失败")
}
dockerAPTSourceCommand := "deb [arch=" + op.AgentArch + " signed-by=" + dockerGPGFilePath + "] " + dockerAPTSource + " " + op.AgentOSReleaseCode + " stable"
log.InfoF("dockerAPTSourceCommand is => %s ", dockerAPTSourceCommand)
ok, log3 := PipelineCommandExecutor([][]string{
{
"echo",
dockerAPTSourceCommand,
},
{
"tee",
dockerAPTFilePath,
},
})
if !ok {
return false, append(log3, "添加APT源失败")
}
// look for specific docker-version to install
AllCommandExecutor([]string{"apt-get", "update"})
// 补充参数
if args == nil {
args = []string{
"20",
}
}
// 20.04 default
specificDockerVersion := "5:20.10.20~3-0~ubuntu-" + op.AgentOSReleaseCode
// apt-cache madison docker-ce | grep 20.10.20 | awk '{print$3}'
// get by method
ok, log4 := HardCodeCommandExecutor("apt-cache madison docker-ce | grep 20.10.20 | awk '{print$3}'")
if ok && log4 != nil && len(log4) > 0 {
specificDockerVersion = strings.TrimSpace(log4[0])
fmt.Println("get docker version from online => " + specificDockerVersion)
}
log.InfoF("需要安装的docker版本为 => %s", specificDockerVersion)
dockerStaffList := []string{
"docker-ce=" + specificDockerVersion,
"docker-ce-cli=" + specificDockerVersion,
"containerd.io",
"docker-compose-plugin",
}
for _, s := range dockerStaffList {
resultOk, log2 = AllCommandExecutor(append(op.InstallCommandPrefix, s))
if !resultOk {
return false, append(log2, s, "安装失败!")
}
}
// 启动docker服务
completeExecutor, log5 := AllCompleteExecutor([][]string{
{
"systemctl",
"stop",
"docker.service",
},
{
"sleep",
"2",
},
{
"systemctl",
"start",
"docker.service",
},
{
"systemctl",
"enable",
"docker.service",
},
})
if !completeExecutor {
return false, append(log5, "启动docker.service失败请查明原因", "journalctl -u docker -n 100 -f")
}
} else if op.IsOsTypeCentOS {
if !op.CanAccessInternet || op.IsOsTypeEuler {
// offline version
log.InfoF("[installDockerExec] - centos can not access to internet, installing by offline !")
return op.InstallDockerBastion()
}
// download
var dockerRepo string
if op.IsAgentInnerWall {
dockerRepo = "https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo"
} else {
dockerRepo = "https://download.docker.com/linux/centos/docker-ce.repo"
}
AllCommandExecutor(append(op.InstallCommandPrefix, "yum-utils"))
ok, resultLog := AllCommandExecutor([]string{
"yum-config-manager",
"--add-repo",
dockerRepo,
})
if !ok {
return false, resultLog
}
// todo 20 version
resultOk, l := AllCommandExecutor(append(op.InstallCommandPrefix, "docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin"))
if !resultOk {
return false, l
}
systemdUp, log2 := BasicSystemdUp("docker")
if !systemdUp {
return false, log2
}
}
return true, []string{
"docker安装成功",
}
}
func (op *AgentOsOperator) InstallDockerBastion() (bool, []string) {
// check offline file exits
log.InfoF("[InstallDockerBastion] - install docker 20.10.15 by local file method !")
BasicCreateFolder("/root/wdd")
// install docker
var dockerOfflineFileName string
if strings.HasPrefix(op.AgentArch, "amd") {
dockerOfflineFileName = "docker-amd64-20.10.15.tgz"
} else if strings.HasPrefix(op.AgentArch, "arm64") {
dockerOfflineFileName = "docker-arm64-20.10.15.tgz"
}
BasicRemoveFolderComplete("/root/wdd/docker")
dockerLocalFile := OctopusAgentInstallPrefix + dockerOfflineFileName
// 下载
if op.CanAccessInternet {
log.Info("[InstallDockerBastion] - start to download docker offline file!")
BasicDownloadFile(op.OssOfflinePrefix+dockerOfflineFileName, "", "", "", dockerLocalFile)
}
if !BasicFileExistAndNotNull(dockerLocalFile) {
sprintf := fmt.Sprintf("docker offline file not exists ! => %s", dockerLocalFile)
log.Error(sprintf)
return false, []string{sprintf}
}
PureResultSingleExecute([]string{
"tar",
"-vxf",
dockerLocalFile,
"-C",
"/root/wdd",
})
HardCodeCommandExecutor("chmod 777 -R /root/wdd/docker/*")
resultOk, l := HardCodeCommandExecutor("mv /root/wdd/docker/* /usr/bin")
if !resultOk {
return false, append(l, "[InstallDockerBastion] - cp docker executable file error!")
}
// daemon docker
// systemd daemonize docker
BasicAppendOverwriteContentToFile(beans.ContainerdDaemonService, beans.ContainerdServiceFile)
if !BasicFileExistAndNotNull(beans.ContainerdServiceFile) {
return false, []string{"docker deamon file not exists !"}
}
BasicAppendOverwriteContentToFile(beans.DockerSocketDaemonService, beans.DockerSocketFile)
if !BasicFileExistAndNotNull(beans.DockerSocketFile) {
return false, []string{"docker deamon file not exists !"}
}
BasicAppendOverwriteContentToFile(beans.DockerDaemonService, beans.DockerServiceFile)
if !BasicFileExistAndNotNull(beans.DockerServiceFile) {
return false, []string{"docker deamon file not exists !"}
}
log.InfoF("[InstallDockerBastion] - docker dameon file append success !")
// run the docker
executor, log3 := AllCommandExecutor([]string{
"systemctl",
"daemon-reload",
})
if !executor {
return false, append(log3, "[InstallDockerBastion] - daemon reload error !")
}
AllCompleteExecutor([][]string{
{
"systemctl",
"unmask",
"containerd",
},
{
"systemctl",
"unmask",
"docker.socket",
},
{
"systemctl",
"unmask",
"docker",
},
})
AllCompleteExecutor([][]string{
{
"groupadd",
"docker",
},
{
"usermod",
"-aG",
"docker",
"root",
},
{
"newgrp",
"docker",
},
})
systemdUp, _ := BasicSystemdUp("containerd")
if !systemdUp {
log.Warn("[InstallDockerBastion] - start containerd service error !")
}
commandExecutor, _ := AllCompleteExecutor([][]string{
{
"systemctl",
"start",
"docker.socket",
},
{
"systemctl",
"enable",
"docker.socket",
},
})
if !commandExecutor {
log.Warn("[InstallDockerBastion] - start docker.socket error !")
}
up, log4 := BasicSystemdUp("docker")
if !up {
return false, append(log4, "[InstallDockerBastion] - start docker service error !")
}
return true, []string{
"[InstallDockerBastion] - docker offline installation from local success!",
}
}
func (op *AgentOsOperator) removeDockerCompose() [][]string {
installDockerComposeFunc := [][]string{
append(op.RemoveCommandPrefix, "docker-compose"),
}
return installDockerComposeFunc
}
func (op *AgentOsOperator) removeDockerComposeExec() (bool, []string) {
commandName := "docker-compose"
if !BasicCommandExists(commandName) {
return true, []string{
commandName + " 卸载成功!",
}
}
possibleDockerComposeFilePath := []string{
"/usr/local/bin/" + commandName,
"/usr/bin/" + commandName,
}
for _, s := range possibleDockerComposeFilePath {
removeDockerCommand := append(RemoveForcePrefix, s)
AllCommandExecutor(removeDockerCommand)
}
return true, []string{
commandName + " 卸载成功!",
}
}
func (op *AgentOsOperator) installDockerCompose() [][]string {
installDockerComposeFunc := [][]string{
append(op.InstallCommandPrefix, "docker-compose"),
}
return installDockerComposeFunc
}
func (op *AgentOsOperator) installDockerComposeExec() (bool, []string) {
log.Info("准备安装docker-compose!")
// 安装特定版本的 docker-compose 2.18.0
if op.OssOfflinePrefix == "" {
return false, []string{"离线下载OSS地址不存在 无法安装 docker-compose"}
}
var DockerComposeFile string
if strings.HasPrefix(op.AgentArch, "amd") {
DockerComposeFile = op.OssOfflinePrefix + "docker-compose-linux-x86_64-v2.18.0"
} else if strings.HasPrefix(op.AgentArch, "arm64") {
DockerComposeFile = op.OssOfflinePrefix + "docker-compose-linux-aarch64-v2.18.0"
}
log.InfoF("需要安装的docker版本为 => %s", DockerComposeFile)
ok, resultLog := BasicDownloadFile(DockerComposeFile, "", "", "", "/usr/local/bin/docker-compose")
if !ok {
return false, resultLog
}
log.Debug("docker-compose下载成功!")
AllCompleteExecutor([][]string{
{
"chmod", "+x", "/usr/local/bin/docker-compose",
},
{
"ln", "-s", "/usr/local/bin/docker-compose", "/usr/bin/docker-compose",
},
})
log.Info("docker-compose安装成功")
return true, []string{"docker-compose安装成功"}
}
func (op *AgentOsOperator) InstallDockerComposeBastion() (bool, []string) {
log.Info("准备安装docker-compose => 版本为 2.18.0 !")
var DockerComposeFile string
if strings.HasPrefix(op.AgentArch, "amd") {
DockerComposeFile = OctopusAgentInstallPrefix + "docker-compose-linux-x86_64-v2.18.0"
} else if strings.HasPrefix(op.AgentArch, "arm64") {
DockerComposeFile = OctopusAgentInstallPrefix + "docker-compose-linux-aarch64-v2.18.0"
}
// check file exits
if !BasicFileExistAndNotNull(DockerComposeFile) {
sprintf := fmt.Sprintf("docker-compose 离线安装文件不存在! => %s", DockerComposeFile)
return false, []string{
sprintf,
}
}
AllCompleteExecutor([][]string{
{
"mv",
DockerComposeFile,
"/usr/local/bin/docker-compose",
},
{
"chmod", "+x", "/usr/local/bin/docker-compose",
},
{
"ln", "-s", "/usr/local/bin/docker-compose", "/usr/bin/docker-compose",
},
})
log.Info("docker-compose安装成功")
if !BasicCommandExistByPath("docker-compose") {
return false, []string{
"[InstallDockerComposeBastion] - docker-compose 安装失败!",
}
}
return true, []string{
"[InstallDockerComposeBastion] - docker-compose offline installation from local success!",
}
}
func (op *AgentOsOperator) installHelm() [][]string {
installHelmFunc := [][]string{
{
"mkdir",
"-p",
OctopusAgentInstallPrefix,
},
{
"rm",
"-rf",
"/root/wdd/helm-v*",
},
{
"rm",
"-rf",
"/root/wdd/linux-amd64",
},
{
"wget",
"--no-check-certificate",
op.OssOfflinePrefix + "helm-v3.12.1-linux-amd64.tar.gz",
"-O",
"/root/wdd/helm-v3.12.1-linux-amd64.tar.gz",
},
{
"tar",
"-zvxf",
"/root/wdd/helm-v3.12.1-linux-amd64.tar.gz",
},
{
"chmod",
"+x",
"/root/wdd/linux-amd64/helm",
},
{
"mv",
"/root/wdd/linux-amd64/helm",
"/usr/local/bin/helm",
},
{
"helm",
"version",
},
}
/*if op.IsOsTypeUbuntu {
installHelmFunc = [][]string{
{
"curl",
"-o",
"/etc/apt/keyrings/helm.gpg",
"https://baltocdn.com/helm/signing.asc",
},
{
"apt-key",
"add",
"/etc/apt/keyrings/helm.gpg",
},
{
"add-apt-repository",
"https://baltocdn.com/helm/stable/debian/ all main",
},
{
"apt-get",
"update",
},
append(op.InstallCommandPrefix, "helm"),
}
} else {
log.ErrorF("Operation OS is CentOS, Helm not installed!")
}*/
return installHelmFunc
}
func (op *AgentOsOperator) installHelmExec() (bool, []string) {
return true, []string{
"[installHelmExec] - pretend to install helm success !",
}
}
func (op *AgentOsOperator) modifyDockerConfig(args []string) [][]string {
harborIPAddr := args[0] + ":8033"
modifyDockerConfigFunc := [][]string{
{
"mv",
"/etc/docker/daemon.json",
"/etc/docker/daemon.backup.json",
},
{
"wget",
op.OssOfflinePrefix + "daemon-config.json",
"-O",
"/etc/docker/daemon.json",
},
{
"sed",
"-i",
"s/$DockerRegisterDomain/" + harborIPAddr + "/g",
"/etc/docker/daemon.json",
},
{
"systemctl",
"restart",
"docker.service",
},
}
return modifyDockerConfigFunc
}
func (op *AgentOsOperator) ModifyDockerConfigBastion() (bool, []string) {
dockerDaemonFile := "/etc/docker/daemon.json"
// check docker daemon json exist
if BasicFileExistAndNotNull(dockerDaemonFile) {
AllCommandExecutor([]string{
"mv",
dockerDaemonFile,
"/etc/docker/daemon-json.backup",
})
}
// download new
if !BasicAppendOverwriteContentToFile(beans.DockerDeamonConfig, dockerDaemonFile) {
return false, []string{
"[ModifyDockerConfigBastion] - modify docker daemon config error !",
}
}
if !BasicReplace(dockerDaemonFile, "DockerRegisterDomain", op.AgentServerInfo.ServerIPInV4) {
return false, []string{
"[ModifyDockerConfigBastion] - modify docker daemon config error !",
}
}
log.InfoF("[ModifyDockerConfigBastion] - 修改docker配置成功 => %s", op.AgentServerInfo.ServerIPInV4)
// restart docker
if !PureResultSingleExecute([]string{
"systemctl",
"restart",
"docker.service",
}) {
return false, []string{
"[ModifyDockerConfigBastion] - restart docker.service error !",
}
}
return true, []string{
"[ModifyDockerConfigBastion] - 修改docker配置成功",
}
}
func (op *AgentOsOperator) modifyDockerConfigExec(args []string) (bool, []string) {
dockerDaemonFile := "/etc/docker/daemon.json"
// check docker daemon json exist
if BasicFileExistAndNotNull(dockerDaemonFile) {
AllCommandExecutor([]string{
"mv",
dockerDaemonFile,
"/etc/docker/daemon-json.backup",
})
}
// download new
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+"docker-daemon-template.json", "", "", "", dockerDaemonFile)
if !ok {
return false, append(resultLog, "[modifyDockerConfigExec] - error download docker-daemon-template.json !")
}
// modify config
parseIP := net.ParseIP(args[0])
if parseIP == nil {
return false, []string{
"[modifyDockerConfigExec] - ip args error !",
args[0],
}
}
if !BasicReplace(dockerDaemonFile, "DockerRegisterDomain", args[0]) {
return false, []string{
"[modifyDockerConfigExec] - modify docker daemon config error !",
}
}
// restart docker
if !PureResultSingleExecute([]string{
"systemctl",
"restart",
"docker.service",
}) {
return false, []string{
"[modifyDockerConfigExec] - restart docker.service error !",
}
}
return true, nil
}
func (op *AgentOsOperator) installNfsOnlineExec() (bool, []string) {
if !op.CanAccessInternet {
return op.installNFSOfflineExec()
}
if op.IsOsTypeUbuntu {
// ubuntu
installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, false, "nfs-common", "nfs-client", "nfs")
if !installOk {
return false, installLog
}
ok, resultLog := BasicSystemdUp("nfs")
if !ok {
return false, append(resultLog, "[installNfsOnlineExec] - start nfs-common.service failed !")
}
} else if op.IsOsTypeCentOS {
// centos
installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, false, "nfs-utils")
if !installOk {
return false, installLog
}
ok, resultLog := BasicSystemdUp("rpcbind")
if !ok {
return false, append(resultLog, "[installNfsOnlineExec] - start rpcbind.service failed !")
}
}
return true, nil
}
func (op *AgentOsOperator) installNFSOfflineExec() (bool, []string) {
log.InfoF("[installNFSOfflineExec] - start to install nfs-client offline !")
BasicCreateFolder("/root/wdd")
// check for version
//executor, i := HardCodeCommandExecutor("grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '\"' | sed 's/ /-/g'")
//if !executor {
// return false, append(i, "[installNFSOfflineExec]- get offline package name suffix error !")
//}
// 2024年1月19日 new version
nfsClientOfflinePackageName := "nfs-client-" + op.AgentArch + "-" + op.AgentServerInfo.Platform + "-" + op.AgentServerInfo.PlatformVersion + ".tar.gz"
// download from oss
nfsClientOfflinePackageOSSUrl := op.OssOfflinePrefix + nfsClientOfflinePackageName
log.InfoF("[installNFSOfflineExec]- start to download nfs-client offline package from => %s", nfsClientOfflinePackageOSSUrl)
ok, resultLog := BasicDownloadFile(nfsClientOfflinePackageOSSUrl, "", "", "", OctopusAgentInstallPrefix+nfsClientOfflinePackageName)
if !ok {
return false, append(resultLog, "[installNFSOfflineExec]- download nfs-client offline package error !", nfsClientOfflinePackageOSSUrl)
}
BasicRemoveFolderComplete("/root/wdd/tmp")
// unzip
AllCommandExecutor([]string{
"tar",
"-zvxf",
OctopusAgentInstallPrefix + nfsClientOfflinePackageName,
"-C",
"/root/wdd",
})
// install
if op.IsOsTypeUbuntu {
BasicPrettyPrint(HardCodeCommandExecutor("dpkg -i /root/wdd/tmp/nfs-client/*.deb"))
} else if op.IsOsTypeCentOS {
BasicPrettyPrint(HardCodeCommandExecutor("rpm -ivh /root/wdd/tmp/nfs-client/*.rpm"))
}
ok, resultLog = BasicSystemdUp("nfs")
if !ok {
return false, append(resultLog, "[installNFSOfflineExec] - start nfs-common.service failed !")
}
return true, []string{
"[installNFSOfflineExec] - install success !",
}
}
func (op *AgentOsOperator) installNfsServerOnlineExec() (bool, []string) {
if !op.CanAccessInternet {
return op.installNFSServerOfflineExec()
}
if !PureResultSingleExecuteBatch([][]string{
{"mkdir", "-p", nfsDataPath},
{"chmod", "777", nfsDataPath},
}) {
return false, []string{
"[installNfsServerOnlineExec]- create nfs data folder failed !",
}
}
if !BasicFindContentInFile(nfsDataPath, "/etc/exports") {
log.DebugF("[installNfsServerOnlineExec]- add nfs path to /etc/exports !")
nfsExport := nfsDataPath + " *(rw,no_root_squash,no_all_squash,sync)"
if !BasicAppendContentToFile(nfsExport, "/etc/exports") {
return false, []string{
"[installNfsServerOnlineExec]- add nfs path to /etc/exports failed !",
}
}
}
// os
if op.IsOsTypeUbuntu {
// ubuntu
installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, true, "nfs-kernel-server", "nfs-common")
if !installOk {
return false, installLog
}
// restart nfs-server
up, resultLog := BasicSystemdUp("nfs-kernel-server")
if !up {
msg := "[installNfsServerOnlineExec]- nfs-kernel-server start error"
log.Error(msg)
return false, append(resultLog, msg)
}
} else {
// CentOS
installOk, installLog := BasicInstallSoftware(op.InstallCommandPrefix, true, "nfs-utils")
if !installOk {
return false, installLog
}
// restart nfs-server
up, resultLog := BasicSystemdUp("rpcbind")
if !up {
msg := "[installNfsServerOnlineExec]- rpcbind start error"
log.Error(msg)
return false, append(resultLog, msg)
}
up, resultLog = BasicSystemdUp("nfs-server")
if !up {
msg := "[installNfsServerOnlineExec]- nfs-server start error"
log.Error(msg)
return false, append(resultLog, msg)
}
}
ok, i := HardCodeCommandExecutor("rpcinfo -p localhost")
if !ok {
return false, append(i, "installNfsServerOnlineExec] - rpc info error !", "please check nfs server installation")
}
return true, nil
}
func (op *AgentOsOperator) installNFSServerOfflineExec() (bool, []string) {
log.InfoF("[installNFSServerOfflineExec] - start to install nfs server offline !")
if !BasicCreateFolder("/root/wdd") {
return false, []string{
"[installNFSServerOfflineExec] - create install folder error !",
}
}
// check for the version
//executor, i := HardCodeCommandExecutor("grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '\"' | sed 's/ /-/g'")
//if !executor {
// return false, append(i, "[installNFSServerOfflineExec]- get offline package name suffix error !")
//}
nfsServerOfflinePackageName := "nfs-server-" + op.AgentArch + "-" + op.AgentServerInfo.Platform + "-" + op.AgentServerInfo.PlatformVersion + ".tar.gz"
// download from oss
nfsServerOfflinePackageOSSUrl := op.OssOfflinePrefix + nfsServerOfflinePackageName
log.InfoF("[installNFSServerOfflineExec]- start to download nfs-server offline package from => %s", nfsServerOfflinePackageOSSUrl)
ok, resultLog := BasicDownloadFileByCurl(nfsServerOfflinePackageOSSUrl, OctopusAgentInstallPrefix+nfsServerOfflinePackageName)
if !ok {
return false, append(resultLog, "[installNFSServerOfflineExec]- download nfs-server offline package error !", nfsServerOfflinePackageOSSUrl)
}
BasicRemoveFolderComplete("/root/wdd/tmp")
// unzip
AllCommandExecutor([]string{
"tar",
"-zvxf",
OctopusAgentInstallPrefix + nfsServerOfflinePackageName,
"-C",
"/root/wdd",
})
if !PureResultSingleExecuteBatch([][]string{
{"mkdir", "-p", nfsDataPath},
{"chmod", "777", nfsDataPath},
}) {
return false, []string{
"[installNFSServerOfflineExec]- create nfs data folder failed !",
}
}
if !BasicFindContentInFile(nfsDataPath, "/etc/exports") {
log.DebugF("[installNFSServerOfflineExec]- add nfs path to /etc/exports !")
nfsExport := nfsDataPath + " *(rw,no_root_squash,no_all_squash,sync)"
if !BasicAppendContentToFile(nfsExport, "/etc/exports") {
return false, []string{
"[installNFSServerOfflineExec]- add nfs path to /etc/exports failed !",
}
}
}
// install
if op.IsOsTypeUbuntu {
BasicPrettyPrint(HardCodeCommandExecutor("dpkg -i /root/wdd/tmp/nfs-server/*.deb"))
up, resultLog := BasicSystemdUp("nfs-kernel-server")
if !up {
msg := "[installNfsServerOnlineExec]- nfs-kernel-server start error"
log.Error(msg)
return false, append(resultLog, msg)
}
} else if op.IsOsTypeCentOS {
BasicPrettyPrint(HardCodeCommandExecutor("rpm -ivh /root/wdd/tmp/nfs-server/*.rpm"))
// restart nfs-server
up, resultLog := BasicSystemdUp("rpcbind")
if !up {
msg := "[installNfsServerOnlineExec]- rpcbind start error"
log.Error(msg)
return false, append(resultLog, msg)
}
up, resultLog = BasicSystemdUp("nfs-server")
if !up {
msg := "[installNfsServerOnlineExec]- nfs-server start error"
log.Error(msg)
return false, append(resultLog, msg)
}
}
rpcinfoOK, i := HardCodeCommandExecutor("rpcinfo -p localhost")
if !rpcinfoOK {
return false, append(i, "[installNFSServerOfflineExec] - rpc info error !", "please check nfs server installation")
}
return true, []string{
"[installNFSServerOfflineExec] - install success !",
}
}
func (op *AgentOsOperator) installHarbor() [][]string {
installHarborFunc := [][]string{
//{
// "mkdir",
// "-p",
// OctopusAgentInstallPrefix,
//},
//{
// "rm",
// "-rf",
// "/root/wdd/harbor-offline-installer-v2.9.0.tgz",
//},
//{
// "wget",
// "--no-check-certificate",
// op.OssOfflinePrefix + "harbor-offline-installer-v2.9.0.tgz",
// "-O",
// "/root/wdd/harbor-offline-installer-v2.9.0.tgz",
//},
{
"tar",
"-zvxf",
"/root/wdd/harbor-offline-installer-v2.9.0.tgz",
"-C",
OctopusAgentInstallPrefix,
},
{
"rm",
"-rf",
"/root/wdd/harbor/harbor.yml",
},
{
"wget",
"--no-check-certificate",
op.OssOfflinePrefix + "harbor-config-template.yml",
"-O",
"/root/wdd/harbor/harbor.yml",
},
{
"sed",
"-i",
"s/HarborHostName/" + op.AgentServerInfo.ServerIPInV4 + "/g",
"/root/wdd/harbor/harbor.yml",
},
{
"sed",
"-i",
"s/HarborHostPort/8033/g",
"/root/wdd/harbor/harbor.yml",
},
{
"sed",
"-i",
"s/HarborAdminPas/V2ryStr@ngPss/g",
"/root/wdd/harbor/harbor.yml",
},
{
"/root/wdd/harbor/install.sh",
"--with-chartmuseum",
},
}
return installHarborFunc
}
func (op *AgentOsOperator) checkHarborInstallExec() (bool, []string) {
// check docker-compose
if !BasicCommandExistByPath("docker-compose") {
return false, []string{
"[install harbor] - docker-compose uninstalled ! can't install harbor!",
}
}
// check already installed
ok, _ := PipelineCommandExecutor([][]string{
{
"docker",
"ps",
},
{
"grep",
"-q",
"harbor-core",
},
})
if ok {
alreadyInstalledLog := []string{
"[install harbor] - container harbor-core already running! harbor installed !",
}
log.Info(alreadyInstalledLog[0])
resultOk, resultLog := AllCommandExecutor([]string{
"docker-compose",
"-f",
"/root/wdd/harbor/docker-compose.yml",
"up",
"-d",
})
if !resultOk {
alreadyInstalledLog = append(alreadyInstalledLog, "restart docker-compose file failed !")
return false, append(alreadyInstalledLog, resultLog...)
} else {
return true, append(alreadyInstalledLog, "restart docker-compose file success !")
}
}
if strings.HasPrefix(op.AgentArch, "arm64") {
return false, []string{
"[install harbor] - script do not support for aarch64 version of harbor installation !",
}
}
return true, []string{
"[install harbor] - check harbor installation environment success !",
}
}
// installHarborExec install harbor offline
func (op *AgentOsOperator) installHarborExec() (bool, []string) {
// 抽离
checkHarborInstallExec, i := op.checkHarborInstallExec()
if !checkHarborInstallExec {
return false, i
}
// download offline file
harborOfflineFileURL := op.OssOfflinePrefix + "harbor-offline-installer-v2.9.0.tgz"
log.InfoF("[install harbor] - start to download harbor offline installer from => %s !", harborOfflineFileURL)
BasicCreateFolder(OctopusAgentInstallPrefix)
BasicRemoveFolderComplete("/root/wdd/harbor-offline-installer-v2.9.0.tgz")
BasicRemoveFolderComplete("/root/wdd/harbor")
log.Info("[install harbor] - start to download harbor offline installation file!")
downloadOk, l := BasicDownloadFile(harborOfflineFileURL, "", "", "", "/root/wdd/harbor-offline-installer-v2.9.0.tgz")
if !downloadOk {
return false, append(l, "download harbor offline installer failed!")
}
// unzip
AllCompleteExecutor([][]string{
{
"tar",
"-zvxf",
"/root/wdd/harbor-offline-installer-v2.9.0.tgz",
"-C",
OctopusAgentInstallPrefix,
},
{
"rm",
"-rf",
"/root/wdd/harbor/harbor.yml",
},
})
// configuration
log.Info("[install harbor] - start to download harbor config file!")
ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+"harbor-config-template.yml", "", "", "", "/root/wdd/harbor/harbor.yml")
if !ok {
return false, resultLog
}
// install and config
installHarborAndConfig, i2 := op.installHarborAndConfig()
if !installHarborAndConfig {
return false, i2
}
msg := "[install harbor] - harbor start complete !"
log.Info(msg)
return true, []string{msg}
}
func (op *AgentOsOperator) installHarborAndConfig() (bool, []string) {
log.Info("[install harbor] - start to modify harbor config file!")
AllCommandExecutor([]string{
"chmod",
"+x",
"/root/wdd/harbor/install.sh",
})
BasicReplace("/root/wdd/harbor/harbor.yml", "HarborHostName", op.AgentServerInfo.ServerIPInV4)
BasicReplace("/root/wdd/harbor/harbor.yml", "HarborHostPort", "8033")
BasicReplace("/root/wdd/harbor/harbor.yml", "HarborAdminPas", "V2ryStr@ngPss")
log.InfoF("[install harbor] - harbor config file changed to => %s %s %s !\n", op.AgentServerInfo.ServerIPInV4, "8033", "V2ryStr@ngPss")
// install
log.Info("[install harbor] - going to start harbor !")
executor := ReadTimeCommandExecutor([]string{
"bash",
"/root/wdd/harbor/install.sh",
})
if !executor {
return false, []string{
"[install harbor] - harbor start FAILED !",
}
}
return true, nil
}
func (op *AgentOsOperator) InstallHarborBastion() (bool, []string) {
// 抽离
checkHarborInstallExec, i := op.checkHarborInstallExec()
if !checkHarborInstallExec {
return false, i
}
// local file check exists
if !BasicFileExistAndNotNull("/root/wdd/harbor-offline-installer-v2.9.0.tgz") {
sprintf := fmt.Sprintf("[InstallHarborBastion] - harbor offline installer not exists ! => %s", "/root/wdd/harbor-offline-installer-v2.9.0.tgz")
return false, []string{sprintf}
}
// unzip
AllCompleteExecutor([][]string{
{
"tar",
"-zvxf",
"/root/wdd/harbor-offline-installer-v2.9.0.tgz",
"-C",
OctopusAgentInstallPrefix,
},
{
"rm",
"-rf",
"/root/wdd/harbor/harbor.yml",
},
})
// configuration
if !BasicAppendOverwriteContentToFile(beans.HarborTemplateFile, "/root/wdd/harbor/harbor.yml") {
return false, []string{
"[InstallHarborBastion] - harbor config file append failed !",
}
}
// install and config
installHarborAndConfig, i2 := op.installHarborAndConfig()
if !installHarborAndConfig {
return false, i2
}
msg := "[InstallHarborBastion] - harbor install SUCCESSES !"
log.Info(msg)
return true, []string{msg}
}
func (op *AgentOsOperator) restartHarborExec() (bool, []string) {
// check pods all run
allHarborContainerName := []string{
"harbor-log",
"harbor-db",
"harbor-portal",
"redis",
"registryctl",
"registry",
"registry",
"harbor-core",
"nginx",
"harbor-jobservice",
}
harborServiceRunningHealthy := true
for _, container := range allHarborContainerName {
ok, _ := PipelineCommandExecutor([][]string{
{
"docker",
"ps",
},
{
"grep",
"-c",
container,
},
})
if !ok {
harborServiceRunningHealthy = false
msg := fmt.Sprintf("[restartHarborExec] - harbor service unhealthy, container [ %s ] not running, prepare to restart !", container)
log.Warn(msg)
break
}
}
if harborServiceRunningHealthy {
return true, []string{
"[restartHarborExec] - harbor container run healthy !",
}
}
// docker-compose.yml exists
harborDockerComposeFile := "/root/wdd/harbor/docker-compose.yml"
if !BasicFileExistAndNotNull(harborDockerComposeFile) {
errorLog := fmt.Sprintf("[restartHarborExec] - harborDockerComposeFile %s not exist !", harborDockerComposeFile)
log.Error(errorLog)
return false, []string{
errorLog,
}
}
// execute docker-compose up
if !BasicCommandExists("docker-compose") {
return false, []string{
"[restartHarborExec] - docker-compose not exist !",
}
}
log.InfoF("[restartHarborExec] - prepare to restart harbor docker compose !")
ok, resultLog := AllCommandExecutor([]string{
"docker-compose",
"-f",
harborDockerComposeFile,
"up",
"-d",
})
if !ok {
return false, resultLog
}
// wait
// check pods all run
for _, container := range allHarborContainerName {
ok, _ := PipelineCommandExecutor([][]string{
{
"docker",
"ps",
},
{
"grep",
"-c",
container,
},
})
if !ok {
errLog := fmt.Sprintf("[restartHarborExec] - harbor service [ %s ] restart failed !", container)
log.Error(errLog)
return false, []string{
errLog,
}
}
}
return true, []string{
"[restartHarborExec] - harbor container restarted and run healthy !",
}
}
func (op *AgentOsOperator) chronyToPublicNTP() [][]string {
serverIPInV4 := op.AgentServerInfo.ServerIPInV4
internalIPCIDR := strings.Join(strings.Split(serverIPInV4, ".")[:2], ".") + ".0.0/16"
chronyToPublicNTPFunc := [][]string{
append(op.InstallCommandPrefix, "chrony"),
{
"systemctl",
"enable",
"chronyd",
},
{
"systemctl",
"start",
"chronyd",
},
}
var chronyFile string
if op.IsOsTypeUbuntu {
chronyFile = "/etc/chrony/chrony.conf"
} else {
chronyFile = "/etc/chrony.conf"
}
chronyToPublicNTPFunc = append(chronyToPublicNTPFunc, [][]string{
{
"sed",
"-i",
"$ a allow " + internalIPCIDR,
chronyFile,
},
{
"sed",
"-i",
"s/pool ntp.ubuntu.com iburst/server ntp2.aliyun.com iburst/g",
chronyFile,
},
{
"systemctl",
"restart",
"chronyd",
},
{
"sleep",
"2",
},
{
"chronyc",
"-n",
"sources",
"-v",
},
{
"chronyc",
"tracking",
},
{
"timedatectl",
"set-timezone",
"Asia/Shanghai",
},
{
"timedatectl",
"set-ntp",
"true",
},
{
"systemctl",
"restart",
"rsyslog",
},
}...)
return chronyToPublicNTPFunc
}
func (op *AgentOsOperator) chronyToPublicNTPExec() (bool, []string) {
var chronyFile string
if op.IsOsTypeUbuntu {
chronyFile = "/etc/chrony/chrony.conf"
} else {
chronyFile = "/etc/chrony.conf"
}
ok, resultLog := AllCompleteExecutor([][]string{
{
"sed",
"-i",
"$ a allow all",
chronyFile,
},
{
"sed",
"-i",
"s/pool ntp.ubuntu.com/server ntp2.aliyun.com/g",
chronyFile,
},
{
"systemctl",
"restart",
"chronyd",
},
{
"timedatectl",
"set-timezone",
"Asia/Shanghai",
},
{
"sleep",
"2",
}})
if !ok {
return false, resultLog
}
_, l := AllCompleteExecutor([][]string{
{
"chronyc",
"-n",
"sources",
"-v",
},
{
"chronyc",
"tracking",
},
{
"chronyc",
"clients",
},
})
// check chrony
return true, l
}
// installChronyExec make sure chrony is installed
func (op *AgentOsOperator) installChronyExec() (bool, []string) {
// uninstall systemd-timesyncd.service
ok, resultLog := BasicSystemdShutdown("systemd-timesyncd.service")
if !ok {
return false, resultLog
}
// install chrony
resultOk, l := AllCommandExecutor(append(op.InstallCommandPrefix, "chrony"))
if !resultOk {
return false, l
}
// check installation
fileExistAndNotNull := BasicFileExistAndNotNull("/etc/chrony/chrony.conf")
if !fileExistAndNotNull {
return false, []string{
"chrony config file is null !",
"chrony installation is failed !",
"please check!"}
}
up, log2 := BasicSystemdUp("chrony.service")
if !up {
return false, log2
}
return true, nil
}
func (op *AgentOsOperator) installChronyByDockerExec(funcArgs []string) (bool, []string) {
// check docker
if !BasicCommandExistByPath("docker") {
return false, []string{
"[installChronyByDockerExec] - docker not installed exited !",
}
}
parseIP := net.ParseIP(funcArgs[0])
if parseIP == nil {
return false, []string{
"[installChronyByDockerExec] - ip args error !",
}
}
chronyCommand := []string{
"docker",
"run",
"--name=chrony",
"--restart=always",
"--detach",
"--cap-add=SYS_TIME",
"--publish=123:123/udp",
"--env=LOG_LEVEL=0",
"--env=TZ=Asia/Shanghai",
"--env=ENABLE_SYSCLK=true",
}
if op.CanAccessInternet {
chronyCommand = append(chronyCommand, "--env=NTP_SERVERS=\"ntp1.aliyun.com,ntp2.aliyun.com,ntp3.aliyun.com,ntp4.aliyun.com\"")
} else {
chronyCommand = append(chronyCommand, "--env=NTP_SERVERS=127.127.1.1")
}
chronyCommand = append(chronyCommand, funcArgs[0]+":8033/cmii/chronyd:0.4.3")
// run docker command
ok, resultLog := AllCommandExecutor(chronyCommand)
if !ok {
return false, append(resultLog, "[installChronyByDockerExec] - docker chrony run error !")
}
BasicPrettyPrint(AllCommandExecutor([]string{
"docker",
"exec",
"chrony",
"chronyc",
"tracking",
}))
BasicPrettyPrint(AllCommandExecutor([]string{
"docker",
"exec",
"chrony",
"chronyc",
"sources",
}))
BasicPrettyPrint(AllCommandExecutor([]string{
"docker",
"exec",
"chrony",
"chronyc",
"sourcestats",
}))
return true, []string{
"[installChronyByDockerExec] - install success !",
}
}
func (op *AgentOsOperator) chronyToMaster(args []string) [][]string {
masterInnerIP := args[0]
chronyToMasterFunc := [][]string{
{
"sed",
"-i",
"$ a NTP=" + masterInnerIP,
"/etc/systemd/timesyncd.conf",
},
{
"systemctl",
"daemon-reload",
},
{
"systemctl",
"restart",
"systemd-timesyncd.service",
},
{
"sleep",
"3",
},
{
"timedatectl",
"show-timesync",
"--all",
},
{
"timedatectl",
"status",
},
}
return chronyToMasterFunc
}
func (op *AgentOsOperator) chronyToMasterExec(args []string) (bool, []string) {
parseIP := net.ParseIP(args[0])
if parseIP == nil {
return false, []string{
"[chronyToMasterExec] - ip args error !",
}
}
if op.IsOsTypeCentOS {
if !op.CanAccessInternet {
return op.chronyToMasterByDocker(args)
}
// install ntp
installSoftwares, i := BasicInstallSoftware(op.InstallCommandPrefix, true, "ntp")
if !installSoftwares {
msg := "[chronyToMasterExec] - centos install ntp error!"
log.ErrorF(msg)
return false, append(i, msg)
}
BasicSystemdUp("ntpd")
HardCodeCommandExecutor("ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime")
ok, resultLog := AllCommandExecutor([]string{
"ntpdate",
args[0],
})
if !ok {
sprintf := fmt.Sprintf("[chronyToMasterExec] - centos ntpdate to %s error", args[0])
log.Error(sprintf)
return false, append(resultLog, sprintf)
}
return true, []string{
"[chronyToMasterExec] - chrony to master success !",
}
}
// ubuntu
// modify the systemd-timesync.service
ntpFile := "/etc/systemd/timesyncd.conf"
AllCommandExecutor([]string{
"sed",
"-i",
"s/#NTP=/NTP=" + args[0] + "/g",
ntpFile,
})
// set time zone and ntp
AllCompleteExecutor([][]string{
{
"timedatectl",
"set-timezone",
"Asia/Shanghai",
},
{
"timedatectl",
"set-ntp",
"true",
},
})
BasicPrettyPrint(AllCompleteExecutor([][]string{
{
"systemctl",
"restart",
"systemd-timesyncd.service",
},
{
"sleep",
"2",
},
{
"timedatectl",
"show-timesync",
"--all",
},
{
"timedatectl",
"status",
},
}))
return true, []string{
"[chronyToMasterExec] - install success !",
}
}
func (op *AgentOsOperator) InstallMinioBastion() (bool, []string) {
return true, nil
}
func (op *AgentOsOperator) chronyToMasterByDocker(args []string) (bool, []string) {
return true, nil
}
func (op *AgentOsOperator) installZSH() [][]string {
installZSHFunc := [][]string{
{
"mkdir",
"-p",
OctopusAgentInstallPrefix,
},
append(op.InstallCommandPrefix, "zsh", "git"),
}
if op.IsAgentInnerWall {
installZSHFunc = append(installZSHFunc, [][]string{
{
"wget",
"https://cdn.jsdelivr.net/gh/robbyrussell/oh-my-zsh@master/tools/install.sh",
"-O",
"/root/wdd/zsh-install.sh",
},
}...)
} else {
installZSHFunc = append(installZSHFunc, [][]string{
{
"wget",
"https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh",
"-O",
"/root/wdd/zsh-install.sh",
},
}...)
}
// install
installZSHFunc = append(installZSHFunc, [][]string{
{
"chmod",
"+x",
"/root/wdd/zsh-install.sh",
},
{
"sh",
"-c",
"/root/wdd/zsh-install.sh",
},
}...)
// modify ZSH
if !op.IsAgentInnerWall {
installZSHFunc = append(installZSHFunc, [][]string{
{
"git",
"clone",
"https://github.com/zsh-users/zsh-autosuggestions",
"/root/.oh-my-zsh/plugins/zsh-autosuggestions",
},
{
"git",
"clone",
"https://github.com/zsh-users/zsh-syntax-highlighting.git",
"/root/.oh-my-zsh/plugins/zsh-syntax-highlighting",
},
{
"wget",
"https://b2.107421.xyz/oh-my-zsh-plugins-list.txt",
"-O",
"oh-my-zsh-plugins-list.txt",
},
{
"wget",
"-c",
"-i",
"./oh-my-zsh-plugins-list.txt",
"-P",
"/root/.oh-my-zsh/plugins/",
},
{
"sed",
"-i",
"s/robbyrussell/agnoster/g",
"/root/.zshrc",
},
{
"sed",
"-i",
"s/^# DISABLE_AUTO_UPDATE=\"true\"/DISABLE_AUTO_UPDATE=\"true\"/g",
"/root/.zshrc",
},
{
"sed",
"-i",
"s/plugins=(git)/plugins=(git zsh-autosuggestions zsh-syntax-highlighting command-not-found z themes)/g",
"/root/.zshrc",
},
{
"source",
"/root/.zshrc",
},
{
"chsh",
"-s",
"/bin/zsh",
},
{
"zsh",
},
}...)
}
return installZSHFunc
}
func (op *AgentOsOperator) installZSHExec() (bool, []string) {
log.Info("[installZSHExec] - 开始安装ZSH!")
if !op.CanAccessInternet {
return false, []string{
"[installZSHExec] - can not access to internet, zsh install failed !",
}
}
BasicRemoveFolderComplete("/root/.oh-my-zsh")
BasicRemoveFolderComplete("/root/wdd/zsh-install.sh")
BasicRemoveFolderComplete("/root/wdd/oh-my-zsh-plugins-list.txt")
BasicCreateFolder(OctopusAgentInstallPrefix)
ok, resultLog := AllCommandExecutor(append(op.InstallCommandPrefix, "zsh", "git"))
if !ok {
return false, resultLog
}
log.InfoF("ZSH环境已经清理, 完成基础安装! 开始安装oh-my-zsh!")
var zshRemoteGitUrl string
if op.IsAgentInnerWall {
zshRemoteGitUrl = "https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh"
} else {
zshRemoteGitUrl = "https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh"
}
log.InfoF("开始下载zsh的安装脚本 => %s", zshRemoteGitUrl)
resultOk, l := BasicDownloadFile(zshRemoteGitUrl, "", "", "", "/root/wdd/zsh-install.sh")
if !resultOk {
l = append(l, "zsh-install.sh 下载失败! 安装终止")
return false, l
}
executor, log2 := AllCompleteExecutor([][]string{
{
"chmod",
"+x",
"/root/wdd/zsh-install.sh",
},
{
"/bin/bash",
"/root/wdd/zsh-install.sh",
"REMOTE=https://gitee.com/mirrors/oh-my-zsh.git",
},
})
if !executor {
return false, log2
}
log.Info("zsh安装完成! 开始进行zsh的配置!")
zshAutoSourcePath := "https://github.com/zsh-users/zsh-autosuggestions"
zshHighLightingSourcePath := "https://github.com/zsh-users/zsh-syntax-highlighting.git"
if op.IsAgentInnerWall {
zshAutoSourcePath = "https://gitee.com/wangl-cc/zsh-autosuggestions.git"
zshHighLightingSourcePath = "https://gitee.com/xiaoqqya/zsh-syntax-highlighting.git"
}
modifyZSHOK, log3 := AllCompleteExecutor([][]string{
{
"git",
"clone",
zshAutoSourcePath,
"/root/.oh-my-zsh/plugins/zsh-autosuggestions",
},
{
"git",
"clone",
zshHighLightingSourcePath,
"/root/.oh-my-zsh/plugins/zsh-syntax-highlighting",
},
{
"wget",
op.OssOfflinePrefix + "oh-my-zsh-plugins-list.txt",
"-O",
"/root/wdd/oh-my-zsh-plugins-list.txt",
},
{
"wget",
"-c",
"-i",
"/root/wdd/oh-my-zsh-plugins-list.txt",
"-P",
"/root/.oh-my-zsh/plugins/",
},
{
"sed",
"-i",
"s/robbyrussell/agnoster/g",
"/root/.zshrc",
},
{
"sed",
"-i",
"s/^# DISABLE_AUTO_UPDATE=\"true\"/DISABLE_AUTO_UPDATE=\"true\"/g",
"/root/.zshrc",
},
{
"sed",
"-i",
"s/plugins=(git)/plugins=(git zsh-autosuggestions zsh-syntax-highlighting command-not-found z themes)/g",
"/root/.zshrc",
},
{
"chsh",
"-s",
"/bin/zsh",
},
{
"zsh",
},
})
if !modifyZSHOK {
log.Warn("ZSH 安装成功,但是配置修改失败!")
return true, log3
}
return true, nil
}
func (op *AgentOsOperator) modifySshPort(args []string) [][]string {
return [][]string{}
}
func (op *AgentOsOperator) modifySshPortExec(args []string) (bool, []string) {
return true, nil
}
func (op *AgentOsOperator) openBBR() [][]string {
return [][]string{}
}
func (op *AgentOsOperator) openBBRExec() (bool, []string) {
return true, nil
}
func (op *AgentOsOperator) ok(funcArgs []string) [][]string {
log.InfoF("base function is ok , args are => " + strings.Join(funcArgs, " "))
return [][]string{
{"ifconfig"},
}
}
func (op *AgentOsOperator) okExec(funcArgs []string) (bool, []string) {
log.WarnF("[okExec] - call empty base func ! func args are => %#v ", funcArgs)
return true, nil
}