歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Jenkins Plugin 基礎開發入門

Jenkins Plugin 基礎開發入門

日期:2017/2/28 13:46:02   编辑:Linux教程

引子:Jenkins 是目前階段各大公司運用持續集成的主要輪子,而 Jenkins 能否發揮如此神威的主要原因即在於其眾多的 Plugins 可以快速實現定制化需求。筆者因工作需要,體驗了一把從零入門 Jenkins Plugin 開發。現把經驗總結形成本文。

0x00 弄清 Jenkins 的主要概念

先來看看 Jenkins 自己搭建的 CI 環境:Jenkins on Jenkins ,再結合下面這張官網給出的解釋持續交付工作流程的示意圖,簡單學習 & 增加感性認識。

IBM 給出資料指出 Jenkins 在實現上有三個重要概念:

Stapler

  • Stapler 可以自動為應用程序對象綁定 URL,並創建直觀的 URL 層次結構。而Jenkins 的類對象和 URL 綁定就是通過 Stapler 來實現的,通過該技術我們可以快速訪問對應的Job及其相應資源。

持久化

  • Jenkins 使用文件來存儲數據(所有數據都存儲在$JENKINS_HOME)。

插件

  • Jenkins 的對象模型是可擴展的,通過 Jenkins 提供的可擴展點,我們可以開發插件擴展 Jenkins 的功能。
  • 所有的 Plugin 都是在 Jenkins Master 上運行的。

0x01 選擇 Jenkins 的擴展功能接口

Jenkins 擁有極多的插件,而這些插件的開發都是基於 Jenkins 的擴展功能接口(Jenkins Extension Points)實現的。為了盡可能的實現定制化,Jenkins 的提供的擴展功能接口極多,詳情可見 Jenkins Extension Points。

但這並不意味著我們需要一一掌握所有的擴展功能接口,Jenkins 官方提供的 資料 指出:

通常,一次構建過程包括如下幾個步驟:
1.SCM checkout:檢出源碼,用於指定構建的目標。
2.Pre-build steps:預編譯。
3.Build wrapper set up:構建環境准備。
4.Builder runs:執行構建的核心過程,例如調用Ant,Make等。
5.Recorder runs:記錄構建過程中的輸出,例如測試結果等。
6.Notifier runs:根據結果發送通知。

而這其中,除了 Pre-build 僅僅是 huson.tasks 的一個 Interface以外。其余五個擴展功能接口就是我們需要關注的重點:

  1. hudson.scm.SCM
  2. hudson.tasks.BuildWrapper
  3. hudson.tasks.Builder
  4. hudson.tasks.Recorder
  5. hudson.tasks.Notifier

當然,如果想實現其他更復雜的功能,可以直接參考 官方文檔 以及 官方提供的插件源碼列表。

0x02 搭建 Jenkins 開發環境

創建插件工程目錄

按照 Jenkins 插件開發的要求配置完 maven 的 settings.xml 配置文件之後,執行以下命令:

mvn -U org.jenkins-ci.tools:maven-hpi-plugin:create -DgroupId={your.gound.id} -DartifactId={your.plugin.id}

其中,your.groud.id 和 your.plugin.id 填你插件的具體對應的值。命令執行之後,該目錄下會產生一個名稱是 {your.plugin.id} 的 HelloWorld 插件工程目錄。

調試插件

由於我們的 Plugin 的相關配置已由 Maven 工程的 pom.xml 定義好了,所以我們的僅需執行如下命令即可進行調試:

mvn hpi:run

這句簡單的命令就已經包含了諸如啟動 Jetty 服務器,將 Jenkins 作為一個 Web 服務增加至上訴服務器以及在 Jenkins 中安裝我們剛寫生成的 HelloWorld 插件等一系列任務。

一旦上述過程成功執行,我們就可以可以在浏覽器中通過下面的 URL 訪問我們剛剛搭建好的 Jenkins 的主頁:

http://localhost:8080

這時我們就可以檢查我們編寫的插件是否滿足我們的設計需要了。

發布及安裝插件

Jenkins 的插件通過 hpi 文件格式發布,所以在發布前,需要通過如下命令進行打包:

mvn package

命令執行完成之後,即可在target目錄下的生成插件的 hpi 文件和 jar 文件。

然後,我們無論是選擇將 hpi 文件拷貝到 Jenkins Home 路徑下的 plugin 目錄中,或者選擇通過 Jenkins 插件管理上傳安裝該 hpi 文件,均可完成插件的安裝。

0x03 梳理 Jenkins Plugin 工程結構

雖然 Jenkins 也支持Groovy 進行UI 開發,Jenkins 主要是用 Jelly 來進行 UI 管理。而 Jelly UI 技術的主要原理是通過服務端的渲染引擎將 Jelly 定義好的 XML 文件渲染成客戶端需要的 HTML,Javascript 和 Ajax 等。

初步入門 Jenkins Plugin 的人(例如筆者自己)往往最困惑的一點就是如何理清 Jenkins Plugin 的工程結構以及 Plugin 的Jelly到底該怎麼寫。

通過上面的 mvn 指令我們生存的工程目錄具有如下的布局結構:

  • pom.xml - Maven POM 文件,用於配置插件的設定
  • src/main/java - 插件的 Java 源文件
  • src/main/resources - 插件的 Jelly 視圖文件
  • src/main/webapp - 插件的靜態資源,如圖片或 HTLM 等

0x04 Jelly UI 入門

弄清楚了工程結構,剩下的事情就是到底怎麼用 jelly 來寫插件的 UI 了。而這無非也就是需要弄明白三件事情:

  1. 如何為指定對象創建一個 Jelly UI 頁面;
  2. 如何讀取 Jelly 中的用戶輸入;
  3. 如何操控 Jelly 反饋信息。

如何為指定對象創建一個 Jelly UI 頁面

前面說到,工程的目錄結構中:

  • src/main/java - 插件的 Java 源文件
  • src/main/resources - 插件的 Jelly 視圖文件

而 Jenkins 如何將兩者之前建立起對應關系的呢?簡單來說根據路徑結構的一致性來建立關系。

假設你建立了一個java類,路徑為

src/main/java/org/sample/HelloWorldBuilder.java

則增加Jelly文件需要在resources文件夾中建立與類同名的目錄:

src/main/resources/org/sample/HelloWorldBuilder/

需要說明的是,Jenkins 通過固定的命名方式來確定頁面文件屬於局部配置還是全局配置:config.jelly 為局部配置;global.jelly 為全局配置。

這裡它們的區別在有點類似於局部變量與全局變量的區別。gloabal.jelly 更多的用於讀取存儲與某個具體構建無關的配置信息。而具體的構建本身的相關參數基本都由 config.jelly 進行處理。

如果我們需要創建的是一個局部的配置(大多數情況),那麼我們就在上述路徑下增加文件config.jelly,路徑如下:

src/main/resources/org/sample/HelloWorldBuilder/config.jelly

如何讀取 Jelly 中的用戶輸入

那麼我們有如何訪問 Jelly 中的信息呢?最為基礎的方法就是通過 Descriptor 進行頁面和數據的綁定了。

假設我們在 jelly 按如下方式進行定義:

<f:entry title="Name" field="name">

那麼與之對應的,我們就可以在對應的類裡進行如下配置了:

@DataBoundConstructor
public HelloWorldBuilder(String name) {
   this.name = name;
}

那麼當 UI 中的數據提交之時, Jenkins 會根據傳過來的具體數據調用構造函數來創建對象。

在類中增加getter方法,或者將變量設置為public final。這樣可以還讓Jelly腳本將數值顯示到配置信息頁面。

public String getName() {
   return name;
}

在內部實現的DescriptorImpl類中,我們也可以選擇增加doCheckFIELD()函數,來進行配置檢查。在參數上可以增加@QueryParameter注解來傳入附近位置的數據。

public FormValidation doCheckName(@QueryParameter String value) 
    throws IOException, ServletException {
  if (value.length() == 0) {
    return FormValidation.error("Please set a name");
  }
  if (value.length() &lt; 4) {
    return FormValidation.warning("Isn't the name too short?");
  }
  return FormValidation.ok();
}

當然,我們也可以使用各種 Jelly 控件,如textbox,checkbox 以及 validateButton等等。具體的使用方法,可以參考以下文檔,這裡就不一一展開了。

參考文檔:jenkinsci/ui-samples-plugin

如何操控 Jelly 反饋信息

首先,我們先來看看 Jelly 如何訪問項目中的其它資源。默認情況下, Jenkins 已經定義了以下對象:

  • app - Jenkins
  • it - Jelly UI 綁定的類
  • instance - Jelly UI 所對應的正在被配置的對象
  • descriptor -與 instance 所對應的 Descriptor
  • h - husdon.Functions 的實例

所以我們如果在類中配置了:

public String getMyString() {
    return "Hello Jenkins!";
}

而按如下方法編寫其對應的 jelly 文件:

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
    ${it.myString}
</j:jelly>

那麼,頁面上就能調用出類的方法,顯示出”Hello Jenkins!”了。

局域網內利用GitLab+Jenkins自動生成GitBook並發布(Nginx) http://www.linuxidc.com/Linux/2016-05/131136.htm

Linux+Git+Maven+Jenkins+Neuxs自動化編譯環境搭建 http://www.linuxidc.com/Linux/2016-02/128652.htm

在CentOS 7上安裝Jenkins http://www.linuxidc.com/Linux/2016-11/137548.htm

CentOS6安裝Jenkins http://www.linuxidc.com/Linux/2016-05/131365.htm

使用Jenkins配置Git+Maven的自動化構建 http://www.linuxidc.com/Linux/2016-02/128641.htm

Jenkins+Maven+Git搭建持續集成和自動化部署的配置手記 http://www.linuxidc.com/Linux/2015-06/118606.htm

Jenkins的分布式構建及部署——節點 http://www.linuxidc.com/Linux/2015-05/116903.htm

Jenkins 的詳細介紹:請點這裡
Jenkins 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved