接触Jenkins(Hudson)API,第2部分

这篇文章从本教程的第1部分继续。 已经快一年了,但是我终于有时间重新审视我为与Jenkins api交互而编写的一些代码。 我已经使用了部分工作来帮助管理许多Jenkins构建服务器,主要是保持插件同步以及将作业从一台机器移动到另一台机器。 在本文中,我将主要关注CLI jar功能以及您可以使用它进行的一些操作。 这主要是针对Jenkins开发的,但是我对Hudson进行了一些轻量级测试,并且可以在我尝试过的所有地方工作,因此对于您选择的构建服务器,代码始终是不可知的。

项目结构

该代码托管在Github上 ,并提供一个Gradle构建,该构建可在本地下载并启动Jenkins(或Hudson)服务器以执行测试。 服务器设置为使用Gradle构建目录作为其工作目录,因此只需执行gradle clean即可将其删除。 我使用所需库的Jenkins版本和Hudson版本进行了尝试,除了两个CLI实现之间的一些古怪之处外,它们的功能仍然相同。 如果要使用Hudson而不是Jenkins进行尝试,请传递命令标志-Pswitch,并将使用适当的war和库。 该项目旨在与Gradle 1.0-milestone-8一起运行,并带有该版本的Gradle包装器 。 自原始文章以来,大多数代码都保持不变,但是对Jenkins和Hudson的较新版本进行了一些增强和更改。
该项目产生的库以Maven工件的形式发布,稍后我将确切描述如何实现。 还包括一些示例,这些示例演示了在Gradle或Maven项目中以及在Grapes的Groovy脚本中如何使用该库。 我们使用Groovy 1.8.6,Gradle 1.0-milestone-8和Maven 3.0.3构建所有内容。

充分利用CLI

作为api的替代方法,CLI jar是一种非常强大的与构建服务器进行交互的方式。 除了各种内置命令之外,Groovy脚本还可以远程执行,而我们只需付出一点努力就可以轻松地序列化响应,以处理服务器上提取的数据。 作为执行环境,服务器提供Groovysh Shell并为hudson.model包存储导入。 该包中的Jenkins / Hudson单例对象的实例也传递给Binding 。 在这些示例中,我使用的是向后兼容的Hudson版本,因为该代码旨在在两种服务器上均可运行。

可用命令

内置命令种类繁多,所有这些命令均在hudson.cli包中实现。 以下是正在运行的应用程序的CLI页面上列出的内容:

  • build:构建作业,并且可以选择等待直到完成。
  • cancel-quiet-down:取消“ quiet-down”命令的效果。
  • clear-queue:清除构建队列
  • connect-node:重新连接到节点
  • 复制作业:复制一份工作。
  • create-job:通过读取stdin作为配置XML文件来创建新作业。
  • delete-builds:删除构建记录。
  • delete-job:删除工作
  • delete-node:删除节点
  • disable-job:禁用工作
  • 断开节点:与节点断开连接
  • enable-job:启用工作
  • get-job:将作业定义XML转储到stdout
  • groovy:执行指定的Groovy脚本。
  • groovysh:运行交互式groovy shell。
  • help:列出所有可用的命令。
  • install-plugin:从文件,URL或从更新中心安装插件。
  • install-tool:执行自动工具安装,并将其位置打印到stdout。 只能从
    内部版本。
  • keep-build:标记该构建以永久保留该构建。
  • list-changes:转储指定构建的变更日志。
  • login:保存当前凭证,以允许将来的命令在没有显式凭证信息的情况下运行。
  • 注销:删除使用登录命令存储的凭证。
  • 邮件:读取stdin并将其作为电子邮件发送出去。
  • offline-node:停止使用临时执行构建的节点,直到下一个“ online-node”命令。
  • online-node:在线使用节点执行构建,以取消先前的“ offline-node”命令。
  • 安静:安静下詹金斯,为重新启动做准备。 不要开始任何构建。
  • 重新加载配置:丢弃内存中所有已加载的数据,然后从文件系统重新加载所有内容。 有用的时候
    您直接在磁盘上修改了配置文件。
  • 重新启动:重新启动詹金斯
  • 安全重启:安全重启詹金斯
  • 安全关闭:将Jenkins置于安静模式,等待现有构建完成,然后关闭
    詹金斯
  • set-build-description:设置构建的描述。
  • set-build-display-name:设置构建的displayName
  • set-build-result:设置当前构建的结果。 仅当从内部调用时才有效。
  • shutdown:立即关闭Jenkins服务器
  • update-job:从stdin更新作业定义XML。 与get-job命令相反
  • version:输出当前版本。
  • wait-node-offline:等待节点脱机
  • wait-node-online:等待节点联机
  • 我是谁:报告您的凭据和权限

目前尚不清楚每个参数都需要什么参数,但是在不带参数调用时,它们几乎普遍遵循打印使用情况详细信息的CLI模式。 例如,当您不带任何参数调用build命令时,以下是您在错误流中返回的内容:

参数“ JOB”为必填项
java -jar jenkins-cli.jar建立args…
开始构建,然后选择等待完成。 除了一般的脚本使用之外,该命令可以是 用于从一个作业的构建中调用另一个作业。 使用-s选项,此命令将根据以下命令更改退出代码 构建的结果(退出代码0表示成功。) 使用-c选项,只有在存在 SCM变更 职位:要建立的工作名称 -c:在开始构建之前检查SCM更改,如果没有,请检查 更改,不进行构建即退出 -p:以键=值格式指定构建参数。 -s:等待命令完成/中止

从系统中取出数据

与远程系统的所有交互都由流处理,编写脚本非常容易,这些脚本将使用内置的Groovy工具以易于解析的String格式返回数据。 从理论上讲,您也应该能够封送更复杂的对象,但是现在让我们保持简单。 这是一个Groovy脚本,该脚本仅将所有作业名称提取到List中,并调用Groovy inspect方法引用所有值。

@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = "github", root = "http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApiString rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()
OutputStream out = new ByteArrayOutputStream()
cliApi.runCliCommand(rootUrl, ['groovysh', 'hudson.jobNames.inspect()'], System.in, out, System.err)
List allJobs = Eval.me(cliApi.parseResponse(out.toString()))
println allJobs

收到响应后,我们将做一些整理工作以删除String开头的一些多余字符,并使用Eval.me将String转换为List。 Groovy提供了多种将文本转换为代码的方法,因此,如果您的使用情况比这种简单情况复杂,则可以使用GroovyShell和Binding或其他替代方法将结果解析为有用的东西。 这种简单的技术也扩展到了Maps和其他类型,从而使得处理从服务器发送回的数据变得简单。

一些有用的例子

查找具有更新的插件并更新所有插件

这是一个使用Groovy脚本查找所有具有可用更新的插件,然后将结果返回给调用者,然后在所有插件上调用CLI'install-plugin'命令的示例。 方便地,此命令将安装插件(如果尚未安装)或将其更新到最新版本(如果已安装)。

def findPluginsWithUpdates = '''
Hudson.instance.pluginManager.plugins.inject([]) { List toUpdate, plugin ->if(plugin.hasUpdate()){toUpdate << plugin.shortName}toUpdate
}.inspect()
'''
OutputStream updateablePlugins = new ByteArrayOutputStream()
cliApi.runCliCommand(rootUrl, ['groovysh', findPluginsWithUpdates], System.in, updateablePlugins, System.err)def listOfPlugins = Eval.me(parseOutput(updateablePlugins.toString()))
listOfPlugins.each{ plugin ->cliApi.runCliCommand(rootUrl, ['install-plugin', plugin])
}

一次安装或升级一套插件

使用“管理插件” UI绝对可以胜任,并且是幂等的,因此多次运行它只会导致可能升级已安装的插件。 这套插件可能有些过分,但是我最近调查了一些插件以供使用。

@GrabResolver(name='glassfish', root='http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name="github", root="http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import static java.net.HttpURLConnection.*
import org.kar.hudson.api.*
import org.kar.hudson.api.cli.HudsonCliApiString rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()['groovy', 'gradle', 'chucknorris', 'greenballs', 'github', 'analysis-core', 'analysis-collector', 'cobertura','project-stats-plugin','audit-trail', 'view-job-filters', 'disk-usage', 'global-build-stats','radiatorviewplugin', 'violations', 'build-pipeline-plugin', 'monitoring', 'dashboard-view','iphoneview', 'jenkinswalldisplay'].each{ plugin ->cliApi.runCliCommand(rootUrl, ['install-plugin', plugin])
}//  Restart a node, required for newly installed plugins to be made available.
cliApi.runCliCommand(rootUrl, 'safe-restart')

查找所有失败的构建并触发它们

网络问题或基础设施事件可能导致大量构建一次全部失败,这并非罕见。 解决问题后,该脚本可用于验证构建是否均正常工作。

@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = "github", root = "http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApiString rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()
OutputStream out = new ByteArrayOutputStream()
def script = '''hudson.items.findAll{ job ->job.isBuildable() && job.lastBuild && job.lastBuild.result == Result.FAILURE
}.collect{it.name}.inspect()
'''
cliApi.runCliCommand(rootUrl, ['groovysh', script], System.in, out, System.err)
List failedJobs = Eval.me(cliApi.parseResponse(out.toString()))
failedJobs.each{ job ->cliApi.runCliCommand(rootUrl, ['build', job])
}

打开一个交互式Groovy Shell

如果您确实想在服务器上戳戳,则可以启动一个交互式外壳程序以检查状态并执行命令。 绑定了System.in流,并立即回显了来自服务器的响应。

@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = "github", root = "http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApi
/*** Open an interactive Groovy shell that imports the hudson.model.* classes and exposes* a 'hudson' and/or 'jenkins' object in the Binding which is an instance of hudson.model.Hudson*/
HudsonCliApi cliApi = new HudsonCliApi()
String rootUrl = args ? args[0] :'http://localhost:8080'
cliApi.runCliCommand(rootUrl, 'groovysh')

项目更新

去年发生了很多事情,所有项目依赖项都需要更新。 特别是,对Groovy,Gradle和Spock进行了一些非常不错的改进。 最值得注意的是,自0.9.2版以来,Gradle已经走了很长一段路。 Groovy 1.8中添加的JSON支持也很方便。 Spock在使用@Unroll时需要进行一些小的调整才能在测试报告中呈现动态内容,但这对于“老”方法和“ 链式存根 ”之类的功能来说是一笔不小的代价。 本质上,为了响应Groovy 1.8+中的更改,Spock @Unroll注释需要从以下更改:

@Unroll('querying of #rootUrl should match #xmlResponse')

闭包封装的GString表达式:

@Unroll({'querying of $rootUrl should match $xmlResponse'})

听起来语法还在不断变化,很高兴我在网上找到了关于这个问题的讨论 。

在Github上托管Maven存储库

也许您从前面的脚本示例中注意到了,我们正在引用一个已发布的库来获取HudsonCliApi类。 上周 ,我读了一篇有趣的文章 ,描述了如何使用内置的Github Pages发布Maven存储库。 尽管它的功能不如Nexus或Artifactory这样的存储库,但足以以标准方式将一些二进制文件提供给大多数常见的构建工具。 只需在标准Maven回购布局中发布二进制文件以及相关的Pom,即可开始比赛! 每个依赖关系管理系统都有其怪癖(我在看着您Ivy!),但是它们很容易解决,因此这里是Gradle,Maven和Groovy Grapes使用此项目代码生成的库的示例。 请注意,Jenkins / Hudson所需的某些依赖项在Maven中央存储库中不可用,因此我们从Glassfish存储库中获取它们。

摇篮

很简单,这适用于最新版本的Gradle,并假定您使用的是Groovy插件。

repositories {mavenCentral()maven {url 'http://maven.glassfish.org/content/groups/public/'}maven {url 'http://kellyrob99.github.com/Jenkins-api-tour/repository'}
}
dependencies {groovy 'org.codehaus.groovy:groovy-all:${versions.groovy}'compile 'org.kar:hudson-api:0.2-SNAPSHOT'
}

马文

xml中的内容基本上相同,在这种情况下,假设您使用的是GMaven插件

<repositories><repository><id>glassfish</id><name>glassfish</name><url>http://maven.glassfish.org/content/groups/public/</url></repository><repository><id>github</id><name>Jenkins-api-tour maven repo on github</name><url>http://kellyrob99.github.com/Jenkins-api-tour/repository</url></repository>
</repositories><dependencies><dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-all</artifactId><version>${groovy.version}</version></dependency><dependency><groupId>org.kar</groupId><artifactId>hudson-api</artifactId><version>0.2-SNAPSHOT</version></dependency>
</dependencies>

葡萄

在这种情况下,解决旧版本Groovy的某些传递依赖关系似乎存在问题,这就是为什么对此有显式排除的原因。

@GrabResolver(name='glassfish', root='http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name='github', root='http://kellyrob99.github.com/Jenkins-api-tour/repository')
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')

链接

  1. Github Jenkins-api-tour项目页面
  2. Github上的Maven存储库
  3. 脚本程序示例Groovy脚本
  4. Jenkins CLI文档

相关文章:

  1. 接触Jenkins(Hudson)API
  2. 使用Groovy脚本可以做的五件事
  3. Grails应用程序演示StackExchange API

参考:在Japkin上的“ ...”博客上 ,我们的JCG合作伙伴 Kelly Robinson 着手研究 Jenkins(Hudson)API,第2部分 。


翻译自: https://www.javacodegeeks.com/2012/08/hooking-into-jenkins-hudson-api-part-2.html

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

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

相关文章

php树莓派魔镜,用树莓派和显示器制作一面“魔镜”

所需要的材料一台显示器一块和显示器大小相同的双面镜一些2*4米的细木条树莓派机器必要组件(电源、HDMI线、usb无线网卡、键盘)木工工具(锯子、磨砂机、螺丝刀)螺丝、液态钉子选一个合适的显示器镜子的大小完全由显示器的类型和大小决定&#xff0c;所以我希望得到一个尽量大的…

【数字图像处理】[3]--直方图规范化

【数字图像处理】[3]--直方图规范化直方图规范化出现的原因是因为直方图均衡只能产生出固定的图像&#xff0c;不满足于需求&#xff0c;有时我们需要让直方图变成特定的直方图&#xff0c;于是有了直方图规范化原理&#xff1a;可能只看公式没什么感觉&#xff0c;我们来举一个…

JavaFX 2.0布局窗格– GridPane

毫无疑问&#xff0c; GridPane是JavaFX 2.0中功能最强大&#xff0c;最灵活的布局窗格。 它在由行和列组成的灵活网格中布置其子项&#xff0c;与Swing的GridBagLayout或HTML的表格模型非常相似。 这种方法使该窗格非常适合于任何形式的表单&#xff08;例如网站上的联系表单&…

leecode 题解 || Merge k Sorted Lists 问题

problem&#xff1a; Merge k sorted linked lists and return it as one sorted list.Analyze and describe its complexity.Tags Divide and Conquer Linked List Heap合并K个已序单链表 thinking&#xff1a; &#xff08;1&#xff09;题目没有要求不能够新开ListNode,所以…

PHP在浏览器中被拒绝请求,php控制请求页面浏览器缓

缓存的主要作用是防止用户频繁刷新网站页面&#xff0c;导致服务器数据库负担&#xff0c;既要保证信息更新的及时性&#xff0c;也要保证缓存能被充分利用。http协议里控制浏览器缓存的头有三个Cache-Control&#xff0c;Expires&#xff0c;Last-Modified&#xff0c;在PHP下…

js -03课 -03 js中的真假判断

真假的问题&#xff1a;数据类型-数字&#xff08;NaN&#xff09;、字符串、布尔、函数、对象&#xff08;elem、[]、{}、null&#xff09;、未定义真&#xff1a;非0的数字、非空字符串、true、函数、能找到的元素、[]、{}假&#xff1a;0、NaN、空字符串、false、不能找到的…

HBASE启动失败,Failed construction of Master: class org.apache.hadoop.hbase.master.HMaster

Master日志错误&#xff1a;2015-12-02 06:34:32,394 ERROR [main] master.HMasterCommandLine: Master exitingjava.lang.RuntimeException: Failed construction of Master: class org.apache.hadoop.hbase.master.HMasterat org.apache.hadoop.hbase.master.HMaster.constru…

Java线程:我应该创建几个

介绍 “我应该创建多少个线程&#xff1f;”。 许多年前&#xff0c;我的一个朋友问我这个问题&#xff0c;然后我按照“ CPU核心数 1”的指示给了他答案。 当您在这里阅读时&#xff0c;大多数人都在点头。 不幸的是&#xff0c;我们所有人当时都错了。 现在&#xff0c;如果您…

java ui自动化测试脚本,如何用Airtest编写UI自动化脚本(示例代码)

前言游戏并不像app一样直接把渲染树节点暴露出来&#xff0c;这就造成游戏UI自动化在元素定位上的不方便性&#xff0c;不过依赖airtest的图片识别&#xff0c;我们可以直接跳过元素检查&#xff0c;以图片对比的形式进行自动化&#xff0c;虽然效率可能会低一些&#xff0c;但…

Spring JDBC数据库连接池设置

对于任何Java应用程序而言&#xff0c; 在Spring框架中设置JDBC数据库连接池都是很容易的&#xff0c;仅需更改spring配置文件中的一些配置即可。使用Apache Commons DBCP和Commons Pool以及Spring框架的连接池是不错的选择&#xff0c;但是如果您拥有Web服务器和托管的J2EE容器…

BZOJ 3505 [Cqoi2014]数三角形(组合数学)

【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id3505 【题目大意】 给定一个nxm的网格&#xff0c;请计算三点都在格点上的三角形共有多少个。   注意三角形的三点不能共线。 【题解】 我们计算三个点组合的情况&#xff0c;去除横竖三共线&#xff0c;以及斜…

matlab多项式加法运算,matlab多项式运算与代数方程求解解析.ppt

* 多项式运算与代数方程求解 数学软件 Matlab Matlab基础及应用 * 多项式转化为符号表达式&#xff1a;poly2sym 四则运算&#xff1a;conv、deconv 导数与积分&#xff1a;ployder、polyint 求值与零点&#xff1a;polyval、polyvalm、roots、poly 多项式运算 主要内容 代数方…

java.lang.NoClassDefFoundError:如何解决–第3部分

本文是我们的NoClassDefFoundError故障排除系列的第3部分。 正如我在第一篇文章中提到的那样&#xff0c;有许多可能导致NoClassDefFoundError的问题。 本文将重点介绍该问题的最常见原因之一&#xff1a;Java类静态初始化程序块或变量的失败。 将提供一个示例Java程序&#xf…

django实现瀑布流、组合搜索、阶梯评论、验证码

django实现图片瀑布流布局 我们在一些图片网站上经常会看到&#xff0c;满屏都是图片&#xff0c;而且图片都大小不一&#xff0c;却可以按空间排列。默认一个div是占用一行&#xff0c;当想把div里的图片并排显示的时候&#xff0c;只能使用float属性&#xff0c;但是&#xf…

通过ifrmae异步下载文档

//通过ifrmae异步下载文档 function iframeGetFile(opts) {var defaultOpts {filePath: ,onload: function (e) { }}, iframeFile;$.extend(defaultOpts, opts);iframeFile document.createElement("iframe");iframeFile.onload function (e) {defaultOpts.onload…

IO与NIO –中断,超时和缓冲区

假设有一个系统有时需要将文件复制到几个位置&#xff0c;但是这种方式在响应速度至关重要的情况下。 换句话说&#xff0c;如果由于某种原因文件系统过载&#xff0c;并且我们无法在不到一秒钟的时间内写入文件&#xff0c;则应该放弃。 ExecutorService是一项非常方便的工作工…

实验5 matlab程序设计2,实验5 Matlab程序设计2

实验5 Matlab程序设计21. 实验目的&#xff1a;2. 掌握建立和执行M文件的方法&#xff1b; 3. 掌握实现选择结构的方法&#xff1b; 4. 掌握实现循环结构的方法。5. 熟悉利用向量运算来代替循环操作的方法。 6. 实验内容&#xff1a;27. 根据61111 122232n2&#xff0c;求π的近…

【poj1041】 John's trip

http://poj.org/problem?id1041 (题目链接) 题意 给出一张无向图&#xff0c;求字典序最小欧拉回路。 Solution 这鬼畜的输入是什么心态啊mdzz&#xff0c;这里用vector储存边&#xff0c;便于边的排序。瞬间变成STL常数boy →_→。 细节 数组大小把握好。 代码 // poj1041 #i…

记一次ora-1652错误的解决过程

报错现象&#xff1a; 通过v$RMAN_BACKUP_JOB_DETAILS查看备份状态&#xff0c;一直卡着不出结果&#xff0c;很长一段时间之后抛出ORA-1652: unable to extend temp segment by 128 in tablespace &#xff0c;此时查看临时表空间使用情况&#xff0c;发现占用很少&#xff0c…

带有docx4j的Java Word(.docx)文档

几个月前&#xff0c;我需要创建一个包含许多表和段落的动态Word文档。 过去&#xff0c;我曾使用POI来实现此目的&#xff0c;但是我发现它很难使用&#xff0c;并且在创建更复杂的文档时对我来说效果不佳。 因此&#xff0c;对于这个项目&#xff0c;经过一番搜索&#xff0c…