經過 API 遠程管理 Jenkins

背景介紹

最近接到一個需求,須要對公司內部的Android性能測試平臺的分支管理模塊進行改造。python

爲了更好地說明問題,在下圖中展現了一個精簡的持續集成測試系統。android

在該系統中,Jenkins負責定時檢測代碼庫(Code Repository)的代碼更新狀況,當檢測到有新的代碼提交時,自動採用最新的代碼進行構建,並採用構建獲得的包(apk)觸發自動化測試平臺(DroidTestbed)執行測試任務。git

而後再說下分支管理模塊。github

因爲咱們的持續集成平臺一般不止監控一個產品,而每一個產品又不止監控一個tag(例如/trunk,/projects/cn/10.9.8),所以,咱們的持續集成平臺須要有分支管理的功能,即針對每個產品的每個tag,單首創建一個分支,並針對各個分支單獨指定測試用例集合測試設備。shell

具體實現方面,出於單一職責的原則,咱們對功能進行了以下劃分:編程

  • 在Jenkins端針對每個分支建立一個Job;
  • DroidTestbed端配置測試資源,針對每個分支分別綁定測試用例集和測試設備,每個分支會存在一個單獨的branch_id;
  • 在Jenkins端的Job配置中,保存該分支在DroidTestbed中對應的branch_id,實現JenkinsDroidTestbed的關聯。

整個過程看上去並無什麼問題,那爲何須要對分支管理模塊進行改造呢?api

問題就出如今分支配置上面。微信

試想一下,每次要新增或修改一個分支的時候,因爲Jenkins端和DroidTestbed端的配置是獨立的,那麼咱們就只能在兩個平臺上分別進行配置。架構

另外一方面,配置工做自己也較爲複雜,例如,在Jenkins端就須要設置的參數包括:repository_url,tag,ref_tag,ref_revision,branch_id,schedule,user_name等;而這其中的大部分參數一樣也要在DroidTestbed端進行配置。app

根據歷史經驗,但凡涉及到複雜且重複的手工操做時,就容易出錯。實際狀況的確是這樣的。在該功能上線後,因爲配置複雜,業務組的同窗每次要新增一個監控分支時,都須要找到管理員來幫忙配置(說實話,管理員對業務同窗能配置正確也沒信心);即便是管理員,也出現過好幾回由於疏忽形成配置錯誤的狀況。

那麼,這個問題要怎麼解決呢?

Jenkins Remote API 的簡介

繞了這麼大一個圈子,終於引出本文的主題,Jenkins Remote API。

實際上,Jenkins自己支持豐富的API接口,咱們經過遠程調用接口,基本上能夠實現全部須要的功能,例如:

  • 從Jenkins獲取Job狀態信息
  • 觸發Jenkins執行構建
  • 建立、複製、修改、刪除Job

回到前面的案例,咱們就能夠將配置操做所有放在DroidTestbed中,只須要在保存配置項時,由DroidTestbed自動調用Jenkins的Remote API,便可實現配置的同步。

Jenkins Remote API 的調用

如今咱們來看下如何調用Jenkins的Remote API。

Jenkins的Remote API以REST-like的形式進行提供,經過對特定的API執行POST請求便可實現對Jenkins的操做。

例如,咱們搭建的Jenkins站點爲http://jenkins.debugtalk.com:8080,那麼,訪問http://jenkins.debugtalk.com:8080/api便可查看到該站點全部可用的API;若想若某個具體的Job進行操做,如job名稱android_core_dashboard_trunk,它的管理頁面爲http://jenkins.debugtalk.com:8080/job/android_core_dashboard_trunk,那麼咱們訪問http://jenkins.debugtalk.com:8080/job/android_core_dashboard_trunk/api/便可查看到該job可用的API。

更詳細的POST調用方式的介紹能夠參考Jenkins的官方wiki,在此就不過多進行介紹。

能夠看出,經過對特定API執行POST請求操做較爲原始,由於咱們須要關注過多底層細節。事實上,當前已經有前輩針對這一痛點,對底層的POST操做細節進行了封裝,造成了一些wrapper方便咱們從上層進行更便捷的操做。

這類wrapper實現的功能相似,均可以方便咱們在代碼中經過更簡潔的方式調用Jenkins API,實現對Jenkins的遠程管理,咱們只須要根據咱們採用的具體編程語言來選擇對應的wrapper便可。固然,若是沒有找到合適的,咱們也能夠參照已有的開源wrapper,本身再造一個輪子,原理都是相同的。

在Jenkins的官方wiki中,推薦了兩個較爲成熟的API wrapper,一個是基於Python實現的salimfadhley/jenkinsapi,另外一個是基於Ruby實現的arangamani/jenkins_api_client

salimfadhley/jenkinsapi爲例,經過使用jenkinsapi,咱們在Python中就能夠很方便地管理Jenkins。常見的操做方式示例以下。

>>> import jenkinsapi
>>> from jenkinsapi.jenkins import Jenkins

# 指定Jenkins實例
>>> J = Jenkins('http://jenkins.debugtalk.com:8080')

# 查看Jenkins版本
>>> J.version
1.542

# 查看Jenkins的全部jobs
>>> J.keys()
['foo', 'test_jenkinsapi']

# 查看指定job的配置信息
>>> J['test_jenkinsapi'].get_config()

# 建立Jenkins job
>>> jobName = 'test_job'
>>> EMPTY_JOB_CONFIG = ''' <?xml version='1.0' encoding='UTF-8'?> <project> <actions>jkkjjk</actions> <description></description> <keepDependencies>false</keepDependencies> <properties/> <scm class="hudson.scm.NullSCM"/> <canRoam>true</canRoam> <disabled>false</disabled> <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding> <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding> <triggers class="vector"/> <concurrentBuild>false</concurrentBuild> <builders/> <publishers/> <buildWrappers/> </project> '''
>>> new_job = J.create_job(jobName, EMPTY_JOB_CONFIG)

# 更新Jenkins job的配置
>>> import xml.etree.ElementTree as et
>>> new_conf = new_job.get_config()
>>> root = et.fromstring(new_conf.strip())
>>> builders = root.find('builders')
>>> shell = et.SubElement(builders, 'hudson.tasks.Shell')
>>> command = et.SubElement(shell, 'command')
>>> command.text = "ls"
>>> J[jobName].update_config(et.tostring(root))

# 刪除Jenkins job
>>> J.delete_job(jobName)複製代碼

更多的使用方法可參考項目文檔。

有些同窗在認真研究了這些開源庫後也許會說,官方文檔已經翻遍了,可是文檔中對用法的描述太少了,也沒給出API調用的示例,仍是不知道怎麼使用啊。這個問題在開源庫中的確也是廣泛存在的。

介紹個技巧,一般優秀的開源庫都會很重視測試,做者可能在文檔中沒有針對每個API接口的調用方式進行說明,但一般會針對各個接口編寫較爲完整的測試代碼。咱們經過閱讀測試代碼,就能夠充分了解API接口的使用方法了,這也比直接閱讀文檔有效率得多。

Read More ...

最後,若是感受上面給的示例還不夠,還想看看在實際項目中如何遠程管理Jenkins,那麼能夠關注我最近在作的一個開源項目。

先看下總體的系統架構圖。

整個系統實現的功能是Android App的性能持續集成測試平臺,主要由DroidTestbedDroidMeter兩部分組成。

其中,DroidTestbed部分採用Ruby on Rails編寫,核心角色爲測試任務管理,可實現測試資源(測試用例、測試設備等)配置,根據代碼提交自動觸發執行測試任務、測試設備自動化調度、測試任務手動下發,測試結果報表查看等。DroidMeter負責具體的性能測試執行,採用Python編寫,可實現控制Android設備執行測試場景,採集性能測試數據,包括內存、啓動時間、幀率、包大小、網速、流量等等。

本文暫時不對該系統進行過多介紹,我後續會單獨對各個模塊涉及到的技術展開進行詳細介紹。若是感興趣,可關注個人GitHub或微信公衆號【DebugTalk】,固然,我也會同步轉發至TesterHome。


Read More ...

公衆號:DebugTalk

原文連接:debugtalk.com/post/manage…

相關文章
相關標籤/搜索