package executor import ( "fmt" "net" "os" "path/filepath" "sort" "strings" "time" ) type OctopusFunc interface { Command(baseFuncName string, funcArgs ...string) []string Exec(baseFuncName string, funcArgs ...string) (bool, []string) Deploy(appFuncName string, funcArgs ...string) (bool, []string) } type AppFunc interface { Deploy(appFuncName string, funcArgs ...string) (bool, []string) } var AppExecuteErrorLogPrefix = []string{"App指令执行错误! => "} var nfsDataPath = "/var/lib/docker/nfs_data" func (op *AgentOsOperator) Deploy(appFuncName string, funcArgs ...string) (bool, []string) { var resultOK bool var result []string switch appFuncName { case "DEPLOY_RKE": resultOK, result = op.deployRke(funcArgs) break case "DEPLOY_K8S_DASHBOARD": resultOK, result = op.deployK8sDashboard(funcArgs) break case "DEPLOY_K8S_NAMESPACE": resultOK, result = op.deployK8sNamespace(funcArgs) break case "DEPLOY_MINIO": resultOK, result = op.deployMinio(funcArgs) break case "DEPLOY_NFS": resultOK, result = op.deployNFS(funcArgs) break case "DEPLOY_TEST_NFS": resultOK, result = op.deployTestNFS(funcArgs) break case "DEPLOY_K8S_PVC": resultOK, result = op.deployPVC(funcArgs) break case "DEPLOY_STORAGE_CLASS": break case "DEPLOY_K8S_MYSQL": resultOK, result = op.deployMySQL(funcArgs) break case "LOAD_MYSQL_INIT_SCRIPT": resultOK, result = op.loadMysqlInitScript(funcArgs) break case "checkMySQL": resultOK, result = op.checkMySQL(funcArgs) break case "DEPLOY_K8S_MIDDLEWARES": resultOK, result = op.deployMiddlewares(funcArgs) break case "DEPLOY_K8S_REDIS": resultOK, result = op.deployRedis(funcArgs) break case "DEPLOY_INGRESS": resultOK, result = op.deployIngress(funcArgs) break case "DEPLOY_FRONTEND": resultOK, result = op.deployFront(funcArgs) break case "INIT_MINIO": resultOK, result = op.initMinio(funcArgs) break case "DEPLOY_K8S_SRS": resultOK, result = op.deploySRS(funcArgs) break case "deployGDR": resultOK, result = op.deployGDR(funcArgs) break case "MODIFY_NACOS": resultOK, result = op.modifyNacos(funcArgs) break case "DEPLOY_BACKEND": resultOK, result = op.deployBackend(funcArgs) break default: op.ok(funcArgs) } // debug log.DebugF("app deploy of %s result is %v", appFuncName, result) return resultOK, result } func CheckAppInstallFolder() (bool, []string) { if !BasicCreateFolder("/root/wdd/install") { return false, []string{ "[CheckAppInstallFolder] - install folder create failed !", } } return true, nil } func (op *AgentOsOperator) deployRke(funcArgs []string) (bool, []string) { var ok bool var resultLog []string // download rke // download kubectl // download rke-cluster.yml ok, resultLog = BasicDownloadFile(op.OssOfflinePrefix+"rke", "/usr/local/bin/rke") if !ok { return false, resultLog } ok, resultLog = BasicDownloadFile(op.OssOfflinePrefix+"kubectl", "/usr/local/bin/kubectl") if !ok { return false, resultLog } ok, resultLog = BasicDownloadFile(op.OssOfflinePrefix+"rke-cluster-template.yaml", "/root/wdd/cluster.yml") if !ok { return false, resultLog } AllCompleteExecutor([][]string{ { "chmod", "+x", "/usr/local/bin/rke", }, { "chmod", "+x", "/usr/local/bin/kubectl", }, }) if !BasicCreateFolder("/root/.kube") { return false, []string{ "[deployRke] - folder [/root/.kube] create error!", } } // replace ip addr parseIP := net.ParseIP(funcArgs[0]) if parseIP == nil { return false, []string{ "[deployRke] - ip args error !", } } if !BasicReplace("/root/wdd/rke-cluster.yml", "A1C2IP", funcArgs[1]) { log.ErrorF("[deployRke] - rke config replace error !") } return true, []string{ "[deployRke] - rke dependency download success !", } } func (op *AgentOsOperator) deployK8sDashboard(funcArgs []string) (bool, []string) { restartHarborExec, strings := op.restartHarborExec() if !restartHarborExec { return false, strings } // check folder folder, i := CheckAppInstallFolder() if !folder { return false, i } // download template file k8sDashBoardYamlFile := "/root/wdd/install/k8s-dashboard.yaml" ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+"k8s-dashboard-template.yaml", k8sDashBoardYamlFile) if !ok { return false, resultLog } // kubectl // replace parseIP := net.ParseIP(funcArgs[0]) if parseIP == nil { return false, []string{ "[deployK8sDashboard] - ip args error !", } } BasicReplace(k8sDashBoardYamlFile, "A1C2IP", funcArgs[0]) // up applyExec, resultLog := KubectlApplyExec(k8sDashBoardYamlFile) if !applyExec { return false, resultLog } // check deployment ok if !K8sCheckDeploymentStatusTimeout("kubernetes-dashboard", "kube-system", 120) { return false, []string{ "[deployK8sDashboard] - deployment run error !", } } return true, nil } func (op *AgentOsOperator) deployK8sNamespace(funcArgs []string) (bool, []string) { if !K8sCreateNamespace(funcArgs[1]) { return false, []string{ fmt.Sprintf("Namespace of [%s] create error!", funcArgs[1]), } } return true, []string{ fmt.Sprintf("Namespace of [%s]create success !", funcArgs[1]), } } func (op *AgentOsOperator) deployMinio(funcArgs []string) (bool, []string) { minioTemplateFileName := "minio-docker-compose.yaml" result := append(AppExecuteErrorLogPrefix, "部署MINIO") // 逻辑为接收执行,但是会报错 // 环境判定 commandExist, commandName := BasicCommandExistsBatch([]string{ "docker-compose", }) if !commandExist { result = append(result, "命令不存在", commandName) return false, result } // 磁盘空间足够 // 目录存在 // 下载模板文件 if !PureResultSingleExecute([]string{ "wget", "-q", op.OssOfflinePrefix + "/" + minioTemplateFileName, }) { result = append(result, "下载模板文件") return false, result } // 根据参数 A1C2IP 替换 if !BasicReplace(minioTemplateFileName, "A1C2IP", funcArgs[0]) { result = append(result, "替换IP信息") return false, result } // 启动服务 if !PureResultSingleExecute([]string{ "docker-compose", "-f", minioTemplateFileName, "up", "-d", }) { result = append(result, "启动minio失败!") return false, result } // 成功启动 return true, []string{ "MINIO安装成功!", "输入如下命令查看启动情况: ", "docker-compose logs minio1", } } func (op *AgentOsOperator) deployNFS(funcArgs []string) (bool, []string) { nfsTemplateFile := "k8s-nfs-template.yaml" result := append(AppExecuteErrorLogPrefix, "部署NFS") // 环境判定 if !BasicCommandExistByPath("kubectl") { result = append(result, "命令不存在", "kubectl") return false, result } // 创建目录修改权限 if !BasicFolderExists(nfsDataPath) { return false, []string{ fmt.Sprintf("[deployNFS] - folder of [ %s ] not exist ! nfs not installed ", nfsDataPath), } } // 下载模板文件 k8sNFSYamlFile := "/root/wdd/install/k8s-nfs.yaml" ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+nfsTemplateFile, k8sNFSYamlFile) if !ok { return false, resultLog } // 根据参数 A1C2IP 替换 ip := net.ParseIP(funcArgs[0]) if ip == nil { return false, append(result, "ip args error !") } if !BasicReplace(k8sNFSYamlFile, "N1C2IP", funcArgs[0]) { result = append(result, "替换IP信息") return false, result } // 启动服务 exec, strings := KubectlApplyExec(k8sNFSYamlFile) if !exec { return false, strings } // check running status if !K8sCheckDeploymentStatusTimeout("nfs-client-provisioner", "kube-system", 60) { return false, []string{ "[deployNFS] - nfs running error !", } } // 成功启动 return true, []string{ "NFS部署成功!", } } func (op *AgentOsOperator) deployTestNFS(funcArgs []string) (bool, []string) { nfsTemplateFile := "k8s-nfs-test-template.yaml" result := append(AppExecuteErrorLogPrefix, "测试NFS部署") // 环境判定 if !BasicCommandExistByPath("kubectl") { result = append(result, "命令不存在", "kubectl") return false, result } // 下载模板文件 k8sNFSYamlFile := "/root/wdd/install/k8s-nfs-test.yaml" ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+nfsTemplateFile, k8sNFSYamlFile) if !ok { return false, resultLog } // 根据参数 A1C2IP 替换 ip := net.ParseIP(funcArgs[0]) if ip == nil { return false, append(result, "ip args error !") } if !BasicReplace(k8sNFSYamlFile, "N1C2IP", funcArgs[0]) { result = append(result, "替换IP信息") return false, result } // 启动服务 // 启动服务 exec, strings := KubectlApplyExec(k8sNFSYamlFile) if !exec { return false, strings } // 测试文件是否存在 if !BasicFileExists(nfsDataPath + "/default-test-claim-pvc*/NFS-CREATE-SUCCESS") { result = append(result, "NFS 文件写入 异常!!") } if !K8sCheckPodStatusTimeout("test-pod", "default", 30) { return false, []string{ "[deployTestNFS] - test pod create failed !", } } // 成功启动 return true, []string{ "[deployTestNFS] - NFS 测试功能正常!", } } func (op *AgentOsOperator) deployPVC(funcArgs []string) (bool, []string) { pvcTemplateFile := "k8s-pvc-template.yaml" result := append(AppExecuteErrorLogPrefix, "部署PVC") // 环境判定 if !BasicCommandExistByPath("kubectl") { result = append(result, "命令不存在", "kubectl") return false, result } // 下载模板文件 k8sPvcYamlFile := "/root/wdd/install/k8s-pvc.yaml" ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+pvcTemplateFile, k8sPvcYamlFile) if !ok { return false, resultLog } // 根据参数 A1C2IP 替换 if !BasicReplace(k8sPvcYamlFile, "SUPREME", funcArgs[1]) { result = append(result, "替换SUPREME信息") return false, result } // 替换版本号 if !BasicReplace(k8sPvcYamlFile, "KIMMY", funcArgs[6]) { log.WarnF("[deployPVC] - pvc config version replace error , expected => %s", funcArgs[6]) } // 启动服务 exec, strings := KubectlApplyExec(k8sPvcYamlFile) if !exec { return false, strings } // check status ok, pvcList := K8sListPVCInNamespace(funcArgs[1]) if !ok { return false, []string{ "[deployPVC] - pvc list error ! can not check status !", } } for _, pvcName := range pvcList { if !K8sCheckPVCStatusTimeOut(pvcName, funcArgs[1], 30) { return false, []string{ fmt.Sprintf("[deployPVC] - pvc [%s] in namepsace [%s] running error !", pvcName, funcArgs[1]), } } } // 成功启动 return true, append(pvcList, "PVC部署成功!") } func (op *AgentOsOperator) deployMySQL(funcArgs []string) (bool, []string) { mysqlTemplate := "k8s-mysql-template.yaml" result := append(AppExecuteErrorLogPrefix, "部署 MySQL !") // 环境判定 if !BasicCommandExistByPath("kubectl") { result = append(result, "命令不存在", "kubectl") return false, result } // 下载模板文件 k8sMysqlYamlFile := "/root/wdd/install/k8s-mysql.yaml" ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+mysqlTemplate, k8sMysqlYamlFile) if !ok { return false, resultLog } // 根据参数 A1C2IP 替换 ip := net.ParseIP(funcArgs[0]) if ip == nil { return false, append(result, "ip args error !") } if !BasicReplace(k8sMysqlYamlFile, "A1C2IP", funcArgs[0]) { result = append(result, "替换A1C2IP信息") return false, result } // 替换SUPREME信 if !BasicReplace(k8sMysqlYamlFile, "SUPREME", funcArgs[1]) { result = append(result, "替换SUPREME信息") return false, result } // 启动服务 exec, strings := KubectlApplyExec(k8sMysqlYamlFile) if !exec { return false, append(result, strings...) } // check mysql if !K8sCheckPodStatusTimeout("helm-mysql-0", funcArgs[1], 180) { return false, []string{ "helm-mysql-0 启动失败!", } } // 成功启动 return true, []string{ "MySQL部署成功!", } } func (op *AgentOsOperator) loadMysqlInitScript(funcArgs []string) (bool, []string) { // download offline sql list if len(funcArgs) <= 7 { return false, []string{ "[loadMysqlInitScript]- MySQL初始化参数有误! 无法进行初始化", } } jackeyLove := funcArgs[7] if !strings.HasSuffix(jackeyLove, "tar") { return false, []string{ "[loadMysqlInitScript]- jackeyLove 有误!", } } log.DebugF("[loadMysqlInitScript] - start to load jackeyLove file from %s", jackeyLove) jackeyLoveLocalPrefix := "/root/wdd/jackeylove/" BasicCreateFolder(jackeyLoveLocalPrefix) jackeyLoveFolder := strings.Split(jackeyLove, ".tar")[0] ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+"jackeyLove", jackeyLoveLocalPrefix+jackeyLove) if !ok { return false, append(resultLog, "[loadMysqlInitScript]- jackeyLove 下载失败!") } // unzip if !PureResultSingleExecute([]string{ "tar", "-vxf", jackeyLoveLocalPrefix + jackeyLove, "-C", jackeyLoveLocalPrefix, }) { return false, []string{ "[loadMysqlInitScript]- jackeyLove unzip error !", } } // list all sql file and sort and convert to []string files, err := os.ReadDir(jackeyLoveLocalPrefix + jackeyLoveFolder) if err != nil { return false, []string{ "[loadMysqlInitScript]- read unzipped jackeylove error !", } } var jackeyLoveFileList []string for _, file := range files { if !file.IsDir() && filepath.Ext(file.Name()) == ".sql" { jackeyLoveFileList = append(jackeyLoveFileList, file.Name()) } } sort.Strings(jackeyLoveFileList) log.InfoF("[loadMysqlInitScript] - all jackey love files are => %v", jackeyLoveFileList) // dispatch mysql execution command jackeyLoveIP := funcArgs[0] parseIP := net.ParseIP(jackeyLoveIP) if parseIP == nil { return false, []string{ "[loadMysqlInitScript]- ip config error !", } } load, result := MysqlSqlFileLoad(jackeyLoveFileList) if !load { return false, result } return true, []string{ "[loadMysqlInitScript] - execute success !", } } func (op *AgentOsOperator) checkMySQL(funcArgs []string) (bool, []string) { if !K8sCheckPodStatusTimeout("helm-mysql-0", funcArgs[0], 180) { return false, []string{ "helm-mysql 启动失败!", } } return true, nil } func (op *AgentOsOperator) deployMiddlewares(funcArgs []string) (bool, []string) { middlewaresTemplate := "k8s-middleware-template.yaml" result := append(AppExecuteErrorLogPrefix, "部署 所有的中间件 !") // 环境判定 if !BasicCommandExistByPath("kubectl") { result = append(result, "命令不存在", "kubectl") return false, result } // 下载模板文件 k8sMiddlewaresYamlFile := "/root/wdd/install/k8s-middlewares.yaml" ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+middlewaresTemplate, k8sMiddlewaresYamlFile) if !ok { return false, resultLog } // 根据参数 A1C2IP 替换 ip := net.ParseIP(funcArgs[0]) if ip == nil { return false, append(result, "[deployMiddlewares] - ip args error !") } if !BasicReplace(k8sMiddlewaresYamlFile, "A1C2IP", funcArgs[0]) { result = append(result, "替换A1C2IP信息") return false, result } if !BasicReplace(k8sMiddlewaresYamlFile, "SUPREME", funcArgs[1]) { result = append(result, "替换SUPREME信息") return false, result } // 替换版本号 if !BasicReplace(k8sMiddlewaresYamlFile, "KIMMY", funcArgs[6]) { log.WarnF("[deployMiddlewares] - pvc config version replace error , expected => %s", funcArgs[6]) } // 启动服务 exec, strings := KubectlApplyExec(k8sMiddlewaresYamlFile) if !exec { return false, append(result, strings...) } // check status podNameList := []string{ "helm-rabbitmq-0", "helm-mongo-0", "helm-emqxs-0", "helm-nacos-0", } for _, podName := range podNameList { if !K8sCheckPodStatusTimeout(podName, funcArgs[1], 180) { return false, []string{ fmt.Sprintf("[deployMiddlewares] - Namepsace [%s] Pod [%s] 启动失败!", funcArgs[1], podName), } } } // 成功启动 return true, append(podNameList, "[deployMiddlewares] - 中间件部署成功!", ) } func (op *AgentOsOperator) deployRedis(funcArgs []string) (bool, []string) { redisTemplate := "k8s-redis-template.yaml" result := append(AppExecuteErrorLogPrefix, "部署 redis !") // 环境判定 if !BasicCommandExistByPath("kubectl") { result = append(result, "命令不存在", "kubectl") return false, result } // 下载模板文件 k8sRedisYamlFile := "/root/wdd/install/k8s-redis.yaml" ok, resultLog := BasicDownloadFile(op.OssOfflinePrefix+redisTemplate, k8sRedisYamlFile) if !ok { return false, resultLog } // 根据参数 A1C2IP 替换 ip := net.ParseIP(funcArgs[0]) if ip == nil { return false, append(result, "ip args error !") } if !BasicReplace(k8sRedisYamlFile, "A1C2IP", funcArgs[0]) { result = append(result, "替换A1C2IP信息") return false, result } if !BasicReplace(k8sRedisYamlFile, "SUPREME", funcArgs[1]) { result = append(result, "替换SUPREME信息") return false, result } // 启动服务 exec, strings := KubectlApplyExec(k8sRedisYamlFile) if !exec { return false, append(result, strings...) } // check status if !K8sCheckPodStatusTimeout("helm-redis-master-0", funcArgs[1], 120) { return false, []string{ "[deployRedis] - redis-master running failed ! please cheak !", } } if !K8sCheckPodStatusTimeout("helm-redis-replicas-0", funcArgs[1], 120) { return false, []string{ "[deployRedis] - redis-replicas running failed ! please check !", } } // 成功启动 return true, []string{ "Redis 部署成功!", } } func (op *AgentOsOperator) deployIngress(funcArgs []string) (bool, []string) { ingressTemplate := "ingress-template.yaml" result := append(AppExecuteErrorLogPrefix, "部署 Ingress !") // 环境判定 commandExist, commandName := BasicCommandExistsBatch([]string{ "kubectl", }) if !commandExist { result = append(result, "命令不存在", commandName) return false, result } // 下载模板文件 if !PureResultSingleExecute([]string{ "wget", "-q", op.OssOfflinePrefix + "/" + ingressTemplate, }) { result = append(result, "下载模板文件") return false, result } // 根据参数 A1C2IP 替换 if !BasicReplace(ingressTemplate, "SUPREME", funcArgs[0]) { result = append(result, "替换SUPREME信息") return false, result } if !BasicReplace(ingressTemplate, "A1C2IP", funcArgs[1]) { result = append(result, "替换A1C2IP信息") return false, result } if !BasicReplace(ingressTemplate, "A1C1JS", funcArgs[1]) { result = append(result, "替换A1C1JS信息") return false, result } // 启动服务 if !PureResultSingleExecute([]string{ "kubectl", "apply", "-f", ingressTemplate, }) { result = append(result, "创建 Ingress 失败!") return false, result } // 成功启动 return true, []string{ "Ingress 部署成功!", } } func (op *AgentOsOperator) deployFront(funcArgs []string) (bool, []string) { fontTemplate := "front-template.yaml" result := append(AppExecuteErrorLogPrefix, "部署 前端服务 !") // 环境判定 commandExist, commandName := BasicCommandExistsBatch([]string{ "kubectl", }) if !commandExist { result = append(result, "命令不存在", commandName) return false, result } // 下载模板文件 if !PureResultSingleExecute([]string{ "wget", "-q", op.OssOfflinePrefix + "/" + fontTemplate, }) { result = append(result, "下载模板文件") return false, result } // 根据参数 A1C2IP 替换 if !BasicReplace(fontTemplate, "SUPREME", funcArgs[0]) { result = append(result, "替换SUPREME信息") return false, result } if !BasicReplace(fontTemplate, "A1C2IP", funcArgs[1]) { result = append(result, "替换A1C2IP信息") return false, result } // 启动服务 if !PureResultSingleExecute([]string{ "kubectl", "apply", "-f", fontTemplate, }) { result = append(result, "创建 前端服务 失败!") return false, result } // 成功启动 return true, []string{ "前端服务 部署成功!", } } func (op *AgentOsOperator) initMinio(funcArgs []string) (bool, []string) { initMinioTemplate := "minio-init.sh" result := append(AppExecuteErrorLogPrefix, "进行MINIO初始化服务 !") // 环境判定 commandExist, commandName := BasicCommandExistsBatch([]string{ "kubectl", }) if !commandExist { result = append(result, "命令不存在", commandName) return false, result } // 下载模板文件 if !PureResultSingleExecute([]string{ "wget", "-q", op.OssOfflinePrefix + "/" + initMinioTemplate, }) { result = append(result, "下载模板文件") return false, result } // 根据参数 A1C2IP 替换 if !BasicReplace(initMinioTemplate, "SUPREME", funcArgs[0]) { result = append(result, "替换SUPREME信息") return false, result } if !BasicReplace(initMinioTemplate, "A1C2IP", funcArgs[1]) { result = append(result, "替换A1C2IP信息") return false, result } if !BasicReplace(initMinioTemplate, "M2D2IP", funcArgs[1]) { result = append(result, "替换A1C2IP信息") return false, result } // 启动服务 if !PureResultSingleExecute([]string{ "kubectl", "apply", "-f", initMinioTemplate, }) { result = append(result, "MINIO 初始化 失败!") return false, result } // 成功启动 return true, []string{ "MINIO 初始化 成功!", } } func (op *AgentOsOperator) deploySRS(funcArgs []string) (bool, []string) { srsTemplate := "srs-template.yaml" result := append(AppExecuteErrorLogPrefix, "开始部署SRS服务!") // 环境判定 commandExist, commandName := BasicCommandExistsBatch([]string{ "kubectl", }) if !commandExist { result = append(result, "命令不存在", commandName) return false, result } // 下载模板文件 if !PureResultSingleExecute([]string{ "wget", "-q", op.OssOfflinePrefix + "/" + srsTemplate, }) { result = append(result, "下载模板文件") return false, result } // 根据参数 A1C2IP 替换 if !BasicReplace(srsTemplate, "SUPREME", funcArgs[0]) { result = append(result, "替换SUPREME信息") return false, result } if !BasicReplace(srsTemplate, "A1C2IP", funcArgs[1]) { result = append(result, "替换A1C2IP信息") return false, result } if !BasicReplace(srsTemplate, "A1C1JS", funcArgs[1]) { result = append(result, "替换A1C1JS信息") return false, result } if !BasicReplace(srsTemplate, "M2D2IP", funcArgs[1]) { result = append(result, "替换M2D2IP信息") return false, result } // 启动服务 if !PureResultSingleExecute([]string{ "kubectl", "apply", "-f", srsTemplate, }) { result = append(result, "部署 SRS 失败!") return false, result } // 成功启动 return true, []string{ "部署 SRS 成功!", } } func (op *AgentOsOperator) deployGDR(funcArgs []string) (bool, []string) { return true, []string{ "请手动进行GDR的部署工作!", } } func (op *AgentOsOperator) modifyNacos(funcArgs []string) (bool, []string) { log.Info("请开始进行Nacos的配置修改工作!") log.Info("请开始进行Nacos的配置修改工作!") after := time.After(120 * time.Second) <-after msg := "等待Nacos的配置结束!" log.Info(msg) return true, []string{msg} } func (op *AgentOsOperator) deployBackend(funcArgs []string) (bool, []string) { backendTemplate := "backend-template.yaml" result := append(AppExecuteErrorLogPrefix, "部署 后端 服务 !") // 环境判定 commandExist, commandName := BasicCommandExistsBatch([]string{ "kubectl", }) if !commandExist { result = append(result, "命令不存在", commandName) return false, result } // 下载模板文件 if !PureResultSingleExecute([]string{ "wget", "-q", op.OssOfflinePrefix + "/" + backendTemplate, }) { result = append(result, "下载模板文件") return false, result } // 根据参数 A1C2IP 替换 if !BasicReplace(backendTemplate, "SUPREME", funcArgs[0]) { result = append(result, "替换SUPREME信息") return false, result } if !BasicReplace(backendTemplate, "A1C2IP", funcArgs[1]) { result = append(result, "替换A1C2IP信息") return false, result } // 启动服务 if !PureResultSingleExecute([]string{ "kubectl", "apply", "-f", backendTemplate, }) { result = append(result, "创建 后端服务 失败!") return false, result } // 成功启动 return true, []string{ "后端服务 部署成功!", } }