分享方式:


如何了解和使用 IoT 中樞裝置更新 (預覽版) 中的 delta 更新

Delta 更新可讓您產生少量更新,只代表兩個完整更新之間的變更 - 來源映像和目標映像。 此方法很適合用來減少用來將更新下載到裝置的頻寬,特別是在來源和目標更新之間只有些許變更的情況下。

注意

delta 更新功能目前是公開預覽版

在 IoT 中樞裝置更新中使用 delta 更新的需求

  • 來源和目標更新檔案必須是 SWUpdate (SWU) 格式。

  • 在每個 SWUpdate 檔案內,都必須有使用 Ext2、Ext3 或 Ext4 檔案系統的原始映像。

  • 差異產生程序會使用 gzip 壓縮來重新壓縮目標 SWU 更新,以產生最佳差異。 將此重新壓縮的目標 SWU 更新匯入至裝置更新服務,以及產生的差異更新檔案。

使用裝置更新代理程式和差異處理器元件設定裝置

為了讓裝置從裝置更新服務下載並安裝 delta 更新,您需要擁有並設定數個元件。

裝置更新代理程式

裝置更新代理程式會「協調」裝置上的更新程序,包括下載、安裝及重新開機動作。 將裝置更新代理程式新增至裝置,並加以設定以供使用。 請使用代理程式 1.0 或更新版本。 如需指示,請參閱裝置更新代理程式佈建

更新處理常式

更新處理常式會與裝置更新代理程式整合,以執行實際的更新安裝。 對於 delta 更新,如果您還沒有想要修改的 SWUpdate 更新處理常式,請從 microsoft/swupdate:2 更新處理常式開始。

差異處理器

在下載差異檔案之後,差異處理器會在您的裝置上重新建立原始的 SWU 映像檔,讓您的更新處理常式能夠安裝 SWU 檔案。 差異處理器可在 Azure/iot-hub-device-update-delta GitHub 存放庫中找到。

若要將差異處理器元件新增至裝置映像並設定以供使用,您可以下載受 Ubuntu 20.04 和更新版本支援的 .deb 套件。 如果您使用其他發行版本,請遵循 README.md 指示,改用 CMAKE 從來源建置差異處理器。 從該處藉由將共用物件 (libadudiffapi.so) 複製到 /usr/lib 目錄,直接安裝共用物件:

sudo cp <path to libadudiffapi.so> /usr/lib/libadudiffapi.so
sudo ldconfig

將來源 SWU 映像檔新增至您的裝置

差異更新下載至裝置後,必須與先前在裝置上快取的有效來源 SWU 檔案進行比較。 必須完成此程序,差異更新才能重新建立完整的目標映像。 填入此快取映像最簡單的方式,就是透過裝置更新服務 (使用現有的匯入部署程序),將完整映像更新部署至裝置。 只要裝置設定了裝置更新代理程式 (1.0 版或更新版本) 和差異處理器,裝置更新代理程式舊會自動快取已安裝的 SWU 檔案,以供後續的差異更新使用。

如果您改為想要直接預先填入裝置上的來源映像,則預期的映像路徑如下:

[BASE_SOURCE_DOWNLOAD_CACHE_PATH]/sha256-[ENCODED HASH]

根據預設,BASE_SOURCE_DOWNLOAD_CACHE_PATH 是路徑 /var/lib/adu/sdc/[provider]。 此值 [provider] 是來源 SWU 檔案 updateId 的提供者部分。

ENCODED_HASH 是二進位 SHA256 的 base64 十六進位字串,但在編碼為 base64 十六進位字串之後,它對字元的編碼如下所示:

  • + 編碼為 octets _2B
  • / 編碼為 octets _2F
  • = 編碼為 octets _3D

使用 DiffGen 工具產生 delta 更新

環境必要條件

使用 DiffGen 建立差異之前,必須先下載及/或安裝在環境機器上。 建議您使用 Linux 環境,特別是 Ubuntu 20.04 (如果是在原生 Windows 上,則為 Windows 子系統 Linux 版)。

下表提供所需的內容清單、擷取它們的位置,以及必要時建議的安裝:

二進位檔案名稱 取得位置 安裝方式
DiffGen Azure/iot-hub-device-update-delta GitHub 存放庫 下載與即將用來產生差異更新之機器上的 OS/發行版本相符的版本。
.NETCore Runtime 8.0.0 版 透過終端機/套件管理員 適用於 Linux 的指示。 只需要執行時間。

使用 DiffGen 建立 delta 更新

DiffGen 工具會使用數個引數來執行。 所有引數都是必要引數,整體語法如下:

DiffGenTool [source_archive] [target_archive] [output_path] [log_folder] [working_folder] [recompressed_target_archive]

  • 將會執行指令碼 recompress_tool.py 來建立檔案 [recompressed_target_archive],然後會使用此檔案,而不是 [target_archive] 作為建立差異的目標檔案。
  • [recompressed_target_archive] 內的映像檔會以 gzip 壓縮。

如果 SWU 檔案已簽署 (可能),則還需要另一個引數:

DiffGenTool [source_archive] [target_archive] [output_path] [log_folder] [working_folder] [recompressed_target_archive] "[signing_command]"

  • 除了使用 [recompressed_target_archive] 做為目標檔案以外,提供簽署命令字串參數會執行 recompress_and_sign_tool.py 來建立檔案 [recompressed_target_archive],並簽署封存內的 sw-description 檔案 (表示會出現 sw-description.sig 檔案)。 您可以使用 Azure/iot-hub-device-update-delta GitHub 存放庫提供的範例 sign_file.sh 指令碼。 開啟指令碼並加以編輯,以將路徑新增至您的私密金鑰檔案,接著儲存。 如需範例使用方式,請參閱範例一節。

下表將詳細說明引數:

Argument 描述
[source_archive] 這是在建立差異時,差異所依據的映像。 重要事項:此映像必須與裝置上存在的映像相同 (例如,從先前的更新快取)。
[target_archive] 這是差異更新裝置的映像。
[output_path] 主機電腦上的路徑 (包括要產生的差異檔案所需名稱),差異檔案會在建立後放置在此路徑。 如果路徑不存在,工具會加以建立。
[log_folder] 要在主機電腦上建立記錄的路徑。 建議將此位置定義為輸出路徑的子資料夾。 如果路徑不存在,工具會加以建立。
[working_folder] 在差異產生期間,在電腦上放置附隨品和其他工作檔案的路徑。 建議將此位置定義為輸出路徑的子資料夾。 如果路徑不存在,工具會加以建立。
[recompressed_target_archive] 重新壓縮目標檔案在主機電腦上的建立路徑。 此檔案會用來取代 <target_archive> 作為差異產生的目標檔案。 如果此路徑在呼叫 DiffGenTool 之前就已存在,則會覆寫路徑。 建議您將此路徑定義為輸出路徑子資料夾中的檔案。
"[signing_command]" (選用) 可自訂的命令,用於簽署重新壓縮封存檔案內的 sw-description 檔案。 重新壓縮封存中的 sw-description 檔案會當做簽署命令的輸入參數使用;DiffGenTool 預期簽署命令會使用附加 .sig 的輸入名稱來建立新的簽章檔案。 需要以雙引號括住參數,以便以單一參數的形式傳入整個命令。 此外,請避免將 '~' 字元放在用於簽署的金鑰路徑中,並改為使用完整的主路徑,並改用完整的主目錄路徑 (例如,使用 /home/USER/keys/priv.pem,而不是 ~/keys/priv.pem)。

DiffGen 範例

在下列範例中,我們在 /mnt/o/temp 目錄中進行操作 (在 WSL 中):

在輸入來源檔案和重新壓縮的目標檔案之間建立差異:

sudo ./DiffGenTool  
/mnt/o/temp/[source file.swu]  
/mnt/o/temp/[target file.swu]  
/mnt/o/temp/[delta file to be created]  
/mnt/o/temp/logs  
/mnt/o/temp/working  
/mnt/o/temp/[recompressed file to be created.swu]

如果您也使用簽署參數 (如果您的 SWU 檔案已簽署,則需要此參數),您可以使用先前參考的範例 sign_file.sh 指令碼。 首先,開啟指令碼並加以編輯,以將路徑新增至您的私密金鑰檔案。 儲存指令碼,然後執行 DiffGen,如下所示:

在重新壓縮/重新簽署的目標檔案之間建立差異:

sudo ./DiffGenTool  
/mnt/o/temp/[source file.swu]
/mnt/o/temp/[target file.swu]   
/mnt/o/temp/[delta file to be created]  
/mnt/o/temp/logs  
/mnt/o/temp/working  
/mnt/o/temp/[recompressed file to be created.swu]  
/mnt/o/temp/[path to script]/sign_file.sh

匯入產生的 delta 更新

將更新匯入裝置更新服務的基本程序對於 delta 更新而言沒有變更,因此,如果您尚未準備好,請務必檢閱此頁面:如何準備將更新匯入適用於 IoT 中樞的 Azure Device Update

產生匯入資訊清單

如果您還沒有匯入資訊清單,將更新匯入裝置更新服務的第一個步驟,一律是建立匯入資訊清單。 如需匯入資訊清單的詳細資訊,請參閱將更新匯入裝置更新。 針對差異更新,匯入指令清單必須參考兩個檔案:

  • 執行 DiffGen 工具時所建立的重新壓縮目標 SWU 映像。
  • 您在執行 DiffGen 工具時所建立的差異檔案。

delta 更新功能會使用稱為相關檔案的功能,需要第 5 版或更新版本的匯入資訊清單。

若要使用 [相關檔案] 功能來建立 delta 更新的匯入資訊清單,您必須將 relatedFilesdownloadHandler 物件新增至您的匯入資訊清單。

使用 relatedFiles 物件指定 delta 更新檔案的相關資訊,包括檔案名稱、檔案大小和 sha256 雜湊。 重要的是,您也需要指定兩個 delta 更新功能唯一的屬性:

"properties": {
      "microsoft.sourceFileHashAlgorithm": "sha256",
      "microsoft.sourceFileHash": "[insert the source SWU image file hash]"
}

上述兩個屬性都是您建立 delta 更新時用來做為 DiffGen 工具輸入的來源 SWU 映像檔。 即便您沒有實際匯入來源映像,您的匯入資訊清單中仍需要來源 SWU 映像的相關資訊。 裝置上的差異元件會使用關於此來源映像的中繼資料,在下載差異之後,在裝置上找出映像。

使用 downloadHandler 物件指定裝置更新代理程式如何使用相關檔案功能來協調 delta 更新。 若不是要為差異功能自訂您自己的裝置更新代理程式版本,則僅應使用此 downloadHandler:

"downloadHandler": {
  "id": "microsoft/delta:1"
}

您可以使用 Azure 命令列介面 (CLI) 來產生 delta 更新的匯入資訊清單。 如果您之前尚未使用 Azure CLI 來建立匯入資訊清單,請參閱建立基本匯入資訊清單

az iot du update init v5
--update-provider <replace with your Provider> --update-name <replace with your update Name> --update-version <replace with your update Version> --compat manufacturer=<replace with the value your device will report> model=<replace with the value your device will report> --step handler=microsoft/swupdate:2 properties=<replace with any desired handler properties (JSON-formatted), such as '{"installedCriteria": "1.0"}'> --file path=<replace with path(s) to your update file(s), including the full file name> downloadHandler=microsoft/delta:1 --related-file path=<replace with path(s) to your delta file(s), including the full file name> properties='{"microsoft.sourceFileHashAlgorithm": "sha256", "microsoft.sourceFileHash": "<replace with the source SWU image file hash>"}' 

將產生的匯入資訊清單 JSON 儲存至副檔名為 .importmanifest.json 的檔案中

使用 Azure 入口網站進行匯入

建立匯入資訊清單之後,即可匯入差異更新。 若要匯入,請依照將更新新增至 IoT 中樞裝置更新中的指示進行。 匯入時,您必須包含下列項目:

  • 您在上一個步驟中建立的匯入資訊清單 .json 檔案。
  • 執行 DiffGen 工具時所建立的重新壓縮目標 SWU 映像。
  • 您在執行 DiffGen 工具時所建立的差異檔案。

將 delta 更新部署至您的裝置

當您部署 delta 更新時,Azure 入口網站的體驗看起來與部署一般映像更新相同。 如需部署更新的詳細資訊,請參閱使用 Azure IoT 中樞裝置更新來部署更新

建立差異更新的部署後,裝置更新服務和用戶端會自動識別您要部署到的每個裝置是否具備有效的差異更新。 如果找到有效的差異,則會在該裝置上下載並安裝差異更新。 如果找不到有效的差異更新,則會改為下載完整映像更新 (重新壓縮目標 SWU 映像) 做為遞補。 此方法可確保您要部署更新的所有裝置皆為適當的版本。

delta 更新部署有三個可能的結果:

  • 已成功安裝 Delta 更新。 裝置為新版本。
  • Delta 更新無法使用或無法安裝,但會改為成功遞補安裝完整映像。 裝置為新版本。
  • 差異和遞補至完整映像失敗。 裝置仍為舊版本。

若要判斷發生上述哪些結果,您可以選取處於失敗狀態的任何裝置,以錯誤碼和延伸的錯誤碼來檢視安裝結果。 如有需要,您也可以從多個失敗的裝置來收集記錄

如果 delta 更新成功,裝置會顯示「成功」狀態。

如果 delta 更新失敗,但成功回溯至完整映像,則會顯示下列錯誤狀態:

  • resultCode:[值大於 0]
  • extendedResultCode:[非零]

如果更新失敗,系統會顯示錯誤狀態,可使用下列指示解譯:

  • result.h 中的裝置更新代理程式錯誤開始。

    • 裝置更新代理程式的錯誤,用於 delta 更新的下載處理常式功能的特有錯誤,開頭為 0x9:

      元件 Decimal Hex 注意
      EXTENSION_MANAGER 0 0x00 表示延伸模組管理員下載處理常式邏輯的錯誤。 範例:0x900XXXXX
      PLUGIN 1 0x01 表示下載處理常式外掛程式共用程式庫的使用錯誤。 範例:0x901XXXXX
      已保留 2 - 7 0x02 - 0x07 保留以供下載處理常式使用。 範例:0x902XXXXX
      通用 8 0x08 表示差異下載處理常式延伸模組最上層邏輯中的錯誤。 範例:0x908XXXXX
      SOURCE_UPDATE_CACHE 9 0x09 表示差異下載處理常式延伸模組來源更新快取的錯誤。 範例:0x909XXXXX
      DELTA_PROCESSOR 10 0x0A 差異處理器 API 錯誤的錯誤碼。 範例:0x90AXXXXX
    • 如果錯誤碼未出現在 result.h 中,則可能是差異處理器元件中的錯誤 (與裝置更新代理程式不同)。 若是如此,extendedResultCode 將是下列十六進位格式的負十進位值:0x90AXXXXXXX

      • 9 是 "Delta Facility"
      • 0A 是 "Delta Processor Component" (ADUC_COMPONENT_DELTA_DOWNLOAD_HANDLER_DELTA_PROCESSOR)
      • XXXXX 是 FIT 差異處理器的 20 位元錯誤碼
  • 如果您無法根據錯誤碼資訊解決問題,請提出 GitHub 問題以取得進一步的協助。

下一步

疑難排解常見問題