1. 程式人生 > 其它 >Jenkins 進階篇 - 任務關聯

Jenkins 進階篇 - 任務關聯

有時候我們的一個任務裡面會進行很多的步驟,例如構建一個後端的 Java 服務,可能會有程式碼靜態掃描,靜態掃描通過後會打包成 jar 或者 war 檔案,打包成功後可能還會對製品進行存檔備份,然後可能會製作容器映象……,這些所有的內容完全可以在一個任務中完成,也可以拆分成多個任務分步驟進行。但是將複雜任務拆分成多個任務後,會有一些附帶的其他問題,可能沒法很好地利用 Jenkins 的多節點優勢,當你的第二個任務要使用第一個任務的工作空間的檔案時,你必須要確保這兩個任務要在同一個 Jenkins 節點上執行,因為如果兩個任務不在同一個節點上執行,但是第二個任務又需要使用第一個任務的工作空間的檔案時就會出問題,第二個任務找不到第一個任務的工作空間。

所以若非必要就不要對任務進行拆分,如果要拆分那就要確保關聯的任務都在同一個節點執行,或者任務之間沒有對工作空間的依賴。對於如何確保關聯任務在同一個節點執行,可以使用 Node and Label parameter 外掛來實現。接下來就演示關聯任務的構建與引數傳遞。

我們建立兩個自由風格的任務,任務 a 和 b 。在做關聯任務配置之前我們先安裝兩個 Jenkins 外掛:Parameterized TriggerNode and Label parameterParameterized Trigger 是用於關聯任務之間的觸發和引數傳遞, Node and Label parameter

是用於解決關聯任務繫結到同一個節點執行。外掛安裝完成後重啟下 Jenkins 服務,用擁有管理許可權的 Jenkins 賬號訪問 http://<jenkins-host>/restart 即可,等待重啟完成後開始對兩個關聯任務進行配置。

建立兩個自由風格的任務:
a 任務的配置如下,其中【構建】部分的 shell 命令後面兩行先註釋遮蔽不執行。同時在【構建】裡面增加一個步驟【Trigger/call builds on other projects】用來觸發其他任務的構建,填入子任務的名稱和要傳遞給子任務的引數,如果子任務有多個則用英文逗號分隔。

# a任務構建部分增加執行shell命令,內容如下
echo "檢查引數:"
echo "release_tag=${release_tag}, target_platform=${target_platform}, run_test=${run_test}"
# echo "Hello Jenkins" >> a.txt
# cat a.txt


b 任務也簡單,就接收列印 a 任務傳過來的引數值,以及看看 a 任務生成的檔案 a.txt 裡面的內容,執行的 shell 命令如下,暫時先將最後一行註釋掉遮蔽執行。

echo "接收到的引數:"
echo "release_tag=${release_tag}, target_platform=${target_platform}, run_test=${run_test}, parent_workspace=${parent_workspace}"
# cat ${parent_workspace}/a.txt


這樣任務 a、b 都配置好了,構建任務 a 成功後會觸發任務 b 的執行,當然任務 b 也可以自己單獨構建執行,引數內容也是由任務 b 自己掌控填寫。

單獨構建任務 b,構建時的引數輸入和輸出的引數資訊如下:

現在構建 a 任務,各個引數值如下:

看看構建日誌,我們會發現 a 任務是在主節點 master 上執行的,並且構建完成後觸發構建了 b 任務:

b 任務的執行日誌如下,從日誌可以發現 b 任務是由上游任務 a 觸發構建,並且是在另一個 Jenkins 節點上執行的,接收到的引數也是從 a 任務傳遞過來的。

現在我們將 a 、b 任務裡面執行 shell 命令後面的檔案操作取消註釋,讓其執行檔案操作相關命令:

# a 任務的 shell 命令內容
echo "檢查引數:"
echo "release_tag=${release_tag}, target_platform=${target_platform}, run_test=${run_test}"
echo "Hello Jenkins" >> a.txt
cat a.txt


# b 任務的 shell 命令內容
echo "接收到的引數:"
echo "release_tag=${release_tag}, target_platform=${target_platform}, run_test=${run_test}, parent_workspace=${parent_workspace}"
# cat ${parent_workspace}/a.txt

同樣的,a 任務執行完後觸發了 b 任務,但是 b 任務執行失敗了,因為 Jenkins 會根據各個節點的壓力負載情況,將任務 a、b 分別在不同的 Jenkins 節點上執行,當 b 任務檢視 a 任務工作空間的檔案時找不到檔案,那麼 b 任務就執行失敗了。

要解決這個問題就要保證各個關聯任務不依賴於各個任務的工作空間的檔案,如果關聯任務又確實需要依賴工作空間的檔案,那就要將任務繫結在同一個節點執行,這就需要用 Node and Label parameter 外掛來實現,該外掛可以通過一個引數來定義任務要在哪個節點上執行。例如,如果我們的 a 任務在 master 節點上運行了,那麼 b 任務就也要在 master 節點上執行,才能正常訪問 a 任務工作空間的檔案。

我們將 a 任務配置裡面【構建】步驟中【Trigger/call builds on other projects】的引數傳遞配置做下調整,將 a 任務的構建節點名稱傳給 b 任務,讓 b 任務也在同一個節點上執行。

release_tag=${release_tag}
target_platform=${target_platform}
run_test=${run_test}
parent_workspace=${WORKSPACE}
patent_node_name=${NODE_NAME}

然後在 b 任務增加一個 Label 或者 Node 引數,控制任務在哪個節點執行,Label 引數是根據節點標籤來匹配節點,而 Node 引數則是根據節點的名稱來匹配節點,我這裡添加了一個 Label 引數,設定如下:

做好節點繫結引數的設定後我們多次構建 a 任務,看看 a 、b 任務最後的執行日誌。




從構建的執行日誌上,我們可以看到任務 a、b 是已經繫結在同一個 Jenkins 節點上運行了。另外這一小節使用了一些 Jenkins 內建的環境變數,WORKSPACE 和 NODE_LABELS,還有一些其他的內建環境變數可以瀏覽器訪問 http://<jenkins-host>/env-vars.html 進行檢視,這些環境變數可以在任務配置時直接獲取使用。