1. 程式人生 > >【Jenkins】使用 Jenkins REST API 配合清華大學映象站更新 Jenkins 外掛

【Jenkins】使用 Jenkins REST API 配合清華大學映象站更新 Jenkins 外掛

自從去年用上了 Jenkins 進行 CI/CD 之後,工作效率高了不少,摸魚的時間更多了。不過 Jenkins 好是好,但在功夫網的影響下,外掛就是經常更新不成功的,就像下面這樣子:

查了不少資料,絕大部分都說把升級站點改了就行

然而並沒有什麼卵用,只是獲取外掛列表從這個地方獲取而已,安裝/更新外掛的時候該炸還是得炸。


作為一個有程式碼潔癖的人,看著有外掛更新不了那感覺就像有屎拉不出的難受。於是乎這幾個月以來一直是通過上面圖中的手動上傳外掛來進行更新的。可是效率實在是低,一兩個外掛還好,有時候一堆外掛有更新,那一個個上傳是真的煩。

最近幾天又相對閒了點,察覺到 Jenkins 是有個 REST API 的,那麼能不能通過程式化來解決問題呢。嘗試了下,算是有個比較滿意的解決方案了。

首先,要用 Jenkins REST API 是需要許可權的,並不是說隨便來個人都可以呼叫。Jenkins REST API 是通過 token 進行驗證的。預設是沒有 token 的,需要手動新增。

登入 Jenkins 管理面板,進入管理使用者

然後選擇一個使用者,點選左側設定,然後新增 token 並且用你的小本本記錄下來

這樣就為這個使用者添加了一個 REST API 的 token 了,後續呼叫 REST API 帶上這個 token 就是了


以 C# 的 HttpClient 為例:

var httpClient = new HttpClient();
httpClient.SetBasicAuthentication("username", "apiToken");

這樣寫就行了,SetBasicAuthentication 方法來自 IdentityModel 這個 nuget 包。(https://www.nuget.org/packages/IdentityModel/)


接下來我們要先獲取哪些外掛是有更新的。

在瀏覽器中來到 /pluginManager/api/ 這個頁面,點開 JSON API。

理論上會得到這麼個 JSON:

一堆空白?再看一下文件,加上 depth 引數就好了。加上 depth=1,再次請求 /pluginManager/api/json?pretty=true&depth=1

當前安裝的所有外掛的資訊都返回了。而且這裡還返回了 hasUpdate 代表這個外掛是否有更新。

用 C# 稍微建個模好了

public class JenkinsPlugin
{
    [JsonProperty("hasUpdate")]
    public bool HasUpdate { get; set; }

    [JsonProperty("shortName")]
    public string ShortName { get; set; }

    [JsonProperty("url")]
    public string Url { get; set; }

    [JsonProperty("version")]
    public string Version { get; set; }
}


接下來假如某個外掛有更新的話,那麼就下載這個外掛的新版本好了,開啟清華大學 Jenkins 的映象頁,並轉到外掛目錄 https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/

以 git 外掛為例,最新版本的下載地址如下:

https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/git/latest/git.hpi

也就是說某個外掛的最新版本在清華大學映象站的下載地址是

https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/{plugin.shortName}/git/lastest/{plugin.shortName}.hpi

用 C# 擼個下載程式碼好了:

public class TsinghuaClient
{
    private static readonly HttpClient Client = new HttpClient();

    public async Task<byte[]> DownloadPluginAsync(string pluginName)
    {
        var url = $"https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/{pluginName}/latest/{pluginName}.hpi";
        var bytes = await Client.GetByteArrayAsync(url);
        return bytes;
    }
}

接下來就是把這個傳到 Jenkins 上。


以 C# 程式碼為例就是

using (var content = new MultipartFormDataContent())
{
    content.Add(new ByteArrayContent(plugin), "name", fileName);// plugin 為 byte[]
    var response = await client.PostAsync("/pluginManager/uploadPlugin", content);
    response.EnsureSuccessStatusCode();
}

上傳成功的話,狀態碼是 200 OK。


最後就是要讓 Jenkins 安裝新版本的外掛了,這個只需要重啟一下 Jenkins 即可。在瀏覽器中開啟 /api 路徑,並滾動到最底部

左邊那個是強制重啟,右邊那個是等待到沒任務時再重啟。我們用右邊那個。

程式碼擼一下:

public async Task RestartAsync()
{
    var response = await client.PostAsync("/safeRestart", null);
    Debug.Assert(response.StatusCode == HttpStatusCode.ServiceUnavailable);
}

重啟指令傳送成功後會返回 503 Service Unavailable 的。


總結一下流程就是:

獲取已安裝外掛列表 –> 篩選有更新的外掛 –> 到清華大學映象站下載外掛最新版本 –> 上傳到 Jenkins –> 重啟 Jenkins


順手擼了個 WPF 的 app,也把原始碼傳上來好了

https://files.cnblogs.com/files/h82258652/JenkinsUpdator.zip

使用的時候注意配置 app.config