持续集成交付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

相关文章

Python实现开根号的五种方式

《Python实现开根号的五种方式》在日常数据处理、数学计算甚至算法题中,开根号是一个高频操作,但你知道吗?Python中实现开根号的方式远不止一种!本文总结了5种常用方法,感兴趣的小伙伴跟着小编一起... 目录一、为什么需要多种开根号方式?二、5种开根号方式详解方法1:数学库 math.sqrt() ——

springboot项目中集成shiro+jwt完整实例代码

《springboot项目中集成shiro+jwt完整实例代码》本文详细介绍如何在项目中集成Shiro和JWT,实现用户登录校验、token携带及接口权限管理,涉及自定义Realm、ModularRe... 目录简介目的需要的jar集成过程1.配置shiro2.创建自定义Realm2.1 LoginReal

SpringBoot集成Shiro+JWT(Hutool)完整代码示例

《SpringBoot集成Shiro+JWT(Hutool)完整代码示例》ApacheShiro是一个强大且易用的Java安全框架,提供了认证、授权、加密和会话管理功能,在现代应用开发中,Shiro因... 目录一、背景介绍1.1 为什么使用Shiro?1.2 为什么需要双Token?二、技术栈组成三、环境

gorm乐观锁使用小结

《gorm乐观锁使用小结》本文主要介绍了gorm乐观锁使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录前言grom乐观锁机制gorm乐观锁依赖安装gorm乐观锁使用创建一个user表插入数据版本号更新总结前言乐观锁,顾名

nginx配置错误日志的实现步骤

《nginx配置错误日志的实现步骤》配置nginx代理过程中,如果出现错误,需要看日志,可以把nginx日志配置出来,以便快速定位日志问题,下面就来介绍一下nginx配置错误日志的实现步骤,感兴趣的可... 目录前言nginx配置错误日志总结前言在配置nginx代理过程中,如果出现错误,需要看日志,可以把

Java 与 LibreOffice 集成开发指南(环境搭建及代码示例)

《Java与LibreOffice集成开发指南(环境搭建及代码示例)》本文介绍Java与LibreOffice的集成方法,涵盖环境配置、API调用、文档转换、UNO桥接及REST接口等技术,提供... 目录1. 引言2. 环境搭建2.1 安装 LibreOffice2.2 配置 Java 开发环境2.3 配

Python 函数详解:从基础语法到高级使用技巧

《Python函数详解:从基础语法到高级使用技巧》本文基于实例代码,全面讲解Python函数的定义、参数传递、变量作用域及类型标注等知识点,帮助初学者快速掌握函数的使用技巧,感兴趣的朋友跟随小编一起... 目录一、函数的基本概念与作用二、函数的定义与调用1. 无参函数2. 带参函数3. 带返回值的函数4.

MySQL中DATE_FORMAT时间函数的使用小结

《MySQL中DATE_FORMAT时间函数的使用小结》本文主要介绍了MySQL中DATE_FORMAT时间函数的使用小结,用于格式化日期/时间字段,可提取年月、统计月份数据、精确到天,对大家的学习或... 目录前言DATE_FORMAT时间函数总结前言mysql可以使用DATE_FORMAT获取日期字段

Qt中实现多线程导出数据功能的四种方式小结

《Qt中实现多线程导出数据功能的四种方式小结》在以往的项目开发中,在很多地方用到了多线程,本文将记录下在Qt开发中用到的多线程技术实现方法,以导出指定范围的数字到txt文件为例,展示多线程不同的实现方... 目录前言导出文件的示例工具类QThreadQObject的moveToThread方法实现多线程QC

Go语言使用sync.Mutex实现资源加锁

《Go语言使用sync.Mutex实现资源加锁》数据共享是一把双刃剑,Go语言为我们提供了sync.Mutex,一种最基础也是最常用的加锁方式,用于保证在任意时刻只有一个goroutine能访问共享... 目录一、什么是 Mutex二、为什么需要加锁三、实战案例:并发安全的计数器1. 未加锁示例(存在竞态)