RFC-0124:去中心化產品整合:構件說明和傳播 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 用於描述及散發非集中式產品整合作業的構件機制。 |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2021-03-30 |
審查日期 (年-月-日) | 2021-08-30 |
摘要
本 RFC 說明一種機制,可從 Fuchsia 來源樹或花瓣存放區中建立來源或預先建構的構件,用於組合 Fuchsia
這個機制包含兩個重要層面:
- 使用適當的元資料,為構件提供說明,以便選取相容或其他理想的版本和變化版本,並納入要組合的產品。
- 傳播構件,以便在來源存放區 (構件來源) 和用於構件的整合存放區,同時識別、參照及存取構件。
提振精神
如去中心化產品整合路線圖文件所述,建議在 Fuchsia 來源樹狀結構之外組合產品。為達成此目標,您必須在 Fuchsia 來源樹狀結構之外執行獨立映像檔組合工具,並為這些工具提供必要的來源或預先建構的構件。Fuchsia 來源樹狀結構會提供 Zircon (Fuchsia 核心) 和系統套件等其他構件。各種花瓣存放區會提供額外元件的套件,例如產品專屬元件和執行程式。
Fuchsia 來源樹構件會按照定期版本產生。 同時,Fchsia SDK 的版本也會產生,這些版本會定期由寵物存放區匯入,進而在石材存放區的版本推出時產生自己的 Fuchsia 構件。
一般來說,花瓣存放區的發布週期與 Fuchsia 來源樹狀結構的發布週期不一致,且版本的 ID 也不同。花瓣可以選擇將發布週期與 Fuchsia 保持一致,例如為每個 Fuchsia SDK 版本製作一個版本。
每個這類成果版本也可能會以不同的變化版本產生,例如各種處理器架構的可執行檔、偵錯與最佳化變化版本、以「穩定」與「最新」標籤指定的變化版本 (用於區分主幹版本與穩定分支版本),或是啟用或停用的建構時間功能的變化版本。
如要在與 Fuchsia 來源樹狀結構分開的整合存放區中,從這類構件組合產品,則必須將構件提供給整合存放區。此外,產品整合所需的構件必須針對每個產品版本和子類選取適當的構件版本和變化版本。
產品整合目前的流程稱為「全域整合」。來自花瓣存放區的預先建構構件會在名為滾動式更新的程序中匯入至 Fuchsia 來源樹狀結構。接著,系統會將 Fuchsia 產品組合為最終建構產品,這些產品來自最新來源修訂版本的 Fuchsia 來源樹狀結構中的所有構件,以及已達到整合存放區的固定版本中 petal 存放區中的預先建構套件。這項程序如圖 1 所示。
圖 1 - 全球整合程序 (圖例)
這個程序有幾個缺點:
- 產品組合設定會保留在 Fuchsia 來源樹狀結構中,而非由
- Fuchsia 系統的版本一律會領先任何花瓣構件所建構的 Fuchsia SDK 版本,因為 Fuchsia 系統是根據 Fuchsia 來源樹狀結構的最新來源修訂版本建構,但花瓣構件的 SDK 是根據較早的修訂版本建構。
- 如果不同花瓣的構件之間有版本相容性要求 (例如 Flutter 執行程式和以 AOT 編譯的 Flutter 應用程式),則必須在同一個 Roller 中特別將這些構件一起推出,才能維護這些構件。
- 即使花瓣構件由產品擁有者控管,用於產品整合的版本仍不受控管,因為讓新版本構件可供產品整合的滾動式程序會與所有其他花瓣構件的其他滾動器協調,且可能因任何其他產品的整合測試失敗而遭到封鎖。
建議的去中心化產品整合程序可改善這些缺點,因為這可在 Fuchsia 存放區外啟用產品組裝功能:
- 產品組合設定會儲存在每項產品的個別整合存放區,可由產品擁有者控制。
- 您可以選取與用於建構花瓣構件所用的 Fuchsia SDK 相容的 Fuchsia 構件,以便在產品的所有構件之間達成 ABI 相容性。舉例來說,類似於 RFC-0002 中規定的 ABI 修訂版本,以及對應於必要的 6 週 ABI 相容性時段,會由 Fuchsia 發布版本號碼的第一個元件表示,每次建立 Fuchsia 發布分支時,這個元件都會遞增。因此,針對用於建構的 SDK 的 Fuchsia 發布版本號碼,產品中的所有構件可以保持一致的第一元件。
- 您可以直接選取來自不同寵物存放區的構件版本,使其符合共同相容性需求,並可根據直接指定的限制推進下一個版本,而無需為一對構件設定專屬滾動器。舉例來說,您可以直接在相同的 Flutter 和 Dart 發布版本號碼上選取 Flutter 應用程式和對應的 Flutter 執行工具。
- 產品可依據自身的發布週期,選取所有貢獻構件版本和變化版本,而不會阻止其他產品也選取該版本。
相關人員
協助人員:abarth@google.com
審查者:aaronwood@google.com (組裝)、etryzelaar@google.com (SWD)、wittrock@google.com (SWD)、atyfto@google.com (Fuchsia 建構基礎架構)、marvinpaul@google.com (TUF 伺服器基礎架構)、jsankey@google.com (安全性)、enoharemaien@google.com (安全性與隱私權)、schilit@google.com (相關 RFC 作者)。
諮詢對象:軟體提交團隊、受管理作業系統團隊和基礎架構團隊成員。
社交化:此 RFC 的草稿除了與諮詢團隊討論之外,還傳送至 FEC 討論郵寄清單以供加註。
設計
在介紹設計總覽之前,我們會先介紹或說明一些術語和概念。
術語
在下文段落中,粗體字詞的意思會在周圍文字中說明。
Fuchsia 來源樹狀結構包含多個不同的 Git 存放區,這些存放區會根據儲存在名為 integration.git 的 Git 存放區中的設定,由名為 jiri 的工具一起設定為一個來源樹狀結構。這些 Git 存放區中最重要的是 fuchsia.git,但還有許多其他存放區,包括第三方存放區。jiri 設定也能控制是否將預先建構的構件納入來源樹狀結構的專屬部分。預先建構的構件本身會儲存在名為 CIPD 的儲存空間服務中,並受修訂版本控制,而描述 CIPD 中預先建構的構件位置和修訂版本的 jiri 設定,則會受 integration.git 存放區中的 Git 修訂版本控制。
定期執行的建構工作稱為 Roller,會嘗試更新 Fuchsia 來源樹狀結構中包含的預先建構構件版本。如果 Fuchsia 樹狀結構的所有所需建構產品都能使用構件的更新版本進行建構及測試,系統會修訂 Fuchsia 樹狀結構,並將更新版本的成果更新為固定版本。不同的預先建構成果可以有不同的 Roller。
事實上,Fchsia 來源樹狀結構會同時取得來源存放區的角色,對 Fuchsia 產品中使用的許多構件,以及「整合存放區」,其中每個 Fuchsia 產品都會按各自的部分組合。
Artifact 是指產品組裝過程中使用的任何成分。這類構件會從來源存放區取得,可以直接做為來源項目之一,也可以做為在存放區中執行建構程序後取得的建構產品。這類構件大多是預先建構的 Fuchsia 套件,但也包含 Zircon、Fuchsia 核心,不久後可能還會包含子組裝規格檔案。Zircon 核心和預先建構的套件是預先建構的構件;子組合規格檔案是來源成果。
從一個來源存放區取得的構件最終會發布至 Artifact Store。這類版本可以手動發布,也可以在預定的時間間隔內自動發布。無論使用哪種方式,產生的構件都會發布至原始碼存放區的專屬 Artifact Store。Artifact Store 可做為原始碼存放區外的任何位置,無須參照原始碼存放區,自行執行建構程序。因此,Artifact Store 可以是 CIPD 目錄、GCS 值區或 TUF 存放區。就這裡設計的流程而言,特定類型的 Artifact Store 並非必要。
TUF 存放區會用於向 Fuchsia 裝置推送軟體更新、在開發中為開發人員 Fuchsia 裝置或模擬器提供新重建套件,以及在實際工作環境中對 Fuchsia 裝置的 OTA 更新。在 Fuchsia 中要用於儲存服務的內容之上,使用 TUF 的具體方法特別適合用來儲存Fuchsia 套件。由於許多構件是 Fuchsia 套件,因此在這項設計中,我們將 TUF 存放區做為 Artifact Store 使用。
屬性是用來描述構件 (例如版本和變化版本) 的鍵/值屬性。索引鍵會說明變數的維度,值則是構件所在維度的位置。屬性會統一描述構件的版本和變化版本。在多數情況下,您不需要區分描述版本的屬性和描述變數的屬性。構件發布者可以指定下列屬性:
- CPU 架構變化版本:
x64
與arm64
。 debug
與optimized
編譯變化版本。- 建構構件的來源存放區的提交版本。
- 建構參數,用於建構構件。
- 建構產物所使用的 Fuchsia SDK 版本。
- 已建構的構件語意版本。例如 Chromium 發布版本 (例如
M88.xxx
),或是 Cast 發布版本 (例如1.56.xxx
)。 - 實作後,Fuchsia 系統 Artifact 的 RFC-0002 規定的 API 級別和 ABI 修訂版本。
- 花瓣提供的 API 級別或 SDK 版本,雖然不屬於 RFC-0002 的範疇,但與系統 ABI 同樣重要。例如,Flutter 應用程式建構時使用的 Flutter SDK 發布版本。
轉移屬性:部分屬性會描述構件檔案的轉移屬性,因為這些屬性與構件檔案所建構的輸入內容屬性相關。舉例來說,Fuchsia SDK 版本或 Flutter 版本其實是先行構件用來建構所述構件的屬性。這類傳遞性質的擴展範圍預期會更廣泛。因此,屬性值可以是依序包含鍵/值組合的物件,並以遞迴方式處理。
依附元件屬性:成果的依附元件 (包括版本和變化版本) 也可以用屬性表示。不過,Fuchsia 套件是密封的,因此已包含其依附元件。因此,依附元件通常不會經常出現在 Fuchsia 構件屬性中。
現況
在目前的全球整合程序中,如圖 2 所示,petal 建構程序會使用 CIPD 目錄做為構件儲存庫。構件儲存庫會在路徑名稱下保留構件 (在 CIPD 中稱為「package」,與 Fuchsia 套件沒有直接關聯)。CIPD 支援在「套件」的相同路徑名稱下儲存多個「例項」,並將「標記」和「參照」附加至例項。變化版本中繼資訊會編碼在儲存成果的路徑名稱元件中。版本中繼資料會在 CIPD 套件例項的標記和參照中編碼。產品建構程序會透過滾動取得固定版本的構件,並一律從固定版本的花瓣構件建構產品。
圖 2 - 目前的系統結構
透過構件儲存庫傳播擴充中繼資料
這裡提出的設計會變更構件儲存庫的結構,以便保留已發布的構件中繼資料屬性。產品接著可根據屬性值指定的條件,選取合適的構件。
這項設計涉及三個額外的設定檔,以及三個用於操作設定檔以與構件儲存庫互動的工具。檔案為 artifact_groups.json
,儲存在構件商店中;artifact_spec.json
和 artifact_lock.json
則儲存在產品整合存放區中。如圖 3 所示,upload
、update
和 fetch
工具會對檔案和構件執行操作,如下所示:
- 每個新版本的一系列構件,從 petal 或 Fuchsia 建構程序建立,會在與來源存放區相關聯的構件儲存庫中建立新的構件群組。已發布構件的屬性會記錄在
artifact_groups.json
檔案中,這個檔案也會保存在構件存放區中。- Petal 建構程序會使用
upload
工具,將新發布的構件發布至構件存放區,並更新artifact_groups.json
檔案。
- Petal 建構程序會使用
- 在產品整合存放區中,
artifact_spec.json
檔案會保留清單,指出要從哪些構件儲存庫取得整合存放區中產品組件的構件,以及要使用哪些屬性。update
工具可用於選取實際用於組件的構件集,方法是使用整合存放區中的artifact_spec.json
檔案,以及artifact_spec.json
檔案中列出的所有構件儲存器中的artifact_groups.json
檔案。
update
工具所選取的成果集會儲存在artifact_lock.json
檔案中。fetch
工具會下載artifact_lock.json
檔案中提及的所有構件,以便提供給整合存放區中的產品建構程序。
這些工具與建構規則的執行方式相關,取決於產品整合存放區中使用的特定建構系統。詳情請參閱實作一節。
這些工具可讓整合存放區中有多個 artifact_spec.json
和 artifact_lock.json
檔案。
圖 3 - 所有合作部分的關係
成果存放區內的邏輯結構
在構件儲存庫中,構件和構件群組的產生邏輯結構如下所示:
└── artifact_groups
|
├── 92d483e5-ac7d-4029-a7db-e2ee6a8365c7
| |
| ├── web_engine
| |
| └── cast_runner
|
└── c907ff3f-cb15-4a7f-bb79-8cc23c0ff445
|
├── web_engine
|
└── cast_runner
每個群組的構件版本都會顯示不透明的名稱,而每個構件都會以可辨識的名稱顯示為群組中的項目。
系統會記錄這個結構,並將發布版本和個別構件相關聯的屬性,以 JSON 資料結構的形式儲存在 artifact_groups.json
檔案中,詳情請參閱下文。
使用構件和群組名稱
JSON 資料會使用群組名稱和構件名稱,將記錄的屬性與所描述的構件建立關聯。群組和構件名稱會用於在 artifact_spec.json
檔案中,將構件選入產品組裝工作區的運算式中參照這兩者。這些構件名稱也會用來做為檔案名稱,fetch
工具會在該名稱下方儲存本機下載的副本。
不過,這兩個名稱都不會用於指定在 Artifact 儲存庫中 Artifact 的儲存位置。而是將所有構件儲存在其內容位址下,而 artifact_groups.json
中每個構件的內容位址都會記錄為 merkle
屬性。
使用的內容位址是構件立即內容的 Fuchsia merkle 根。部分構件 (特別是 Fuchsia 套件) 會以其他儲存空間元件 (稱為「blob」) 表示,這些元件會間接包含在構件的直接內容中。這些額外元件會儲存在其內容位址下,但不會在 artifact_groups.json
中明確提及。
唯一性不變量
在 Artifact Store 中,您必須維護一些不重複的變數。這些不變量可確保透過參照構件名稱和屬性,明確選取構件:
- 群組名稱在整個記錄期間內,在構件儲存庫中不得重複。
- 每個群組中的構件名稱不得重複。
- 在目前的構件儲存庫中,同一個群組中所有同名構件的屬性不得重複。
在構件儲存庫中新增構件群組時,upload
工具會維護這些不重複的不變性。update
工具也會檢查唯一性,如果所存取的所有 artifact_group.json
檔案皆不符合不變量,就會拒絕計算更新。在維護這些不變量時,構件儲存庫本身不需要扮演任何角色。
群組名稱不透明
您可以根據屬性值命名構件群組,讓構件儲存庫更易於理解或瀏覽。不過,只有在屬性不多且屬性集合固定時,這項方法才能正常運作。一旦屬性集合擴大到許多屬性,並且屬性集合開放,從這些屬性建立名稱就會變得繁瑣,因為即使是單一屬性值集合,也可能會出現大量可能的排列組合 (例如,架構是先出現還是最後出現,還是介於兩者之間?)。而且閱讀這類名稱時,眼睛也不容易看清楚,而且維持不變的唯一性,尤其是在歷史記錄中,也更加麻煩。
因此,由於這項設計的目標是支援大型且開放的屬性集合,因此群組名稱會設為不透明,以滿足必要的唯一不變量。在上述範例中,群組名稱是隨機的 UUID。另一種做法是使用單調遞增的填充整數。
artifact_groups.json
檔案
artifact_groups.json
檔案會列出該構件儲存庫中的所有群組、所含構件和相關屬性。
以下範例顯示與上述範例中結構體儲存庫相對應的 artifact_groups.json
。屬性會與構件群組建立關聯,在這種情況下,所有屬性都會套用至群組中的所有構件。屬性也可以只套用至個別構件。
這項設計並未規定屬性集。所有屬性都是由在原始碼存放區中產生構件的建構和發布程序選擇和指派。只有在需要維持上述不變的唯一性時,才需要指派屬性。
{
"schema_version": "https://fuchsia.dev/schemas/artifact_groups_schema.json",
"version": 15,
"artifact_groups": [
{
"name": "92d483e5-ac7d-4029-a7db-e2ee6a8365c7",
"attributes": {
"petal": "chromium.org",
"version": "chrominum_release_20210304",
"architecture": "arm64",
"sdk_version": "2.20210303.3.1",
"creation_time": "1622696983",
"commit": "b26e44e9910608a2d0aec9b38e003a04a2da06df"
},
"artifacts": [
{
"name": "web_engine",
"merkle":"90f67b10ded655852acb78a852ac5451486fc1e7378ce53368386244ce8f6e66",
"type": "package",
"attributes": {
"runner_version": "2.20210301.1.3"
}
},
{
"name": "cast_runner",
"merkle": "3394db36d228f4c719d055c394938c5a881ca6eea7ad3af0ad342e764cadc8b3",
"type": "package"
}
]
},
{
"name": "c907ff3f-cb15-4a7f-bb79-8cc23c0ff445",
"attributes": {
"petal": "chromium.org",
"version": "chrominum_release_20210402",
"architecture": "arm64",
"sdk_version": "2.20210303.3.4",
"creation_time": "1622157425",
"commit": "2dd76ad2298dfb869ef83c10b84b62485dc8a573"
},
"artifacts": [
{
"name": "web_engine",
"merkle": "acb78a852ac5451486fc1e7378ce53368386244ce8f6e6690f67b10ded655852",
"type": "package",
"attributes": {
"runner_version": "2.20210225.1.4"
}
},
{
"name": "cast_runner",
"merkle": "19d055c394938c5a881ca6eea7ad3af0ad342e764cadc8b33394db36d228f4c7",
"type": "package"
}
]
}
]
}
artifact_groups
清單中的每個群組物件都包含 3 個屬性:name
是群組名稱、artifacts
是群組中的成果清單,而 attributes
則是群組中所有成果共用的屬性。
只適用於單一構件的屬性,會包含在直接代表該構件的物件中。這個構件的屬性會附加至群組的屬性,以便取得完整的構件屬性組合。
版本號碼是單調遞增的數字。update
工具會使用這個數字,避免意外將 artifact_groups.json
檔案復原為舊版 artifact_groups.json
檔案。
構件群組及其屬性的可變動性
在一般情況下,每個已發布的建構版本都會記錄為新群組。因此,群組名稱、其中的一系列構件,以及大部分的屬性在概念上都是不可變動的。例外狀況是指反映構件發布後產生構件的資訊屬性。舉例來說,您可以透過手動測試構件,在構件發布後變更構件的測試結果狀態。反映這類資訊的屬性可能會更新。
原則上,成果群組內容與名稱或屬性不會因此隨著時間而變更。這在產品組合管道中很有用,但不會用於提議的應用程式 (請參閱下方實作一節的說明)。
產品建構程序
整合存放區中的產品建構程序會建立 artifact_spec.json
檔案,以下稱為「規格檔案」。這個檔案會列出產品在整合存放區中組合所需的構件、從中取得構件的構件商店,以及構件屬性的模式和限制。也會說明構件儲存庫的類型,而且一個規格檔案中可以同時存在多種不同類型的構件儲存庫。
具體來說,預先建構的構件可儲存在整合存放區本身,並可在規格檔案中參照來自「local」類型的構件存放區。
整合存放區中的產品建構程序會使用 update
工具,比對規格檔案中提及的所有構件商店中的 artifact_groups.json
檔案,並計算要使用的特定構件變化版本和版本。這組資訊會記錄在 artifact_lock.json
檔案中。這個檔案應當做為存放區中的來源檔案提交。
fetch
工具會讀取 artifact_lock.json
檔案,並將所有構件下載到整合存放區。這些構件並非要以來源檔案的形式提交至存放區。不過,系統會在 artifact_lock.json
檔案中,透過從 artifact_groups.json
檔案擷取的內容位址來識別這些構件。這可確保 artifact_lock.json
的已提交內容能完全決定提供給建構作業的構件內容,進而讓產品組合建構作業在 artifact_lock.json
檔案中選取的構件方面,具有密封性和可重現性。
實作
我們首先會實作這裡提出的設計,將工作站產品整合移至單獨的存放區。
另一個 RFC 說明了 artifact_spec.json
的必要詳細資料,以及如何針對 artifact_groups.json
檔案處理 artifact_spec.json
,以產生 artifact_lock.json
檔案。
遷移現有的花瓣和產品
只要 Fuchsia 來源樹狀結構中仍需要使用 Pechsia 來源樹狀結構 (透過 integration.git 設定) 的寵物預建物,就必須將這類模型上傳到 CIPD,才能使用 Fuchsia 來源樹狀結構中的 gn 建構規則,以及用於樹狀產品產品使用的成果儲存庫。最終,Fuchsia 來源樹狀結構中將不再需要某些 petal 預先建構項目,因此可以停止上傳至 CIPD。
您不需要取代使用 jiri 自行設定 Fuchsia 來源樹狀結構的機制,因為所有 Fuchsia 平台構件和 SDK,以及部分產品仍使用 Fuchsia 來源樹狀結構建構。
構件存放區
工作站及其花瓣的實作項目會使用 TUF 存放區做為構件儲存空間。TUF 存放區 targets.json
檔案中唯一的項目是用於 artifact_groups.json
檔案。構件本身會儲存在由 Fuchsia 使用的 TUF 伺服器基礎架構維護的內容位址 blob 儲存庫中,而對應的 blob 位址會記錄在 artifact_groups.json
檔案中。
此外,構件也可以列在目錄和構件名稱下的 targets.json
中,但這項設計中沒有任何必要項目。(這只是為了完整呈現歷史資料,因為過去如果有人需要 targets.json
項目,請參閱下方的替代方法一節)。
Fuchsia 套件結構依附元件
這裡提供的三個工具可與構件集合存放區互動 (上傳、更新、擷取),並在 Fuchsia 套件上運作,因此會對 Fuchsia 套件的結構做出假設。具體來說,我們假設 Fuchsia 套件包含一個 meta.far
blob,其中含有其他同樣屬於套件的 blob 內容位址 (以「merkle roots」表示)。系統會使用 Fuchsia SDK 提供的工具取得 meta.far
中參照的 blob 清單,因此構件儲存工具 (上傳、更新、擷取) 不依賴 meta.far
的內部結構。
工具與建構規則的關係
upload
、update
和 fetch
工具與執行建構規則的關係,取決於來源存放區和產品整合存放區中的特定建構系統,以及執行建構作業的基礎架構。
建構系統完成建構作業後,系統會執行 upload
工具。
通常,update
工具應在建構作業執行前,於建構規則外部使用。
fetch
工具可在執行建構規則之前使用,如果建構系統支援,也可以在建構系統執行時使用。至於工作站,系統會使用 bazel
做為建構系統,支援設定在稱為「工作區規則」中的輸入檔案。
工具可執行檔的名稱
相較於這項設計所用的概念名稱,工具 upload
、update
、fetch
最終可能會以其他名稱實作。具體來說,這些工具可做為 ffx
工具的外掛程式,或做為 bazel
建構規則產生的工具。初始原型會實作為名為 artifact_upload.py
、artifact_update.py
和 artifact_fetch.py
的 Python 指令碼。
檔案語法
artifact_groups.json
檔案的語法是由下列 JSON 結構定義提供。artifact_spec.json
和 artifact_lock.json
檔案的 JSON 結構定義記錄在不同的 RFC 中。
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "https://fuchsia.dev/schemas/artifact_groups_schema.json",
"type": "object",
"additionalProperties": false,
"required": [
"contents",
"schema_version",
"version"
],
"properties": {
"schema_version": {
"type": "string"
},
"version": {
"type": "integer"
},
"artifact_groups": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"attributes": {
"type": "object"
},
"artifacts": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"merkle",
"type",
],
"properties": {
"name": {
"type": "string"
},
"merkle": {
"type": "string"
},
"attributes": {
"type": "object"
},
"type": {
"type": "string"
}
}
}
}
}
}
}
}
}
檔案語意
以下說明 artifact_groups.json
的檔案格式語意。artifact_spec.json
和 artifact_lock.json
的詳細語意再次記錄在個別 RFC 中。
{
"schema_version": SCHEMA_VERSION,
"version": VERSION,
"artifact_groups": [
ARTIFACT_GROUP,
...
]
}
SCHEMA_VERSION
代表
artifact_groups.json
JSON 結構定義網址的字串。
版本
這個整數會指出
artifact_groups.json
的版本號碼。發布新版本時,這個數字應會增加。
ARTIFACT_GROUP
每個 ARTIFACT_GROUP 都是一個物件,其格式如下:
{
"name": NAME,
"attributes": ATTRIBUTES,
"artifacts": [
ARTIFACT,
...
]
}
名稱
提供參照這個成果群組的字串。
屬性:
由發布商定義的物件。
古物
每個 ARTIFACT 都是物件,格式如下:
{
"name": NAME,
"merkle": MERKLE,
"type": TYPE,
"attributes": ATTRIBUTES
},
名稱
包含此構件名稱的字串。
商品
資源的 Merkle 根目錄字串。
類型
包含此構件類型的字串。如果
TYPE
是"package"
,則由其梅克爾根目錄參照的 Blob 中的這個構件,就是 Fuchsia 套件的meta.far
,而meta.far
中間接參照的 Blob 一律會與 meta.far Blob 一併處理。否則,構件只包含已列出 Merkle 的單一 Blob。
屬性
與上述定義的 ATTRIBUTES 類似的物件。請在這裡定義構件專屬的屬性。
安全性考量
本 RFC 中的設計不會變更現有參與者之間的信任模式。這個機制只會變更儲存空間結構,不會變更使用構件儲存庫的使用者之間,或使用者與構件儲存庫之間的信任關係。
信任模式
如同目前使用 CIPD 做為構件存放區的現況,產品建構程序需要信任構件存放區。此信任目前是以存取權控管和驗證為基礎,在將構件提供給商店時,會套用至寵物和 Fuchsia 建構程序,並仰賴建構基礎架構和環境來解析已設定的構件儲存庫名稱,以存取正確的構件存放區。
建立更多構件商店和產品整合存放區後,就必須評估這些項目的信任基地,而必須對應組合產品的可信度。
日後,我們可能會建立額外的機制,以便在目前使用的機制之上運作,例如驗證簽章 (例如 TUF 存放區中的簽章)。這裡設計的機制可支援相關資訊的傳播,以便評估可信度,但這類資訊的建立方式是互相獨立的。
請特別注意,針對 TUF 簽章,請務必注意,這類簽章僅提供證據,證明託管構件的存放區是否可信。這項資訊本身並不能構成評估從中取得的構件可信度的完整依據,因為這還取決於簽署金鑰的控管方式、產生構件的建構程序的可信度,以及建構程序用來做為輸入內容的傳遞來源和工具的可信度。以目前用於 Fuchsia 產品的 TUF 實作方式 (用於簽署任何上傳至維護存放區的服務的成果) 而言,也取決於 ACL 的完整性,以及允許用戶端存取該服務的驗證機制。
多個花瓣建構程序發布至相同的構件儲存庫
建議發布來源存放區不要共用構件儲存庫,這樣無論信任關係如何建立,都不會與伺服器共用信任關係。舉例來說,在實作 TUF 時,發布者不必分享簽署金鑰。
另外,多個花瓣式建構程序發布至相同的構件儲存庫,也可能會導致妥協。舉例來說,某個發布者可能會覆寫其他發布者發布的構件。但這超出本 RFC 的範圍,因為在本 RFC 中,所有發布至構件儲存庫的 petal 建構程序都是由同一機構運作,因此可以妥善協調。如果要將這項功能擴展至多個機構,就必須設計不同的協調模型。
成效
隨著 artifact_groups.json
檔案中的項目數量增加,尋找符合所有必要屬性的群組時間會至少線性增加。如果各個構件之間有限制條件,則可能會超線性,因為更新工具需要彙整多個 artifact_groups.json
檔案才能進行選取。構件發布者可能需要移除過舊的構件群組,以便改善用戶端更新工具的效能。
大型產品選取後,構件的下載時間可能會相當可觀。這與現況並無二致。與全域整合相比,這裡提供的設計具有以下優點:fetch
工具只需將單一產品的預先建構構件下載至任何一個整合存放區。在目前的全域整合作業中,所有已知產品的預先建構構件組合,都必須在 jiri update
期間下載。
隱私權注意事項
唯一儲存在構件儲存庫中的新資料是 artifact_groups.json
檔案。構件存放區的發布者不應在 artifact_groups.json
檔案中發布 PII。
測試
工具使用的程式庫 (例如將 artifact_spec.json
檔案中的屬性模式與 artifact_groups.json
檔案進行比對) 將由單元測試來測試。
以執行工具做為執行檔的作業而言,整合測試會從本機保留的黃金檔案執行。
針對端對端測試,專屬的存放區會包含「Hello World」產品,持續執行機制,並監控是否發生錯誤。
缺點、替代方案和未知事項
使用其他類型的構件儲存庫
除了 TUF 之外,您也可以使用其他構件儲存庫。例如:
- CIPD,
- 靜態 HTTPS 伺服器
- GCS 值區
- Git 存放區。
您可以在所有這些構件儲存庫中建立適當的結構,以便在其內容位址下方找到構件,並在 artifact_groups.json
檔案中維護中繼資料,就像在上述實作中使用的 TUN 存放區一樣。
每個版本的 TUF 存放區
先前設計在這個設計中的另一個替代方案,就是每個構件版本的 TUF 存放區。upload
工具不會為版本的所有構件建立群組,而是會建立新的 TUF 存放區來代管構件。眾所周知的查詢存放區包含記錄屬性的 artifact_groups.json
檔案。這個檔案會包含每個構件群組的存放區名稱,而非群組名稱。
這種方法的好處是,可支援使用暫時性套件的產品,這些套件只會在首次使用時傳送至裝置。該存放區不會包含在產品組合中這類發布存放區中,或是連同套件一起納入產品中,用來在執行階段解析套件網址。
這項設計用途遭到拒絕,因為這類產品目前尚不存在,而且在裝置和 TUF 基礎架構中,目前用於提供軟體的機制雖然是為了這類用途而設計,但從未證明可用於正式版,因此在可行之前,這些機制預計會進一步演進。因此,我們強烈建議不要受限於目前的軟體推送狀態。同樣地,TUF 基礎架構也無法妥善處理大量 TUF 存放區。
TUF 存放區 targets.json
中列出的所有構件
原本的構想是,所有構件 (尤其是所有 Fuchsia 套件) 都會列在 TUF 存放區的 targets.json
檔案中,而將成果群組在一個版本中的目錄,則是包含 TUF 存放區目標的實際目錄。這項資訊與 artifact_groups.json
中記錄的資訊重複,毫無用途,因此為了求明確而捨棄此資訊,同時也為了規避 targets.json
中並未對 targets.json
中所列的檔案設下的大小限制。
不明
目前尚未回答有關應用程式可擴充的設計問題。
- 這個機制是否也適用於 Fuchsia SDK?Fuchsia SDK 是建立花瓣元件和樹狀結構產品的必要構件,就像預先建構的構件是建立產品的必要構件一樣。您需要根據描述變化版本和版本的屬性,以非常相似的方式選取這項構件。因此,這個問題本身是請寵物建構程序是否應在
artifact_spec.json
檔案中宣告 SDK 的使用方式,以及產品建構程序是否應在artifact_spec.json
檔案中加入 Fuchsia SDK。 - 這個機制是否也適用於花瓣 SDK?也就是一個花瓣提供給其他花瓣的 SDK,例如 Flutter SDK?啟用去中心化產品整合功能並非必要,但可以簡化產生的分散式建構程序。舉例來說,透過檢查花瓣存放區鎖定檔案擷取的 Flutter SDK 版本後,上傳工具能找出已上傳構件的正確 Flutter SDK 版本屬性值。
- 這個機制是否也能用於發布已建構的產品?在工作站實作中,fuchsia 工作站產品可發布至構件儲存庫。您上傳的產品之後可以用於差異化組。
- 說明機制是否可用於對產品建立作業中涉及的所有二進位檔成果建立二進位檔透明度,並回溯至產品中包含的預先建構成果、用於組合產品的工具的預先建構成果,以及用於建立預先建構成果的工具等。
說明文件
本文件做為初始說明文件。除了能提供的工具與說明頁面外工作站存放區設定可做為藍圖和示範,供日後使用。
既有技術與參考資料
其他作業系統的產品整合作業通常會從源樹開始,因為這類樹狀結構較少使用預先建構的項目,因此在儲存庫之間同時散布多個變化版本和預先建構的版本的需求也較少。
建構系統「選取」相依項目的「版本」,只需在目前版本中重新建構相依項目,並在由目前套用建構參數決定的變化版本中執行此操作。這裡顯示的設計可以理解為建構系統的一般化程序,以非同步和發布的方式運作。
相關文件
- 去中心化產品整合 Fuchsia 路線圖項目。
- 平台版本管理 RFC
- 獨立圖片組合工具 RFC
- Workstation Out Of Tree RFC
- 樹外 Bazel SDK RFC 草稿
- 去中心化產品整合作業,構件選取規格 RFC 草稿
- 從子組件組合產品 RFC 草稿
附錄
圖 4 - 全域整合圖圖例