# Pipeline 入门
# 什么是CORNERSTONE Pipeline?
CORNERSTONE Pipeline (或简称为 "Pipeline" ),它是一个自动化服务模块,可用于自动化各种任务, 如构建,测试和部署软件。跟Jenkins的流水线类似,CORNERSTONE通过Pipeline实现了持续集成(CI)和持续交付(CD)的功能。
需要注意的是,CORNERSTONE Pipeline虽然兼容了大量Jenkins流水线的概念,但依然与Jenkins流水线有明显的不同,Jenkins流水线的设计思想表达了这样一种流程:将基于版本控制管理的软件持续的交付到用户手中。
而与Jenkins不同,CORNERSTONE Pipeline希望通过提供一些基础的概念设计以及命令函数,来允许用户自定义的实现自己想要的功能(代码的持续集成,APP的编译发布,Sonar代码检查等等)。 换言之,CORNERSTONE Pipeline更像是一种粘合剂,我们并不直接提供特定功能,Pipeline最终能实现何种功能,取决于您如何使用它。
下面我们先从一个简单的例子开始讲起。
# Hello Pipeline
var pipeline={
stages:{
download:{
node:'compile',
workspace:'/opt/soft/',
steps:{
download(){
ret = $.sh('wget http://download.redis.io/releases/redis-4.0.14.tar.gz');
if(ret!=0){
$.print('下载Redis文件失败');
}
}
}
}
}
}
上面是一个最简单的Pipeline,它只实现了一个功能,在一台名叫compile的主机上,执行wget这个shell命令,以达成将redis安装包下载到/opt/soft/目录的目的。如果下载失败, 那么打印输出下载Redis文件失败。
让我们先忽略掉stages,node,workspace,steps这些概念,我们会在接下来的章节一一讲到他们。您可以看出实际上一个pipeline就是一段JavaScript的脚本。在满足我们对pipeline基础格式的前提下, 您可以基于JavaScript语法任意书写pipeline来实现您的功能。
下面我们会先开始讲解pipeline中的一些基本的概念,等概念讲解完毕后,我们会继续讲解pipeline的基础格式要求。
# 入门指南
# Pipeline 基本概念
stages
描述了 Pipeline 的一个阶段集合,Pipeline 实际上就是由多个 stage 组成,每个 stage 完成对应的一组事情。 在语法上,stages是pipeline对象里面的一个属性,stages属性本身也是一个对象。 我们规定,stages对象里面定义的任意属性都是一个stage阶段,Pipeline会按照stages对象中属性出现的顺序执行各个stage阶段。
让我们回看下上一节的例子:
var pipeline={ stages:{ download:{ node:'compile', workspace:'/opt/soft/', steps:{ download(){ ret = $.sh('wget http://download.redis.io/releases/redis-4.0.14.tar.gz'); if(ret!=0){ $.print('下载Redis文件失败'); } } } } } }
在这个简单的例子中,我们在Pipeline中只定义了一个download的stage。Pipeline并不强制约束您拆分stage的方式,这取决于您流水线的复杂程度。 例如,您可以根据您流水线的实际情况,将stage拆分为"compile"、"test"和"deploy"等等。
每一个Stage中,有三个属性有特殊含义,分别是node,workspace,steps。
node
node是指主机,您可以回顾我们前面章节的讲解。node的有效取值是在主机页面定义的某一个主机的名称。 node是必填字段,pipeline中需要至少有一个node属性字段。
node属性可以存在于pipeline对象中,和stages属性平级,如果定义在此处,意味着pipeline中所有的操作都是执行在该主机下。
node属性也可以存在于某个stage对象中(就像我们上面的例子一样),这意味着这个stage阶段里面的所有操作都会执行在该主机下。
workspace
workspace是指pipeline运行在主机时所在的文件目录,需要跟node配合使用。还是以我们上面的例子为例,在这个例子里面,node为compile, workspace为/opt/soft/。也就是最终redis的包会下载到名字为compile的主机的/opt/soft/目录下,如果该主机上/opt/soft/目录不存在,pipeline会执行报错。
steps
steps是一个对象,我们规定,所有定义在steps中的函数都是一个step(执行步骤)。pipeline会按照step出现的先后顺序来逐一执行。
# Pipeline 方法摘要
在上面的例子中我们看到最终在download step函数中,shell命令通过$.sh()来执行,其中sh就是pipeline的函数,pipeline约定所有的函数都是需要以$.函数名()的方式来调用。 下面是全部的pipeline函数。
返回值 | 方法名和摘要 |
---|---|
int | sh(String cmd) 执行命令 cmd: Shell命令 |
void | copyFrom(String machineName,String remoteFilePath,String localFilePath) 拉取指定节点[主机]指定远程目录下的文件至本地目录 machineName:主机节点名称 remoteFilePath:远程文件路径 localFilePath:本地文件路径 |
void | copyTo(String localFilePath,String machineName,String remoteFilePath) 拷贝本地路径下的文件至指定节点[主机]目录。 remoteFilePath:本地文件路径 machineName:主机节点名称 remoteFilePath:远程文件路径 |
String | sendNotification(String userName,String content) 发送通知给指定用户 userName:系统用户名 content:通知内容 |
boolean | portTest(String host,int port) 测试host对应服务器port端口是否在监听 host: 主机IP或域名 port:端口 |
void | sleep(long millis) 休眠。 millis: 毫秒 |
void | print(String message) 打印消息,并记录消息内容。 message: 打印消息内容 |
void | printQRCode(String message) 打印二维码消息,并记录消息内容。 message: 打印消息内容 |
Object | parameter(String parameterName) 接收参数 parameterName: 参数名称 ==参数接收超时时间为:60s== |
void | abort(String message) 终止 message: 终止说明,并记录日志内容 |
sh的额外说明:
一次性执行多条shell的方法:
- 每个命令之间用;隔开
各命令的执行给果,不会影响其它命令的执行。换句话说,各个命令都会执行,但不保证每个命令都执行成功。
- 每个命令之间用&&隔开
若前面的命令执行成功,才会去执行后面的命令。这样可以保证所有的命令执行完毕后,执行过程都是成功的。
- 每个命令之间用||隔开
||是或的意思,只有前面的命令执行失败后才去执行下一条命令,直到执行成功一条命令为止。
# Pipeline 运行状态
用户可以通过Pipeline执行窗口,查阅当前执行的状态
# Pipeline 入门总结
在了解完Pipeline所有的基本属性后,我们可以回过头来总结下Pipeline的基础写法。
var pipeline={
stages:{
stage1:{
node:"主机名称",
workspace:'工作位置',
steps:{
step1(){
$.sh('echo helloworld');
},
//...
}
},
stage2:{
//...
}
}
};
- 首先Pipeline中必须定义一个pipeline对象,固定写法var pipeline={};
- stages是执行阶段的集合,stages对象里面定义的所有变量都是一个stage,我们要求stages中至少要有一个stage阶段。
- stage中可以定义node和workspace的值。
- steps是stage中执行步骤的汇总,所有定义在steps中的函数都是一个step(执行步骤)。pipeline会按照step出现的先后顺序来逐一执行
- 我们可以通过$.xxx()来执行pipeline函数。
# Pipeline 构建触发器
在持续集成的过程中,我们经常会遇到一些需要定期执行的Pipeline任务。比如我们需要在明天早上9点前,发布最新的应用版本。此时就需要通过定时任务来辅助我们完成这些定时的触发任务,已达到周期进行构建的目的。 我们通过Cron表达式来完成定时任务的工作。Cron表达式的格式如下:
Cron 结构说明 从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份
Cron表示式示例
表示式 | 说明 |
---|---|
0 0 2 1 * ? * | 表示在每月的1日的凌晨2点调整任务 |
0 0 10,14,16 * * ? | 每天上午10点,下午2点,4点 |
0 0/30 9-17 * * ? | 朝九晚五工作时间内每半小时 |
0 0 12 ? * WED | 表示每个星期三中午12点 |
0 0 12 * * ? | 每天12点运行 |
0 15 10 ? * * | 每天上午10:15触发 |
0 15 10 * * ? * | 每天上午10:15触发 |
0 15 10 * * ? 2020 | 在2020年的每天10:15运行 |
0 15 10 ? * MON-FRI | 周一至周五的上午10:15触发 |
0 0 12 ? * WED | 表示每个星期三中午12点 |
0 15 10 15 * ? | 每月15日上午10:15触发 |
0 15 10 L * ? | 每月最后一日的上午10:15触发 |
0 15 10 ? * 6L | 每月的最后一个星期五上午10:15触发 |
0 15 10 ? * 6#3 | 每月的第三个星期五上午10:15触发 |
0 15 10 ? * 6L 2019-2020 | 2019年至2020年的每月的最后一个星期五上午10:15触发 |