針對遠端執行調整 Bazel 規則

回報問題 查看來源

本頁面可協助 Bazel 使用者編寫自訂建構作業和測試規則,並瞭解在遠端執行作業中對 Bazel 規則的需求。

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

本頁面使用下列術語在提到不同的環境類型或「平台」時:

  • 主機平台 - Bazel 的執行位置。
  • 執行平台:執行 Bazel 動作的位置。
  • 目標平台:建構輸出內容 (和一些動作) 執行的位置。

總覽

為遠端執行設定 Bazel 建構作業時,您必須遵循本頁所述規範,確保建構作業可在遠端執行且未發生錯誤。這是因為遠端執行作業的特性,即:

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

  • 多種執行環境本機建構設定不一定適用於遠端執行環境。

本頁面說明為遠端執行實作自訂 Bazel 建構作業和測試規則時可能發生的問題,以及如何避免這些問題。涵蓋下列主題:

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

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

ScalaRustGo 的 Bazel 建構作業和測試規則目前已有工具鍊規則,而其他語言和工具 (例如 bash) 也採用新的工具鍊規則。如果規則使用的工具不存在工具鍊規則,請考慮建立工具鍊規則

管理隱含依附元件

如果建構工具可以存取不同建構動作的依附元件,這些動作在遠端執行時會失敗,因為每個遠端建構動作會彼此分開執行。某些建構工具會保留狀態,用於建構動作和存取依附元件,而該工具未在工具叫用中明確納入這些項目,這會導致遠端執行的建構動作失敗。

舉例來說,當 Bazel 指示有狀態編譯器在本機建構 foo 時,編譯器會保留對 foo 建構輸出內容的參照。當 Bazel 指示編譯器建構依附 foobar,而未明確說明 BUILD 檔案中要納入編譯器叫用的依附元件,只要同一個編譯器執行個體會同時執行這兩個動作 (如同本機執行的一般執行方式),該動作就會成功執行。但是,由於在遠端執行情境中,每個建構動作都會執行單獨的編譯器執行個體,因此 foo 上的編譯器狀態和 bar 的隱含依附元件將會遺失,且建構作業將會失敗。

為協助偵測及消除這些依附元件問題,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 完成的必要處理作業,如這裡所示。