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 "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) { sysctlConfigFile := "/etc/sysctl.d/wdd-k8s.conf" // ssh config // system redirection if !BasicFileExistAndNotNull(sysctlConfigFile) { ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+"systemctl-config-template.txt", "", "", "", sysctlConfigFile) if !ok { return false, resultLog } } AllCommandExecutor([]string{ "sysctl", "-p", sysctlConfigFile, }) return true, nil } 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.installDockerOfflineExec(args) } 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", } } // todo ubuntu 22.04 // ubuntu 内部 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 } 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.installDockerOfflineExec(args) } // 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) installDockerOfflineExec(args []string) (bool, []string) { log.InfoF("[installDockerOfflineExec] - install docker 20.10.15 by offline method !") BasicCreateFolder("/root/wdd") // download static binary installer of 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" } ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+dockerOfflineFileName, "", "", "", OctopusAgentInstallPrefix+dockerOfflineFileName) if !ok { return false, resultLog } BasicRemoveFolderComplete("/root/wdd/docker") PureResultSingleExecute([]string{ "tar", "-vxf", OctopusAgentInstallPrefix + dockerOfflineFileName, "-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, "[installDockerOfflineExec] - cp docker executable file error!") } // systemd daemonize docker downloadOk, log2 := BasicDownloadFile(op.OssOfflinePrefix+"docker-containerd-daemon.service", "", "", "", beans.ContainerdServiceFile) if !downloadOk { return false, append(log2, "[installDockerOfflineExec] - daemon file download error !") } downloadOk, log2 = BasicDownloadFile(op.OssOfflinePrefix+"docker-socket-daemon.service", "", "", "", beans.DockerSocketDaemonService) if !downloadOk { return false, append(log2, "[installDockerOfflineExec] - daemon file download error !") } downloadOk, log2 = BasicDownloadFile(op.OssOfflinePrefix+"docker-daemon.service", "", "", "", beans.DockerServiceFile) if !downloadOk { return false, append(log2, "[installDockerOfflineExec] - daemon file download error !") } // run the docker executor, log3 := AllCommandExecutor([]string{ "systemctl", "daemon-reload", }) if !executor { return false, append(log3, "[installDockerOfflineExec] - daemon reload error !") } AllCompleteExecutor([][]string{ { "groupadd", "docker", }, { "usermod", "-aG", "docker", "root", }, { "newgrp", "docker", }, }) systemdUp, log5 := BasicSystemdUp("containerd") if !systemdUp { return false, append(log5, "[installDockerOfflineExec] - start containerd service error !") } commandExecutor, log6 := AllCompleteExecutor([][]string{ { "systemctl", "start", "docker.socket", }, { "systemctl", "enable", "docker.socket", }, }) if !commandExecutor { return false, append(log6, "[installDockerOfflineExec] - start docker.socket error !") } up, log4 := BasicSystemdUp("docker") if !up { return false, append(log4, "[installDockerOfflineExec] - start docker service error !") } return true, []string{ "[installDockerOfflineExec] - docker offline installation success!", } } 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 !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 if op.IsOsTypeCentOS { // ubuntu 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 !", } } // run docker command ok, resultLog := AllCommandExecutor([]string{ "docker", "run", "--name=chrony", "--restart=always", "--detach", "--cap-add=SYS_TIME", "--publish=123:123/udp", "--env=NTP_SERVERS=\"ntp1.aliyun.com,ntp2.aliyun.com,ntp3.aliyun.com,ntp4.aliyun.com\"", "--env=LOG_LEVEL=0", "--env=TZ=Asia/Shanghai", "--env=ENABLE_SYSCLK=true", funcArgs[0] + ":8033/cmii/chronyd:0.4.3", }) 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 !", } } // 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 }