都。 幾個月前,我開始使用Hudson v1.395來從事這個小項目,在出現巨大分歧之后又回到了這個項目。 我以此為契機,看我將來選擇永久搬到詹金斯時是否會遇到任何重大問題。 有很多麻煩-最值得注意的是,新的CLI jar不能立即使用-但Jenkins的整體v1.401在切換后按預期工作。 好消息是,舊版本的CLI jar仍然有效,因此此示例實際上是使用代碼混合來完成工作。 無論如何,該軟件非常出色,并且值得稱贊的有余。
API
Jenkins / Hudson有一個便捷的遠程API,其中包含有關您的構建的信息,并支持一組豐富的功能來遠程控制它們以及服務器(通常是服務器)。 可以觸發構建,復制作業,停止服務器,甚至遠程安裝插件。 與服務器的API交互時,可以選擇XML,JSON或Python。 而且,正如內置文檔所述,您可以在以下位置的相對路徑中找到構建服務器URL所需的功能:
“ /.../api/,其中“ ...”部分是您要訪問的對象”。
如果您在瀏覽器中導航到該頁面,它將顯示一個簡短的文檔頁面,如果您將所需的格式添加為路徑的最后一部分,則將返回結果。 例如,要加載有關運行本地托管Jenkins服務器的計算機的信息,對此URL的get請求將以JSON格式返回結果:http:// localhost:8080 / computer / api / json。
{'busyExecutors': 0,'displayName': 'nodes','computer': [{'idle': true,'executors': [{},{}],'actions': [],'temporarilyOffline': false,'loadStatistics': {},'displayName': 'master','oneOffExecutors': [],'manualLaunchAllowed': true,'offline': false,'launchSupported': true,'icon': 'computer.png','monitorData': {'hudson.node_monitors.ResponseTimeMonitor': {'average': 111},'hudson.node_monitors.ClockMonitor': {'diff': 0},'hudson.node_monitors.TemporarySpaceMonitor': {'size': 58392846336},'hudson.node_monitors.SwapSpaceMonitor': null,'hudson.node_monitors.DiskSpaceMonitor': {'size': 58392846336},'hudson.node_monitors.ArchitectureMonitor': 'Mac OS X (x86_64)'},'offlineCause': null,'numExecutors': 2,'jnlpAgent': false}],'totalExecutors': 2
}
這是使用GraphViz渲染的同一棵樹。

此功能從服務器的根開始在樹中擴展,您可以通過在網址上提供“ depth”參數來控制從任何特定分支加載的樹的數量。 請注意您指定此變量的高度。 在人口眾多,運行時間較長的構建服務器(數十個具有數千個作業執行的構建)上進行了四個加載深度的測試,從而設法使我定期超時。 為了讓您有個想法,這里是api根深3處的域的非常粗略的可視化。

從服務器中獲取數據非常簡單,但是遠程觸發服務器上的活動的能力更加有趣。 為了觸發名為“ test”的作業的構建,http:// localhost:8080 / job / test / build上的POST執行了該作業。 使用可用的設施,很容易做到:
- 加載作業的配置文件,對其進行修改并通過發布新的config.xml文件來創建新作業
- 將作業從一臺構建機器移至另一臺
- 建立計劃的構建概述
CLI Jar
還有另一種方法可以在與服務器一起分發的CLI jar中遠程驅動構建服務器。 這個jar提供了用于在構建服務器上遠程執行某些命令的簡單工具。 值得注意的是,這使遠程安裝插件和執行遠程Groovy Shell成為可能。 我將這個功能與CLI罐公開的主類的非常薄的包裝器結合在一起,如下一個代碼示例所示。
/*** Drive the CLI with multiple arguments to execute.* Optionally accepts streams for input, output and err, all of which* are set by default to System unless otherwise specified.* @param rootUrl* @param args* @param input* @param output* @param err* @return*/
def runCliCommand(String rootUrl, List<String> args, InputStream input = System.in,OutputStream output = System.out, OutputStream err = System.err)
{def CLI cli = new CLI(rootUrl.toURI().toURL())cli.execute(args, input, output, err)cli.close()
}
這是一個簡單的測試,顯示了如何執行Groovy腳本以加載有關作業的信息,類似于您可以從服務器上內置的Groovy腳本控制臺執行的操作,該操作可在http:/本地安裝的部署中找到。 / localhost:8080 / script。
def 'should be able to query hudson object through a groovy script'()
{final ByteArrayOutputStream output = new ByteArrayOutputStream()when:api.runCliCommand(rootUrl, ['groovysh', 'for(item in hudson.model.Hudson.instance.items) { println('job $item.name')}'],System.in, output, System.err)then:println output.toString()output.toString().split('\n')[0].startsWith('job')
}
如果您想了解更多信息,下面是一些有關CLI的文章鏈接:
- 哈德遜CLI Wikidoc
- Jenkins CLI Wikidoc
- Jenkins上PHP作業的模板
- 川口浩輔的文章
- 一個不錯的教程
HTTPBuilder
如今 ,當針對HTTP API進行編程時, HTTPBuilder是我的首選工具。 用法非常簡單,我只能使用兩種方法來支持到達整個API:一種用于GET,一種用于POST。 這是GET方法,足以執行請求,解析JSON響應并完成(盡管很幼稚)錯誤處理。
/*** Load info from a particular rootUrl+path, optionally specifying a 'depth' query* parameter(default depth = 0)** @param rootUrl the base url to access* @param path the api path to append to the rootUrl* @param depth the depth query parameter to send to the api, defaults to 0* @return parsed json(as a map) or xml(as GPathResult)*/
def get(String rootUrl, String path, int depth = 0)
{def statusHTTPBuilder http = new HTTPBuilder(rootUrl)http.handler.failure = { resp ->println 'Unexpected failure on $rootUrl$path: ${resp.statusLine} ${resp.status}'status = resp.status}def infohttp.get(path: path, query: [depth: depth]) { resp, json ->info = jsonstatus = resp.status}info ?: status
}
調用它來獲取數據是一個內襯,因為唯一的真正區別是調用API時使用的“路徑”變量。
private final GetRequestSupport requestSupport = new GetRequestSupport()...
/*** Display the job api for a particular Hudson job.* @param rootUrl the url for a particular build* @return job info in json format*/
def inspectJob(String rootUrl, int depth = 0)
{requestSupport.get(rootUrl, API_JSON, depth)
}
從技術上講,這里沒有什么可以將其限制為僅JSON。 HTTPBuilder的一大優點是,它將很高興地嘗試對響應進行正確的處理。 如果返回的數據為JSON格式(如以下示例所示),則將其解析為JSONObject。 另一方面,如果數據是XML,則將其解析為Groovy GPathResult。 盡管導航對象圖的語法不同,但它們都很容易導航。
你能做什么呢?
探索Hudson / Jenkins API的主要動機是了解如何使管理多臺服務器變得更加容易。 目前,我每天處理四臺構建服務器和另一臺從屬計算機,并支持各種不同版本的分支。 這包括單元測試套件和功能測試套件的混合,以及持續進行的部署作業,該作業定期將更改推送到與我們支持的平臺矩陣匹配的測試機上,因此,不幸的是,事情并沒有分支時復制單個作業那么簡單。 確實,以自動或至少半自動的方式為新功能分支創建構建基礎結構確實很有吸引力,尤其是因為正在制定擴展構建自動化的計劃時。 對于最近的555天項目,我利用API層構建了Grails應用程序,該應用程序既可以作為跨服務器構建的輻射器,又可以用作服務器管理的中央工具。 該概念證明能夠連接到多個構建服務器并可視化作業數據以及特定的系統配置,觸發構建,并直接鏈接到每個連接的服務器以允許進一步鉆取。 這是幾個樣機,幾乎可以顯示圖片。


只是一個非常酷的應用程序,用于安裝Jenkins
這只是非常間接的關系,但是我遇到了一個非常漂亮且簡單的Griffon應用程序,稱為Jenkins-Assembler ,它簡化了構建服務器的準備工作。 它為您提供了一系列插件,讓您選擇并選擇,然后下載并將它們組合成一個可部署的戰爭。

足夠多的談話–代碼在哪里???
與本文相關的源代碼可在github上找到 。 這些測試更多地是對實時API的探索,而不是對該項目中代碼的實際測試。 它們在使用Gradle Jetty插件啟動的本地服務器上運行。 最后,這是為您準備的一些漂亮圖片。
[以幻燈片顯示]
[使用PicLens查看]










繼續第2部分 。
參考:在The Kaptain on…博客上,從我們的JCG合作伙伴 Kelly Robinson接觸到Jenkins(Hudson)API 。
翻譯自: https://www.javacodegeeks.com/2012/08/hooking-into-jenkins-hudson-api-part-1.html