[和訳] Software Version Management and Image Update

# この記事について

* この記事はOpenBMCのSoftware Version Management and Image UpdateのREADMEを和訳したものです。
* 筆者が調査していた時(2020年10月)のREADMEを翻訳していますので、最新版は記述が変わっている場合もあると思います。
* 機械翻訳を少し手直して掲載していますが、表現を変えた方がよいというご指摘は歓迎です。編集リクエストお願いします。

> 翻訳元
> https://github.com/openbmc/phosphor-dbus-interfaces/tree/master/xyz/openbmc_project/Software
> ライセンス: Apache License 2.0

----
# Software Version Management and Image Update

## Overview

ソフトウェアバージョン管理とコード更新に関係するプロセスには2つのタイプがあります:

1. *ImageManager* - これは、ファイルシステムのどこかにある、おそらく一時的なイメージのコレクションを管理するプロセスです。
これらは、BMCの更新で使えるイメージです。
2. *ItemUpdater* - このプロセスは、インベントリアイテムのような特定のストレージエレメントを管理して、そのアイテムにインストールされているソフトウェアバージョンを決めるプロセスです。この具体的な例は、管理対象ホストのBIOSフラッシュモジュールを制御および更新するプロセスです。

単純なシステムデザインの場合、1つの* ImageManager *と2つの* ItemUpdater *を含めます。1つはBMC自体用で、もう1つはホスト用です。

### ImageManager

*ImageManager* は、`/xyz/openbmc_project/software` にインターフェイスを提供し、RESTのObject.Add() やTFTPのDownloadViaTFTP() などの追加のイメージをBMCに追加できるようにします。標準のObject.Delete()インターフェースも提供され、不要になったイメージの削除を容易にします。ファイルシステムに保持されているイメージは、対応する `/xyz/openbmc_project/software/<id>` オブジェクトとして表示されます。さらに、イメージの場所を指定するために、 `xyz.openbmc_project.Common.FilePath`インターフェースが提供されます。

*ImageManager* は、おそらく一般的なイメージ形式のために、
`xyz.openbmc_project.Software.Version`　のすべてのプロパティにデータを入力できるようにするために、
[少なくとも]最小限の解析知識を持っていることが必要です。

### *ItemUpdater*


*ItemUpdater*は、新しい `Software.Version`要素が作成されたか監視する責務を持っていて、管理しているインベントリエレメントで適用可能なバージョンを識別します。
*ItemUpdater* は、 `/xyz/openbmc_project/software/`の下に `xyz.openbmc_project.Software.Activation` インターフェイスを動的に作成する必要があります。
これは、`/xyz/openbmc_project/software/`の下の`Software.Version` と `Software.Activateion`の間の `{active_image、software_version}`型のアソシエーションです。
そして、`/xyz/openbmc_project/software/` の下の、`Inventory.Item` と `Software.Activation` .Activation`の間の `{activation、item}`型のアソシエーションです。
ソフトウェアイメージの適用は、 `Software.Activation` インターフェースの `RequestedActivation` プロパティを
介して処理されます。

*ItemUpdater* は、可能であれば、独自の `xyz.openbmc_project.Software.Version`オブジェクトと、管理対象インベントリ要素に現在存在するソフトウェアバージョンの適切なアソシエーションも作成する必要があります。
これにより、*ImageManager* にコピー(のイメージ?)が含まれなくなった時にソフトウェアバージョンを問い合わせるためのメカニズムが提供されます。

## 詳細

### イメージの識別 (Image Identifier)

*ImageManager* と*ItemUpdater* は、各 `Software.Version`のD-Busパスの `<id>` 部分に、 おそらく実装固有の方法ではありますが、共通のアルゴリズムを適用して決める必要があります。
これにより、同じソフトウェアバージョンを複数の場所に配置しても、同じオブジェクトパスで表すことができます。

お手軽なアルゴリズムはこんなかんじ:
`echo <Version.Version> <Version.Purpose> | sha512sum | cut -b 1-8`

> TODO: 単一のD-Busオブジェクトのコピー二つを、単一のRESTオブジェクトに「マージ」するには、RESTサーバーに対するIssueを解決する必要がありそうです。

### Activation States

`xyz.openbmc_project.Software.Activation`には、次のStateになり得るActivationプロパティがあります:

1. *NotReady* - ItemUpdaterがまだバージョンを処理しているため、アクティブ化の準備ができていないことを示します。これは、セキュリティヘッダーを持つイメージでverificationの実行中に使用される場合があります。
2. *Invalid* - `Software.Version.Purpose` はイメージが管理対象エレメントに対して有効であることを示唆するStateですが、*ItemUpdater* による詳細な分析はそうではなかったことを示しています。理由には、CRCまたはセキュリティ検証の失敗によって検出されたイメージの破損が含まれる場合があります。  イベントは、追加の詳細とともに記録される場合があります。
3. *Ready* - `Software.Version`をアクティブ化できることを示します。
4. *Activating* - `Software.Version`がアクティブ化されている途中であることを示します。
5. *Active* - `Software.Version`は管理対象エレメントでアクティブになっています。
冗長ストレージデバイスを備えたシステムでは、バージョンは *アクティブ* である可能性がありますが、プライマリバージョンではないことに注意してください。
6. *Failed* - `Software.Version`またはそれが保存されている記憶メディアに障害が発生しました。 イベントは、追加の詳細とともに記録される場合があります。
7. *Staged* - `Software.Version`は段階的な(in staged)フラッシュ領域にあります。これは、リセット時にステージングされたフラッシュ領域からアクティブなフラッシュ領域に移動されます。ステージングされたフラッシュ領域は、ファームウェアの更新プロセス中に着信する整合性が検証されたファームウェアイメージを格納するために使用される指定されたフラッシュ領域です。ステージングされたイメージは必ずしも機能するファームウェアではないことに注意してください。

### Image Apply Time

`xyz.openbmc_project.Software.ApplyTime` には、新しく適用されたソフトウェアイメージがいつアクティブ化されるかを示す RequestedApplyTime というプロパティがあります。
RequestedApplyTimeは、RedfishUpdateServiceスキーマの `ApplyTime` プロパティにマップされるD-Busプロパティです。
以下は現在サポートされている値であり、値はHttpPushUriApplyTimeオブジェクトを介して提供できます:

1. *Immediate* - `Software.Version`をすぐにアクティブ化する必要があることを示します。
2. *OnReset* - 次のリセット時に `Software.Version`をアクティブ化する必要があることを示します。

### 状態遷移のブロック (Blocking State Transitions)

アクティベーションの実行中にシステム状態遷移をブロックすると便利な場合があります。
たとえば、BIOSの更新中に管理対象ホストを起動したくありません。
これを容易にするために、インターフェース `xyz.openbmc_project.Software.ActivationBlocksTransition` を `Software.Activation` を持つ任意のオブジェクトに追加してこの動作を示すことができます。
詳細については、そのインターフェイスを参照してください。

管理対象のBMCを再起動する前に、アクティベーションを完了することを強くお勧めします。 これは、systemdサービス指定子(service specifiers)を使用すると容易になります。

### Software Versions

すべてのバージョン識別子は、実装固有の文字列です。
どのようなフォーマットにも限定されるべきではありません。

一部のソフトウェアバージョンはイメージの集合であり、それぞれに独自のバージョン識別子があります。
`xyz.openbmc_project.Software.ExtendedVersion`インターフェースを任意の` Software.Version`に追加して、集約のバージョン管理を表すことができます。

### Activation Progress

`xyz.openbmc_project.Software.ActivationProgress`インターフェースは、ソフトウェアバージョンが *Activating* されている間の現在の進行状況を表示するために提供されています。
  *ItemUpdater* は、バージョンが *Activating* されている間にこのインターフェイスを動的に作成し、アクティブ化が完了した（または失敗した）ときに動的に削除することが期待されます。

### Handling Redundancy

`xyz.openbmc_project.Software.RedundancyPriority` インターフェースは、単一の管理対象エレメントに対してアクティブ化された2つ(またはそれ以上) のソフトウェアバージョン間の関係を表すために提供されています。
インストールされているすべてのバージョンが *Active* としてリストされ、「優先度」はどのバージョンがプライマリで、どのバージョンが待機用に使用できるかを示します。

`Activation` の前に、目的の「RedundancyPriority」を指定すると便利な場合があります。
これは、 `RequestedRedundancyPriority`インターフェースで `Priority` を設定することで実行できます。
一部の *ItemUpdater* の実装は、このフィールドを重視しないか、
リクエストに準拠できない場合があります。
その場合、結果としての `Activation` は、`ActivationState = Failed` または
`RedundancyPriority = 0 (High)`を伴った`ActivateState = Active` の
いずれかの条件になる可能性があります。


## REST use-cases

### アクティブまたは使用可能なシステム上のすべてのソフトウェアバージョンを検索

`/xyz/openbmc_project/software/` をリストする。 
このリストは、アクティブなリスト `.../software/active/` にフィルターをかけ、 `software_version`のアソシエーションに従ってバージョン情報を取得できます。
「functional」または実行中のバージョンのみを一覧表示するには、 `/xyz/openbmc_project/software/Functional/` を一覧表示します。

### 管理対象エレメントのすべてのソフトウェアバージョンを検索

`/xyz/openbmc_project/inventory/.../<item>/activation` のアソシエーションをリストする。

### REST経由で新しいバージョンをアップロード

HTTP PUT → `/xyz/openbmc_project/software/`。
*ImageManager* は`<id>` をObject.Add() が呼ばれるとアサインする。

### ???経由で新しいバージョンをアップロード

Need additional interfaces defined for alternative upload methods.

### versionのアクティベート.

目的となる`Activation`上で、`RequestedActivation`を *Active* に変更します。

### プライマリイメージのスイッチ

目的となる `RedundancyPriority`インターフェースで `Priority` を 0 に設定します。