針對遠端執行調整 Bazel 規則

回報問題 查看原始碼

本頁面旨在協助 Bazel 使用者撰寫自訂建構和測試規則,以掌握遠端執行作業中 Bazel 規則的相關規定。

遠端執行功能可讓 Bazel 在資料中心等獨立平台上執行動作。Bazel 使用 gRPC 通訊協定進行遠端執行作業。您可以嘗試透過 bazel-buildfarm 執行遠端執行,這個開放原始碼專案旨在提供分散式遠端執行平台。

本頁面參照不同的環境類型或平台時,採用以下術語:

  • 主機平台:Bazel 會用於執行這個平台。
  • 執行平台:Bazel 動作的執行位置。
  • 目標平台 - 執行建構作業和部分動作的執行平台。

總覽

針對遠端執行作業設定 Bazel 建構作業時,您必須遵守本頁所述的指南,確保建構作業可順利執行遠端錯誤。這是由於遠端執行作業的性質所致:

  • 隔離的建構動作。建構工具不會保留狀態,且依附元件之間無法外洩。

  • 多樣化的執行環境:本機建構設定不一定適合遠端執行環境。

本頁說明在實作遠端執行自訂 Bazel 建構和測試規則時可能發生的問題,以及如何避免這些問題。內容包括以下主題:

透過工具鍊規則叫用建構工具

Bazel 工具鍊規則是一種設定提供者,可指示建構規則使用哪些建構工具 (例如編譯器和連結器),以及使用規則建立者定義的參數來設定工具。工具鍊規則可讓建構和測試規則以可預測且預先設定且與遠端執行相容的方式叫用建構工具。例如,使用工具鍊規則,而不要透過 PATHJAVA_HOME 或其他在遠端執行環境中設為同等值 (或完全無法) 的本機變數叫用建構工具。

目前 Bazel 建構規則已有 Bazel 規則,而適用於 ScalaRustGo 的測試規則,而其他工具與工具 (例如 bash) 也正在推出全新工具鍊規則。如果規則所使用的工具不存在工具鍊規則,請考慮建立工具鍊規則

管理隱含依附元件

如果建構工具可存取所有建構動作的依附元件,則遠端執行時,這些動作將會失敗,因為每個遠端建構動作都會分開執行。某些建構工具會在建構動作和存取依附元件中保持狀態 (未明確包含在工具叫用中),這會導致遠端執行的建構動作失敗。

例如,當 Bazel 指示有狀態編譯器在本機建構 foo 時,編譯器會保留 foo 建構輸出內容的參照。當 Bazel 指示指令編譯器建立需要 foobar 時,並未明確指出在 BUILD 檔案中建立依附元件以納入編譯器叫用,只要相同編譯器執行個體執行了這兩個動作 (通常是本機執行作業),就會成功執行該動作。然而,在遠端執行情境中,每個建構動作都會執行獨立的編譯器執行個體,因此將失去編譯器狀態和 barfoo 的隱含依附元件。

為協助偵測及排除這些依附元件問題,Bazel 0.14.1 提供本機 Docker 沙箱,其對依附元件和遠端執行的限制相同。使用沙箱找出並解決與依附元件相關的建構錯誤,為遠端執行作業做好準備。詳情請參閱使用 Docker Sandbox 排解 Bazel Remote Execution 問題

管理與平台相關的二進位檔

一般來說,在主機平台上建構的二進位檔可能會因依附元件不符,而無法在任意遠端執行平台上安全地執行。舉例來說,搭配 Bazel 提供的 SingleJar 二進位檔指定主機平台。不過,如果是遠端執行,必須在建構程式碼的過程中編譯 SingleJar,使其指定遠端執行平台。(請參閱目標選取邏輯)。

除非您確定自己在執行平台中可以安全執行,否則請勿以原始碼傳送建構所需的二進位檔工具。建議改用下列方法:

  • 為工具提供原始碼或外部參照,以便針對遠端執行平台建構。

  • 如果工具的穩定性夠高,請將工具預先安裝在遠端執行環境中 (例如工具鍊容器),並在建構作業中使用工具鍊規則執行這項工具。

管理設定樣式的 WORKSPACE 規則

Bazel 的 WORKSPACE 規則可用於針對主機所需的工具和程式庫進行探測作業,而本機版本也是 Bazel 的執行平台。如果建構作業明確依賴本機建構工具和構件,如果遠端執行平台與主機平台不同,在遠端執行期間就會失敗。

WORKSPACE 規則執行的以下動作與遠端執行作業不相容:

  • 建構二進位檔。WORKSPACE 規則中執行編譯動作會產生與遠端執行平台不相容的二進位檔 (如果與主機平台不同)。

  • 安裝 pip 套件。透過 WORKSPACE 規則安裝的 pip 套件需要在依附元件平台上預先安裝其依附元件。這類專為主機平台設計的套件如果與主機平台不同,就會與遠端執行平台不相容。

  • 連結本機工具或構件。在透過 WORKSPACE 規則建立的主機平台上安裝工具或程式庫的符號連結會導致建構在遠端執行平台失敗,因為 Bazel 無法找到這類工具。請改為使用標準建構動作建立符號連結,以便從 Bazel 的 runfiles 樹狀圖存取符號化的工具和程式庫。請勿使用 repository_ctx.symlink 對目標存放區以外的外部檔案建立符號連結。

  • 靜音主機平台。避免在 Bazel runfiles 樹狀結構之外建立檔案、建立環境變數及執行類似操作,因為這些檔案可能會在遠端執行平台上出現非預期的行為。

您可以利用 Workspace 規則記錄找出潛在的非密封行為。

如果外部依附元件會根據主機平台執行特定作業,您應該在 WORKSPACE 和建構規則之間拆分這些作業,如下所示:

  • 平台檢查和依附元件列舉。透過 WORKSPACE 規則即可在本機執行這些作業,該規則可檢查已安裝的程式庫、下載必須建構的套件,以及準備編譯所需的構件。對遠端執行來說,這些規則還必須支援使用預先勾選的構件,以提供一般在主機平台檢查期間取得的資訊。預先檢查的成果可讓 Bazel 描述依附元件,就如同本機一般。為此,請使用條件陳述式或 --override_repository 旗標。

  • 產生或編譯特定目標的構件和平台異動。這些作業必須透過一般建構規則執行。產生外部依附元件目標專屬成果的動作必須在建構期間執行。

如要更輕鬆地產生遠端檢查的預先檢查成果,您可以使用 WORKSPACE 規則發出產生的檔案。您可以針對各個新的執行環境 (例如每個工具鍊容器內部) 執行這些規則,並檢查來源存放區中遠端存放區的輸出內容以參照。

舉例來說,在 Tensorflow 的 cudapython 規則中,WORKSPACE 規則會產生下列 BUILD files。進行本機執行時,系統會使用檢查主機環境產生的檔案。對遠端執行來說,環境變數上的條件陳述式可讓規則使用檢查存放區中的檔案。

BUILD 檔案會宣告 genrules,其可在本機和遠端執行,並執行先前透過 repository_ctx.symlink 完成的必要處理,如這裡所示。