持续集成交付CICD:Jenkins使用GitLab共享库实现基于SaltStack的CD流水线部署前后端应用

本文主要是介绍持续集成交付CICD:Jenkins使用GitLab共享库实现基于SaltStack的CD流水线部署前后端应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、实验

1.Jenkins使用GitLab共享库实现基于SaltStack的CD流水线部署前后端应用

2.优化共享库代码

二、问题

1.Jenkins手动构建后端项目流水线报错


一、实验

1.Jenkins使用GitLab共享库实现基于SaltStack的CD流水线部署前后端应用

(1)GitLab共享库更新代码

① 更新共享库目录结构

② 修改制品类Artifacts.grovvy

package org.devops//上传制品def PushRawArtifacts(repoName,targetDir, filePath, pkgName,type ){withCredentials([usernamePassword(credentialsId: '318df1ad-083b-4158-ac88-2f584446563e', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) {sh """curl -X POST "http://192.168.204.13:8081/service/rest/v1/components?repository=${repoName}" \-H "accept: application/json" \-H "Content-Type: multipart/form-data" \-F "raw.directory=${targetDir}" \-F "raw.asset1=@${filePath}/${pkgName};type=${type}" \-F "raw.asset1.filename=${pkgName}" \-u "${USER}":"${TOKEN}""""}}//下载制品
def PullArtifacts(version,projectName,repoName,type){withCredentials([usernamePassword(credentialsId: '318df1ad-083b-4158-ac88-2f584446563e', passwordVariable: 'TOKEN', usernameVariable: 'USER')]) {repoUrl = "http://192.168.204.13:8081/repository"pkgPath = "${repoUrl}/${repoName}/${projectName}/${version}/${projectName}-${version}.${type}"sh "wget --http-user=${user} --http-passwd=${TOKEN} ${pkgPath} -q"}
}

③ 修改文件类Gitlab.groovy

package org.devops// 封装HTTP
def HttpReq(reqType, reqUrl,reqBody ){def gitServer = "http://192.168.204.8:82/api/v4"withCredentials([string(credentialsId: '02dce3ff-4e46-4de2-b079-5dd6093d4f64', variable: 'GITLABTOKEN')]) {response = httpRequest acceptType: 'APPLICATION_JSON_UTF8', consoleLogResponseBody: true, contentType: 'APPLICATION_JSON_UTF8', customHeaders: [[maskValue: false, name: 'PRIVATE-TOKEN', value: "${GITLABTOKEN}"]], httpMode: "${reqType}", url: "${gitServer}/${reqUrl}", wrapAsMultipart: false,requestBody: "${reqBody}"}return response
}//获取文件内容
def GetRepoFile(projectId,filePath, branchName ){//GET /projects/:id/repository/files/:file_path/rawapiUrl = "/projects/${projectId}/repository/files/${filePath}/raw?ref=${branchName}"response = HttpReq('GET', apiUrl, "")return response.content
}//更新文件内容
def UpdateRepoFile(projectId,filePath,fileContent, branchName){apiUrl = "projects/${projectId}/repository/files/${filePath}"reqBody = """{"branch": "${branchName}","encoding":"base64", "content": "${fileContent}", "commit_message": "update a new file"}"""response = HttpReq('PUT',apiUrl,reqBody)println(response)}//创建文件
def CreateRepoFile(projectId,filePath,fileContent, branchName){apiUrl = "projects/${projectId}/repository/files/${filePath}"reqBody = """{"branch": "${branchName}","encoding":"base64", "content": "${fileContent}", "commit_message": "update a new file"}"""response = HttpReq('POST',apiUrl,reqBody)println(response)}

④ CI流水线更名: ci.jenkinsfile

 ⑤新增CD流水线: cd.jenkinsfile

@Library("mylib@master") _
import org.devops.*def artifacts = new Artifacts()
def gitlabutil = new Gitlab()pipeline {agent { label "build" }options {skipDefaultCheckout true}stages{stage("PullArtifacts"){steps{script{repoName = "${JOB_NAME}".split("/")[0]env.projectName ="${JOB_NAME}".split("/")[-1].split("_")[0]if ("${env.projectType}" == "maven"){type="jar"}if ("${env.projectType}" == "npm"){type="tar.gz"}artifacts.PullArtifacts("${env.releaseVersion}","${env.projectName}",repoName,type)env.pkgName="${env.projectName}-${env.releaseVersion}.${type}"}}}stage("DeployHost"){steps{script{print("DeployHost")if ("${env.deployTool}" == "saltstack"){targetHosts = "${env.saltHosts}"println(targetHosts)localDeployDir = "/srv/salt/${env.projectName}"sh """[ -d ${localDeployDir} ] || mkdir -p ${localDeployDir}mv ${env.pkgName} ${localDeployDir}# 清理发布目录salt -L "${targetHosts}" cmd.run  "rm -fr ${targetDir}/${env.projectName}/* &&  mkdir -p ${targetDir}/${env.projectName} || echo file is exists"# 发布应用salt -L "${targetHosts}" cp.get_file salt://${env.projectName}/${env.pkgName} ${targetDir}/${env.projectName}"""if ("${env.projectType}" == "npm") {sh """# 解压salt -L "${targetHosts}" cmd.run  "cd ${targetDir}/${env.projectName} ;tar zxf ${env.pkgName}""""}}}}}stage("ServiceCtrl"){steps{script{print("ServiceCtrl")localDeployDir = "/srv/salt/${env.projectName}"if ("${env.projectType}" == "maven") {// 文件内容写到本地response = gitlabutil.GetRepoFile(21, "service.sh", "master")writeFile file: 'service.sh', text: "${response}"sh "ls -a "sh """mv service.sh  ${localDeployDir}# 发布启动脚本salt -L "${targetHosts}" cp.get_file salt://${env.projectName}/service.sh ${targetDir}/${env.projectName}# 启动服务salt -L "${targetHosts}" cmd.run  "cd ${targetDir}/${env.projectName} ;source /etc/profile  && sh service.sh ${env.projectName} ${env.releaseVersion} ${env.port} start"# 检查服务sleep 5salt -L "${targetHosts}" cmd.run  "cd ${targetDir}/${env.projectName} ;source /etc/profile  && sh service.sh ${env.projectName} ${env.releaseVersion} ${env.port} check""""}}}}stage("HealthCheck"){steps{script{print("HealthCheck")}}}}
}

⑥ 更新提交到master

(2) Jenkins修改后端流水线

① 流水线设置SCM

② 手动构建CD流水线

③ 成功

④ ⑤ ⑥ ⑦ ⑧

(3)Jenkins修改前端流水线

① 流水线设置SCM

② 手动构建CD流水线

③ 成功

④ 再次手动构建CD流水线

⑤ 成功

⑥ 命令观察

# for i in `seq 1000`; do sleep 1 ; curl http://127.0.0.1:8099; echo -e "\n\n\n";done

2.优化共享库代码

(1)共享库新建部署类 Deploy.groovy

(2)修改Deploy.groovy

package org.devops//SaltStackdef SaltCP(){targetHosts = "${env.saltHosts}"localDeployDir = "/srv/salt/${env.projectName}"sh """[ -d ${localDeployDir} ] || mkdir -p ${localDeployDir}mv ${env.pkgName} ${localDeployDir}# 清理发布目录salt -L "${targetHosts}" cmd.run  "rm -fr ${targetDir}/${env.projectName}/* &&  mkdir -p ${targetDir}/${env.projectName} || echo file is exists"# 发布应用salt -L "${targetHosts}" cp.get_file salt://${env.projectName}/${env.pkgName} ${targetDir}/${env.projectName}"""if ("${env.projectType}" == "npm") {sh """# 解压salt -L "${targetHosts}" cmd.run  "cd ${targetDir}/${env.projectName} ;tar zxf ${env.pkgName}""""}
}//启动服务
def ServiceCtrl(){localDeployDir = "/srv/salt/${env.projectName}"if ("${env.projectType}" == "maven") {// 文件内容写到本地gitlab = new Gitlab()response = gitlab.GetRepoFile(21, "service.sh", "master")writeFile file: 'service.sh', text: "${response}"sh "ls -a "sh """mv service.sh  ${localDeployDir}# 发布启动脚本salt -L "${targetHosts}" cp.get_file salt://${env.projectName}/service.sh ${targetDir}/${env.projectName}# 启动服务salt -L "${targetHosts}" cmd.run  "cd ${targetDir}/${env.projectName} ;source /etc/profile  && sh service.sh ${env.projectName} ${env.releaseVersion} ${env.port} start"# 检查服务sleep 5salt -L "${targetHosts}" cmd.run  "cd ${targetDir}/${env.projectName} ;source /etc/profile  && sh service.sh ${env.projectName} ${env.releaseVersion} ${env.port} check""""}
}

(3)精简代码的 cd.jenkinsfile

@Library("mylib@master") _
import org.devops.*def artifacts = new Artifacts()
def gitlabutil = new Gitlab()
def deployer = new Deploy()pipeline {agent { label "build" }options {skipDefaultCheckout true}stages{stage("PullArtifacts"){steps{script{repoName = "${JOB_NAME}".split("/")[0]env.projectName ="${JOB_NAME}".split("/")[-1].split("_")[0]if ("${env.projectType}" == "maven"){type="jar"}if ("${env.projectType}" == "npm"){type="tar.gz"}artifacts.PullArtifacts("${env.releaseVersion}","${env.projectName}",repoName,type)env.pkgName="${env.projectName}-${env.releaseVersion}.${type}"}}}stage("DeployHost"){steps{script{print("DeployHost")if ("${env.deployTool}" == "saltstack"){deployer.SaltCP()            }}}}stage("ServiceCtrl"){steps{script{print("ServiceCtrl")deployer.ServiceCtrl()}}}}
}

(4)Jenkins手动构建后端项目流水线

(5)Jenkins手动构建前端项目流水线

二、问题

1.Jenkins手动构建后端项目流水线报错

(1)报错

No signature of method: static org.devops.Gitlab.GetRepoFile()

(2)原因分析

GitLab共享库调用其他类未初始化函数

(3)解决方法

初始化函数。

修改前:

response = Gitlab.GetRepoFile(21, "service.sh", "master")

修改后:

gitlab = new Gitlab()
response = gitlab.GetRepoFile(21, "service.sh", "master")

成功:

这篇关于持续集成交付CICD:Jenkins使用GitLab共享库实现基于SaltStack的CD流水线部署前后端应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/503373

相关文章

Maven中的profiles使用及说明

《Maven中的profiles使用及说明》:本文主要介绍Maven中的profiles使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录主要用途定义 Profiles示例:多环境配置激活 Profiles示例:资源过滤示例:依赖管理总结Maven 中的

如何使用Haporxy搭建Web群集

《如何使用Haporxy搭建Web群集》Haproxy是目前比较流行的一种群集调度工具,同类群集调度工具有很多如LVS和Nginx,本案例介绍使用Haproxy及Nginx搭建一套Web群集,感兴趣的... 目录一、案例分析1.案例概述2.案例前置知识点2.1 HTTP请求2.2 负载均衡常用调度算法 2.

shell中set -u、set -x、set -e的使用

《shell中set-u、set-x、set-e的使用》本文主要介绍了shell中set-u、set-x、set-e的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录✅ 1. set -u:防止使用未定义变量 作用: 示例:❌ 报错示例输出:✅ 推荐使用场景:✅ 2. se

Redis 配置文件使用建议redis.conf 从入门到实战

《Redis配置文件使用建议redis.conf从入门到实战》Redis配置方式包括配置文件、命令行参数、运行时CONFIG命令,支持动态修改参数及持久化,常用项涉及端口、绑定、内存策略等,版本8... 目录一、Redis.conf 是什么?二、命令行方式传参(适用于测试)三、运行时动态修改配置(不重启服务

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

Python的端到端测试框架SeleniumBase使用解读

《Python的端到端测试框架SeleniumBase使用解读》:本文主要介绍Python的端到端测试框架SeleniumBase使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录SeleniumBase详细介绍及用法指南什么是 SeleniumBase?SeleniumBase

Qt 设置软件版本信息的实现

《Qt设置软件版本信息的实现》本文介绍了Qt项目中设置版本信息的三种常用方法,包括.pro文件和version.rc配置、CMakeLists.txt与version.h.in结合,具有一定的参考... 目录在运行程序期间设置版本信息可以参考VS在 QT 中设置软件版本信息的几种方法方法一:通过 .pro

Java继承映射的三种使用方法示例

《Java继承映射的三种使用方法示例》继承在Java中扮演着重要的角色,它允许我们创建一个类(子类),该类继承另一个类(父类)的所有属性和方法,:本文主要介绍Java继承映射的三种使用方法示例,需... 目录前言一、单表继承(Single Table Inheritance)1-1、原理1-2、使用方法1-

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级