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

成功:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/226573.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Redis构建简单的社交网站

文章目录 第1关:创建用户与动态第2关:处理用户关系第3关:状态与信息流 第1关:创建用户与动态 编程要求 在Begin-End区域编写 create_user(login_name, real_name) 函数,实现创建新用户的功能,具体参数与要…

【javascript】npm ERR! cb() never called!

错误 环境 windows 10 nvm node 14.17.0 如何解决 尝试了 5 种方法 1,npm cache clean --force 2, npm cache verify 3, 删掉package-lock.json (然鹅我的这个项目没有这个文件) 4, npm set strict-ssl false 5, 删除node_modules 这五种…

Excel中MATCH和INDEX函数的用法详解,以及Vlookup的数组用法

match函数 目的:查询函数,范围单元格中搜索特定的项,然后返回该项在此区域中的相对位置。 For example:让 match 去【隔壁办公室】找【老张】 Match 回复:【老张】坐在【隔壁办公室】第【四】个座位上 公式:【 mat…

【FPGA/verilog -入门学习7】 条件判断if与分支判断case语句的语法介绍

需求 使用if 和case 产生格雷码 / /*条件判断if与分支判断case语句的语法介绍 需求 使用if 和case 产生格雷码*/ / timescale 1ns/1ps module vlg_design(input [3:0] i_data, output reg [3:0] o_data,output reg [3:0] o_datac);always (*) begin if (4b0000 i_data) o_d…

MySQL数据库 入门

目录 一、MySQL概述 二、MySQL安装 安装数据库 配置数据库 启动停止数据库 客户端连接数据库 三、数据模型 四、SQL 一、MySQL概述 先来讲解三个概念:数据库、数据库管理系统、 SQL 。 而目前主流的关系型数据库管理系统的市场占有率排名如下: …

【从零开始学习--设计模式--代理模式】

返回首页 前言 感谢各位同学的关注与支持,我会一直更新此专题,竭尽所能整理出更为详细的内容分享给大家,但碍于时间及精力有限,代码分享较少,后续会把所有代码示例整理到github,敬请期待。 此章节介绍建…

C语言算法与数据结构,旅游景区地图求最短路径

背景: 本次作业要求完成一个编程项目。请虚构一张旅游景区地图,景区地图包括景点(结点)和道路(边):地图上用字母标注出一些点,表示景点(比如,以点 A、B、C、…

vue2使用wangeditor实现数学公式+富文本编辑器

需求: 做一个带有数学公式的富文本编辑器,在网上看了很多,这个最合适,借鉴了wangEditor富文本编辑器 这里面写的是v3的整合富文本编辑器,我照着上面改成了v2的,本文章主要是实现步骤和错误解决,…

【数据结构】单链表的定义和操作

目录 1.单链表的定义 2.单链表的创建和初始化 3.单链表的插入节点操作 4.单链表的删除节点操作 5.单链表的查找节点操作 6.单链表的更新节点操作 7.完整代码 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助…

2023-12-16:用go语言,给定整数数组arr,求删除任一元素后, 新数组中长度为k的子数组累加和的最大值。 来自字节。

2023-12-16:用go语言,给定整数数组arr,求删除任一元素后, 新数组中长度为k的子数组累加和的最大值。 来自字节。 答案2023-12-16: 来自左程云。 灵捷3.5 大体步骤如下: 算法 maxSum1 分析&#xff1…

网络时间服务器

本章主要介绍网络时间服务器。 使用chrony配置时间服务器 配置chrony客户端向服务器同步时间 1 时间同步的必要性 一些服务对时间要求非常严格,例如,图所示的由三台服务器搭建的ceph集群。 这三台服务器的时间必须保持一致,如果不一致&#…

杰卡德的故事

三个男人分别是杰卡德距离 杰卡德相似系数和杰卡德系数 杰卡德相似系数和杰卡德距离是互为相反数的。 杰卡德系数和杰卡德距离是不是一回事 感觉是一回事

DevOps搭建(二)-阿里云镜像仓库的使用详解

博主介绍:Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 🍅文末获取源码下载地址🍅 👇🏻 精彩专栏推荐订阅👇🏻…

NVIDIA A100 PCIE 40GB k8s-device-plugin install in kubernetes

文章目录 1. 目标2. 简介2.1 英伟达 A100 技术规格2.2 架构优势2.3 显卡跑分对比2.4 英伟达 A100 与 kubernetes 3. 安装 NVIDIA A100 GPU 40G 硬件4. NVIDIA R450 datacenter driver5. NVIDIA Container Toolkit6. 创建 runtimeclass5. MIG Strategies6. 配置仓库7. 下载镜像8…

Spring cloud - 断路器 Resilience4J

其实文章的标题应该叫 Resilience4J,而不是Spring Cloud Resilience4J,不过由于正在对Spring cloud的一系列组件进行学习,为了统一,就这样吧。 概念区分 首先区分几个概念 Spring cloud 断路器:Spring Cloud的官网对…

02_Web开发基础之JavaScript

Web开发基础之JavaScript 学习目标和内容 1、能够描述Javascript的作用 2、能够使用分支结构if语句逻辑判断 3、能够使用其中一种循环语句 4、能够定义javaScript中的函数 5、能够定义javaScript中的对象 6、能够描述DOM的作用 7、能够通过DOM操作HTML标签元素及其属性 8、能够…

走进暄桐教室 一起观看暄桐同学作品及感受

暄桐是一间传统美学教育教室,创办于2011年,林曦是创办人和授课老师,教授以书法为主的传统文化和技艺,旨在以书法为起点,亲近中国传统之美,以实践和所得,滋养当下生活。其实,暄桐教室…

数据结构与算法—查找算法(线性查找、二分查找、插值查找、斐波那契查找)

查找算法 文章目录 查找算法1. 线性查找算法2. 二分查找算法2.1 二分查找思路分析2.2 应用实例 3. 插值查找3.1 基本原理3.2 应用实例 4. 斐波那契4.1 基本原理4.2 应用实例 5. 查找总结 在java中,常用的查找有四种: 顺序(线性)查找二分查找/折半查找插值…

广州华锐互动:汽车电子线束加工VR仿真培训与实际生产场景相结合,提高培训效果

随着科技的不断发展,虚拟现实(VR)技术已经逐渐渗透到各个领域,为企业和个人带来了前所未有的便利。在汽车制造行业中,线束加工作为一项关键的生产工艺,其质量直接影响到汽车的性能和安全。因此,…

基于中小微企业_个体工商户的信贷评分卡模型和用户画像(论文_专利_银行调研建模使用)

背景介绍 信用贷款是指由银行或其他金融机构向中小微企业和个体工商户提供的一种贷款产品。该贷款的特点是无需提供抵押品或担保,主要依据借款人的信用状况来进行评估和审批。 中小微企业和个体工商户信用贷款的申请流程相对简单,申请人只需要提供个人…