设为首页 收藏本站
查看: 1083|回复: 0

[经验分享] Jenkins: 使用groovy + job-dsl 创建并触发job

[复制链接]

尚未签到

发表于 2018-1-7 13:47:21 | 显示全部楼层 |阅读模式
Jenkins: 使用groovy + job-dsl 创建并触发job

背景:
  我们的 Automation 测试脚本需要在10个不同语言的机器上跑,本地化测试产品。
  
我们用Jenkins启动测试执行,需要同时向1-10个机器发送文件和脚本运行命令,现有Jenkins的配置采用master/slave 机制如下:
  Dispatcher Job:
  1。 启用参数化,每个语言机器传递两个参数:
  

- Choice Parameter: slave Node 名,比如这里的NodeLabel1,表示第一台目标机器  


  

- File Parameter: 要发送给目标机器的文件  


  2。 在Build Steps中trigger seed job:

  Seed Job: 设置具体的运行脚本。

现有设计的问题:
  运行很流畅,但是维护不方便


  • 每个Slave Node都添加一个Choice Paramter 和 File Parameter,
  • Build Step中也要添加10次trigger seed job,
  • Steps中如有一处脚本改动,需重复改动10次
  • 如果有新添加测试机器,需要在Parameters中手动添加新Node, 在Steps中也要添加。
改进需求:
  自动获取所有Node列表,减少不必要的手动增添Node。
  在Build Steps中,通过脚本trigger seed job,这样避免重复设置10次trigger step, 提高可重复性(Reusability)。

改进方案:
  使用Groovy脚本,安装Jenkins插件:


  •   Active Choices: 一个蛮好的参数化插件,可插入Groovy脚本和文件(集成Scriptlet插件)。

  •   Scriptler:Groovy脚本插件,可以集中管理脚本文件。

  •   Job-DSL: 一个很好的利用DSL设置和运行Job的插件。

具体实施:

准备global scripts,获取全部节点,用的是scriptler插件。
  1。 在Jenkins->Scriptler中创建getAllNodeByProject.groovy文件,用来获取所有的Node机器。需要的话也可以加入一些筛选条件,比如在线与否。
  scriptler中支持参数传递,这里的project就是预先设置的参数,可在job调用该脚本时进行设置。
  

  def list = jenkins.model.Jenkins.instance.slaves.findAll{
  if (it.name.contains(project)) it.name
  }.collect{it.name}
  list.add(0,"None")
  return list
  


  2。 在Jenkins->Scriptler中创建getRuntimeNodes.groovy文件,用来获取dispatcher job在运行时指定的Node机器。
  

  import hudson.model.*
  def list =""
  def runable=false
  def build = Thread.currentThread()?.executable
  // get the selected node parameter value at runtime
  def nodes = build?.actions.find { it instanceof ParametersAction }?.parameters.collect{
  (it instanceof StringParameterValue)?it.value:""
  } as List
  println "node is $nodes"
  nodes.unique().removeAll(["None"])
  nodes.remove(" ")
  nodes.remove("")
  if (nodes!=[]) {
  list=nodes.join(",").toString()
  }
  println "list is:  $list"
  if (list!=" " && list!="") runable=true
  println "runable is $runable"
  build.addAction( new ParametersAction([new StringParameterValue("runtimeNodes",list)]))
  build.addAction( new ParametersAction([new BooleanParameterValue("runable",runable)]))
  

  运行结果是,在dispatcher job runtime会新建两个参数:


  •   String参数 runtimeNodes: 存放运行时获取用户指定的Node 机器列表,用于后续在这些node 机器上分别trigger seed job

  •   布尔型参数 runable:如果没有指定任何Node,则将runable设为false, 即不会trigger seed job

创建main,dispatcher和seed jobs
  手动创建一个名为main的 job, 用来动态生成dispatcher and seed jobs.

在main中用job-dsl创建dispatcher job
  在main job中,插入一个Process Job DSLs 构建步骤, 下面的代码会在运行时创建一个名为dispatcher的job:


  • 为每个language node (“Client_CHS","Client_JPN") 设置了active choice node 参数和File参数。
  • 创建一个conditional step, 如果符合条件,则trigger seed job,并将用户运行时指定的所有node以NodeListFactory参数方式传给seed job。
  

  import hudson.model.*
  

  // get all available nodes if its name contains "client" - specific for our project use;
  def nodes = hudson.model.Hudson.instance.slaves.findAll{
  if (it.name.contains("Client")) it.name
  }.collect{it.name}
  nodes.add(0,"None")
  

  //def nodes = ["Client_JPN","Client_CHS"]
  

  defineJob(nodes-["None"],"dispatcher") // setup the dispatcher job
  

  // method to define a dispatcher job
  def defineJob(nodes,jobName) {
  return job(jobName) {
  def list =[]
  nodes.each {
  def node =it
  parameters {
  activeChoiceParam(node) {
  description('Allows user choose from choices')
  filterable()
  choiceType('SINGLE_SELECT')
  scriptlerScript('getAllNodesByProject.groovy') {
  parameter('project', 'Client')
  }
  }
  fileParam(node+'_File', 'Select test case file to upload')
  }
  }
  

  steps {
  //systemGroovyScriptFile('${JENKINS_HOME}\\scriptler\\scripts\\getRuntimeNodes.groovy') {
  systemGroovyCommand(readFileFromWorkspace("${JENKINS_HOME}\\scriptler\\scripts\\getRuntimeNodes.groovy")){
  }
  conditionalSteps {
  condition {
  booleanCondition("\${runable}")
  }
  

  steps{ downstreamParameterized {
  trigger('seed') {
  /* parameters{
  println node
  nodeLabelBuildParameter {
  name(node)
  nodeLabel(node)
  }*/
  parameterFactories {
  nodeListBuildParameterFactory {
  

  // The name of the parameter to set.
  name("test")
  // A comma separated list of nodes to execute the job on.
  nodeListString("\${runtimeNodes}")
  

  }
  //booleanParam("f",true) /
  }
  }
  }
  }
  }
  }
  }
  }
  

  现在运行 main job,成功后你会看到 dispatcher job 和 seed job 生成了


  进入 dispatcher job, 选择 build with parameters,会看到我们想要的参数都列出来了。


在main中用job-dsl创建 seed job
  打开main job,再次插入一个Process Job DSLs 构建步骤, 下面的代码会在运行时创建一个名为 seed 的job, seed job 会 触发实际执行的自动化脚本,这里为简单起见,我们让它执行一行命令。这里用到了Node and Label parameter 插件
  

  job("seed") {
  concurrentBuild()
  /*parameters{
  nodeParam("node") {
  description('Select Test Node')
  defaultNodes(["Test Node"])
  allowedNodes(["Test Node"])
  }*/
  

  steps {
  batchFile('echo Hello World!')
  }
  }
  

  

  现在再运行一次main job, 回到job 列表中,可以看到dispatcher和seed都列在其中了。

  点击进入seed job, 便可以看到上面定义的batch command step了。

  现在,dispatcher和seed job都就位了,接下来我们需要修改dispatcher,让它运行时trigger seed job.

测试:允许dispatcher job
  运行的时候我们手动或自动触发 dispatcher job.
  进入dispatcher job, 选择 build with parameters,


  • 将所有Node 都设为"None", 运行结果显示,seed job 没有trigger。成功


  •   指定一个或多个Node(不为None),运行结果显示,seed job在指定Nodes上触发了。成功


  上述操作还没有将File Parameter的使用加上去,后续再补充。欢迎一起讨论!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-432575-1-1.html 上篇帖子: jenkins+svn+gradle自动化部署笔记 下篇帖子: Jenkins备份与恢复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表