Share via


Device Update for IoT Hub の差分更新について理解して使用する方法 (プレビュー)

差分更新を使用すると、2 つの完全な更新 (ソース イメージとターゲット イメージ) 間の変更のみを表す小さな更新を生成できます。 これは、更新をデバイスにダウンロードする際に使用される帯域幅を減らすのに最適な方法です。特に、ソースとターゲットの更新の間にわずかな変更しかない場合に有効です。

Note

現在、差分更新機能はパブリック プレビュー段階にあります。

Device Update for IoT Hub で差分更新を使用するための要件

  • ソースとターゲットの更新ファイルは、SWUpdate (SWU) 形式である必要があります。
  • 各 SWUpdate ファイル内には、Ext2、Ext3、または Ext4 ファイルシステムを使用する生イメージが存在している必要があります。 このイメージは、gzip または zstd で圧縮できます。
  • 差分生成プロセスは、最適な差分を生成するために、zstd 圧縮を使用してターゲット SWU 更新を再圧縮します。 この再圧縮されたターゲット SWU 更新を、生成された差分更新ファイルと共にデバイス更新サービスにインポートします。
  • デバイスの SWUpdate 内で、zstd 圧縮解除も有効にする必要があります。
    • このプロセスには、SWUpdate 2019.11 以降を使用する必要があります。

デバイス更新エージェントと差分プロセッサ コンポーネントを使用してデバイスを構成する

デバイスがデバイス更新サービスから差分更新をダウンロードしてインストールするには、複数のコンポーネントが存在し、構成されている必要があります。

デバイス更新エージェント

デバイス更新エージェントは、ダウンロード、インストール、再起動の操作など、デバイス上の更新プロセスを "調整" します。 デバイス更新エージェントをデバイスに追加して、使用できるように構成します。 エージェント バージョン 1.0 以降を使用します。 手順については、「デバイス更新エージェントのプロビジョニング」を参照してください。

更新ハンドラー

更新ハンドラーは、デバイス更新エージェントと統合され、更新の実際のインストールを実行します。 差分更新では、変更したい独自の 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 イメージ ファイルをデバイスに追加する

差分更新がデバイスにダウンロードされた後、デバイスで以前にキャッシュされた有効な "ソース 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 16 進数文字列ですが、base64 16 進数文字列にエンコードした後、文字を次のようにエンコードします。

  • +octets _2B にエンコード
  • /octets _2F にエンコード
  • =octets _3D にエンコード

DiffGen ツールを使用して差分更新を生成する

環境の前提条件

DiffGen を使用して差分を作成する前に、環境マシンにダウンロードまたはインストール (あるいはその両方) する必要があるものがいくつか存在します。 Linux 環境、特に Ubuntu 20.04 (または、Windows ネイティブの場合は Linux 用 Windows サブシステム) をお勧めします。

次の表に、必要なコンテンツの一覧、それらの取得先、および必要に応じて推奨されるインストールを示します。

バイナリ名 取得先 インストール方法
DiffGen Azure/iot-hub-device-update-delta GitHub リポジトリ ルート フォルダーから、Microsoft.Azure.DeviceUpdate.Diffs.[version].nupkg ファイルを選択します。 NuGet パッケージの詳細については、こちらを参照してください
.NET Core ランタイム、バージョン 6.0.0 ターミナル/パッケージ マネージャー経由 Linux 向けの手順。 ランタイムのみ必要になります。

依存関係

zstd_compression_tool は、アーカイブのイメージ ファイルを圧縮解除し、zstd で再圧縮するために使用されます。 このプロセスにより、差分生成に使用されるすべてのアーカイブ ファイルが、アーカイブ内のイメージに対して同じ圧縮アルゴリズムを使用するようになります。

必要なパッケージやライブラリをインストールするコマンドは、次のとおりです。:

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

DiffGen を使用して差分更新を作成する

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 ファイルが署名されている (その可能性が高い) 場合、引数がもう 1 つ必要になります。

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 が追加された入力の名前を使用して、署名コマンドが新しいシグネチャ ファイルを作成することを想定しています。 コマンド全体が 1 つのパラメーターとして渡されるように、パラメーターを二重引用符で囲む必要があります。 また、署名に使用するキー パスに '~' 文字を含めないようにしてください。代わりに完全なホーム パスを使用します (たとえば、~/keys/priv.pem の代わりに /home/USER/keys/priv.pem を使用します)。

DiffGen の例

こちらの例では、(WSL で) /mnt/o/temp ディレクトリから操作しています。

"入力ソース ファイルと再圧縮されたターゲット ファイル間の差分の作成":

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

生成された差分更新をインポートする

デバイス更新サービスに更新をインポートするための基本的なプロセスは、差分更新でも変更されていないため、まだ確認していない場合は、Azure Device Update for IoT Hub にインポートする更新の準備方法に関するページをお読みください。

インポート マニフェストを生成する

デバイス更新サービスに更新をインポートするための最初の手順は常に、インポート マニフェストを作成することです (まだ存在しない場合)。 インポート マニフェストの詳細については、デバイス更新への更新のインポートに関するページを参照してください。 差分更新の場合、インポート マニフェストで次の 2 つのファイルを参照する必要があります。

  • DiffGen ツールを実行したときに作成された "再圧縮された" ターゲット SWU イメージ。
  • DiffGen ツールを実行したときに作成された差分ファイル。

差分更新機能では、関連ファイルと呼ばれる機能が使用されます。これには、バージョン 5 以降のインポート マニフェストが必要です。

関連ファイル機能を使用して差分更新用のインポート マニフェストを作成するには、インポート マニフェストに relatedFilesdownloadHandler オブジェクトを追加する必要があります。

ファイル名、ファイル サイズ、sha256 ハッシュなど、デルタ更新ファイルに関する情報を指定するには、relatedFiles オブジェクトを使用します。 重要な点として、以下に示すように、差分更新機能に固有の 2 つのプロパティも指定する必要があります。

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

これらの両方のプロパティは、差分更新の作成時に DiffGen ツールへの入力として使用した "ソース SWU イメージ ファイル" に固有のものです。 ソース SWU イメージに関する情報は、実際にはソース イメージをインポートしない場合でも、インポート マニフェストで必要になります。 デバイス上の差分コンポーネントは、差分がダウンロードされると、ソース イメージに関するこのメタデータを使用して、デバイス上のイメージを見つけます。

デバイス更新エージェントが関連ファイル機能を使って、差分更新を調整する方法を指定するには、downloadHandler オブジェクトを使用します。 独自のバージョンのデバイス更新エージェントを差分機能用にカスタマイズする場合を除き、こちらの downloadHandler のみ使用してください。

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

Azure コマンド ライン インターフェイス (CLI) を使用して、差分更新のインポート マニフェストを生成できます。 以前に Azure CLI を使用してインポート マニフェストを作成したことがない場合は、「基本的な Device Update のインポート マニフェストを作成する」をご覧ください。

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 Portal を使用したインポート

インポート マニフェストを作成したら、差分更新をインポートする準備ができました。 インポートするには、Device Update for IoT Hub への更新の追加に関するページに記載されている手順に従います。 インポート時に、こちらの項目を含める必要があります。

  • 前の手順で作成したインポート マニフェスト .json ファイル。
  • DiffGen ツールを実行したときに作成された "再圧縮された" ターゲット SWU イメージ。
  • DiffGen ツールを実行したときに作成された差分ファイル。

差分更新をデバイスにデプロイする

差分更新をデプロイする際の Azure portal におけるエクスペリエンスは、通常のイメージ更新のデプロイと同様です。 更新のデプロイの詳細については、「Device Update for Azure IoT Hub を使用して更新プログラムを展開します」を参照してください。

差分更新のデプロイを作成すると、デバイス更新サービスとクライアントは、デプロイ先のデバイスごとに有効な差分更新があるかどうかを自動的に識別します。 有効な差分が見つかった場合は、差分更新がダウンロードされ、そのデバイスにインストールされます。 有効な差分更新が見つからない場合は、代わりに、完全なイメージ更新 (再圧縮されたターゲット SWU イメージ) がフォールバックとしてダウンロードされます。 この方法により、更新のデプロイ先のすべてのデバイスが適切なバージョンになります。

差分更新のデプロイの結果として、次の 3 つが考えられます。

  • 差分更新が正常にインストールされた。 デバイスは新しいバージョンになります。
  • 差分更新を使用できなかったか、インストールできなかったが、代わりに、完全なイメージのフォールバック インストールが正常に行われた。 デバイスは新しいバージョンになります。
  • 差分と完全なイメージへのフォールバックの両方が失敗した。 デバイスは古いバージョンのままです。

上記のどの結果が発生したかを判断するために、失敗状態のデバイスを選択することで、エラー コードと拡張エラー コードを含むインストール結果を表示できます。 必要に応じて、障害が発生した複数のデバイスからログを収集することもできます。

差分更新が成功した場合、デバイスには "成功" の状態が表示されます。

差分更新に失敗したが、完全なイメージへのフォールバックが成功した場合、次のエラー状態が表示されます。

  • resultCode: [0 より大きい値]
  • extendedResultCode: [0 以外]

更新が失敗した場合は、こちらの手順を使用して解釈できるエラー状態が表示されます。

  • result.h にあるデバイス更新エージェントのエラーから始めます。

    • 差分更新に使用されるダウンロード ハンドラー機能に固有のデバイス更新エージェントのエラーは、0x9で始まります。

      コンポーネント Decimal (10 進数型) Hex 注意
      EXTENSION_MANAGER 0 0x00 拡張機能マネージャーのダウンロード ハンドラー ロジックのエラーを示します。 例: 0x900XXXXX
      PLUGIN 1 0x01 ダウンロード ハンドラー プラグイン共有ライブラリの使用に関するエラーを示します。 例: 0x901XXXXX
      RESERVED 2 - 7 0x02 - 0x07 ダウンロード ハンドラー用に予約されています。 例: 0x902XXXXX
      COMMON 8 0x08 差分ダウンロード ハンドラー拡張機能の最上位ロジックのエラーを示します。 例: 0x908XXXXX
      SOURCE_UPDATE_CACHE 9 0x09 差分ダウンロード ハンドラー拡張機能のソース更新キャッシュのエラーを示します。 例: 0x909XXXXX
      DELTA_PROCESSOR 10 0x0A 差分プロセッサ API のエラーのエラー コード。 例: 0x90AXXXXX
    • エラー コードが result.h に存在しない場合は、差分プロセッサ コンポーネント (デバイス更新エージェントとは異なります) でエラーが発生している可能性があります。 その場合、extendedResultCode は 0x90AXXXXX という 16 進数形式の負の 10 進値になります。

      • 9 は "差分機能" です
      • 0A は "差分プロセッサ コンポーネント" です (ADUC_COMPONENT_DELTA_DOWNLOAD_HANDLER_DELTA_PROCESSOR)
      • XXXXX は、FIT 差分プロセッサの 20 ビット エラー コードです
  • エラー コード情報に基づいて問題を解決できない場合は、GitHub の問題を提出して、さらにサポートを受けてください。

次のステップ

一般的な問題のトラブルシューティング