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

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

注意

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

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

  • 來源和目標更新檔案必須是 SWU (SWUpdate) 格式。
  • 在每個 SWUpdate 檔案內,都必須有使用 Ext2、Ext3 或 Ext4 檔案系統的原始映像。 該映像可以使用 gzip 或 zstd 壓縮。
  • 差異產生程序會使用 zstd 壓縮來重新壓縮目標 SWU 更新,以產生最佳差異。 您會將此重新壓縮的目標 SWU 更新匯入到裝置更新服務,以及產生的 delta 更新檔案。
  • 在裝置上的 SWUpdate 內,也必須啟用 zstd 解壓縮。

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

為了讓裝置從裝置更新服務下載並安裝差異更新,您需要數個元件存在並設定。

裝置更新代理程式

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

更新處理常式

更新處理常式會與裝置更新代理程式整合,以執行實際的更新安裝。 對於 delta 更新,如果您還沒有想要修改的 SWUpdate 更新處理常式,請從 microsoft/swupdate:2 更新處理常式開始。 如果您使用自己的更新處理常式,請務必在 SWUpdate 中啟用 zstd 解壓縮

差異處理器

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

若要將差異處理器元件新增至您的裝置映像並加以設定以供使用,請遵循 README.md 指示,使用 CMAKE 從來源建置差異處理器。 從該處藉由將共用物件 (libadudiffapi.so) 複製到 /usr/lib 目錄,直接安裝共用物件:

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

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

將 delta 更新下載到裝置之後,必須將其與先前快取在裝置上的有效「來源 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 上,則為 WSL)。

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

二進位檔案名稱 取得位置 安裝方式
DiffGen Azure/iot-hub-device-update-delta GitHub 存放庫 從根資料夾中,選取 Microsoft.Azure.DeviceUpdate.Diffs.[version].nupkg 檔案。 深入了解 NuGet 套件
.NET (執行階段) 透過終端機/套件管理員 適用於 Linux 的指示。 只需要執行時間。

相依性

zstd_compression_tool 用於解壓縮封存的映像檔,並使用 zstd 重新壓縮它們。 此程序確保用於差異產生的所有封存檔案對於封存內的映像具有相同的壓縮演算法。

安裝所需套件/程式庫的命令:

sudo apt update  
sudo apt-get install -y python3 python3-pip  
sudo pip3 install libconf zstandard

使用 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] 內的影像檔會以 zstd 壓縮。

如果您的 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 腳本。 開啟腳本,編輯腳本以將路徑新增至您的私密金鑰檔案,然後加以儲存。 如需範例使用方式,請參閱下面的範例一節。

下表將詳細說明引數:

引數 描述
[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 工具時所建立的差異檔案。

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

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

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

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

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

downloadHandler使用 物件來指定裝置更新代理程式如何使用相關的檔案功能協調差異更新。 除非您為差異功能自訂自己的裝置更新代理程式版本,否則請只使用此 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 入口網站進行匯入

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

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

將 delta 更新部署至您的裝置

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

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

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
      COMMON 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 問題以取得進一步的協助。

下一步

針對常見問題進行疑難排解