Topics で読み物として読む
この HLD は実装詳細を含みます。機能の概念・設定・運用を読み物として読みたい場合は Topics 10 章: gNMI / OpenConfig / 管理プレーン を参照。
裏取りステータス: Code-verified
sonic-host-services/host_modules/gnoi_reset.py L28-78 で factoryOs / zeroFill / retainCerts フラグ受領と factory_os_unsupported / zero_fill_unsupported レスポンス分岐実装を確認。sonic-gnmi/gnmi_server/gnoi_reset.go L16-41 で factory_reset.Start ハンドラが DBus 経由 FactoryReset を呼ぶ実装、sonic-gnmi/sonic_service_client/dbus_client.go L353 で DbusClient.FactoryReset、sonic-gnmi/pkg/gnoi/file/remove_test.go L18-49 で File.Remove のパス検証(nil / config_db.json / ../../etc/passwd リジェクト等)を確認。sonic-gnmi/gnoi_client/file/file.go L26-58 で File Stat/Get クライアント、sonic-gnmi/gnoi_client/factory_reset/factory_reset.go を確認。
gNOI File.Remove と FactoryReset.Start¶
読み手が知りたいこと¶
- gNOI とは何で、なぜ gNMI と同じポートで受けるのか
- なぜ container(telemetry)の中で実行せず DBUS で host に投げる必要があるのか
File.Removeは何を消せて、何を消せないのか(path traversal は防げているか)FactoryReset.Startの 3 フラグ(factory_os/zero_fill/retain_certs)は何を意味するか- 同時実行の抑制とエラー時の挙動
なぜこの拡張が必要か¶
gNOI(gRPC Network Operations Interface)は CLI 代替として gRPC で運用コマンドを実行 する仕様で、protobuf は openconfig/gnoi にある。SONiC では gNMI/telemetry サーバ(UMF)が gNOI も 同じ TCP 9339 で受け、認証認可後にバックエンドへ振り分ける1。本 HLD は以下 2 つの RPC を実装1:
gnoi.file.File.Remove: target ファイル削除(現状はconfig_db.json限定)gnoi.factory_reset.FactoryReset.Start: 工場出荷状態に戻す
バックエンドは python ベースの host service(プラグイン構成)に DBUS で要求 を投げる形を取る。詳細は SONiC GNMI Server Interface Design と Docker to Host communication を参照1。
全体構成¶
flowchart LR
CL[gNOI client] -->|gRPC :9339<br/>authn/authz| UMF[gNMI/UMF サーバ<br/>telemetry container]
UMF --> FE[GNOI*Server]
FE --> TR[transformer<br/>FileRemove / FactoryReset]
TR -->|HostQuery| DBUS[(DBUS)]
DBUS --> HS[SONiC Host Service<br/>plugin: infra_host / gnoi_reset]
HS --> OS[Linux host]
- gNOI と gNMI は 同じ TCP 9339 で受ける
- container(telemetry)→ host 到達は DBUS + host service
- 危険な操作(factory reset / ファイル削除)は host 側で実行
File.Remove¶
protobuf(openconfig/gnoi/file):
service File { rpc Remove(RemoveRequest) returns (RemoveResponse) {} }
message RemoveRequest { string remote_file = 1; }
message RemoveResponse {}
SONiC 実装の特徴1:
config_db.jsonのみ削除可。host service backend でrm ..../etc/sonic/config_db.jsonを文字列マッチで検証、それ以外は失敗- FE (
GNOIFileServer.Remove) はtransformer.FileRemove(remote_file)を呼ぶ transformer.FileRemoveはHostQuery("infra_host.exec_cmd", "rm "+remoteFile)で DBUS 投入fileMuロックで同時実行を抑制
sequenceDiagram
participant CL as Client
participant SV as GNOIFileServer
participant TR as transformer
participant HS as host service<br/>infra_host
CL->>SV: Remove(remote_file=/etc/sonic/config_db.json)
SV->>TR: FileRemove(remote_file)
TR->>HS: HostQuery(exec_cmd, "rm ...config_db.json")
HS->>HS: string match
alt match OK
HS->>HS: rm 実行
HS-->>SV: ok → RemoveResponse{}
else 不一致
HS-->>SV: error → codes.Internal
end
注: 「
config_db.json以外を消させない」を string match で守るのは脆く見える。実装側で../系の traversal が抜けないか要確認(remove_test.goで../../etc/passwdリジェクトは UT 済)。
FactoryReset.Start¶
protobuf 抜粋(openconfig/gnoi/factory_reset):
message StartRequest {
bool factory_os = 1; // OS を出荷時イメージにロールバック
bool zero_fill = 2; // 永続ストレージをゼロ埋め
bool retain_certs = 3; // 証明書を保持
}
message StartResponse {
oneof response { ResetSuccess reset_success = 1; ResetError reset_error = 2; }
}
Start は storage / configuration / logs / certificates / licenses を全消去 し出荷状態で再起動する強烈な操作で、retain_certs だけ証明書を残す等の例外を許す1。
sequenceDiagram
participant CL as Client
participant SV as GNOIFactoryResetServer
participant TR as transformer
participant HS as host service<br/>gnoi_reset
CL->>SV: Start(StartRequest)
SV->>TR: factoryReset(protojson)
TR->>HS: HostQuery(gnoi_reset.issue_reset, jsonReq)
HS->>HS: storage / config / logs / certs / licenses クリーン
HS-->>SV: jsonResp (ResetSuccess or ResetError)
ポイント1:
- FE はリクエストを JSON シリアライズ して host に渡す(応答も JSON)
resetMuロックで同時実行を抑制- 未対応フラグ指定時は
INVALID_ARGUMENT+ResetError(gNOI 仕様準拠)
CLI / 設定例¶
| Command | 用途 |
|---|---|
gnoi_client ... |
UMF が提供する gNOI 呼び出し用クライアント |
gnoi_client file remove --remote_file /etc/sonic/config_db.json
gnoi_client factory_reset start --factory_os=false --zero_fill=false --retain_certs=true
専用 CONFIG_DB / YANG は無く、gNMI 認証認可・証明書配置などの既存 telemetry 経路を再利用する。SAI / Warmboot / Fastboot への影響なし1。
制限事項¶
File.Removeは/etc/sonic/config_db.json限定- path 検証が string match ベースで
../系の抜け道に注意(UT で代表ケースはカバー) FactoryReset.Startは デバイス状態を破壊する重操作。誤実行防止に RBAC で role を絞ること- 各フラグの対応はベンダ依存。未対応時
INVALID_ARGUMENT - 同時実行は
fileMu/resetMuで抑制
干渉する機能¶
- gNMI / telemetry: 同 9339 ポート・同認証経路(証明書 / RBAC 共通)
- SONiC Host Service / DBUS: docker → host 通信の汎用機構を共有
config save/config reload:config_db.json削除直後の再生成・初期化と整合させる- gNMI 用証明書:
retain_certs=trueで残る範囲(/etc/sonic/telemetry/...含むか)が運用上の要点
トラブルシューティング¶
RemoveがINTERNAL→ host service ログでinfra_host.exec_cmdの string match 結果確認FactoryResetがINVALID_ARGUMENT→ 未対応フラグ(zero_fill等)を指定していないか- DBUS 応答なし → SONiC Host Service の稼働と container↔host の DBUS proxy 設定確認
コマンド例: gNOI File / FactoryReset 確認¶
下記コマンドで関連する CONFIG_DB / APP_DB / STATE_DB と CLI 出力・syslog を 突き合わせ、HLD 記載の挙動と現在の挙動が一致しているか確認できる。
# gNOI File.Get / FactoryReset を gnoic で叩く
gnoic -a 127.0.0.1:8080 --skip-verify file stat --file /etc/sonic/config_db.json
gnoic -a 127.0.0.1:8080 --skip-verify factory-reset start --factory-os --zero-fill
docker logs gnmi 2>&1 | tail -30
コマンド例: gNOI File / FactoryReset 確認¶
下記コマンドで関連する CONFIG_DB / APP_DB / STATE_DB と CLI 出力・syslog を 突き合わせ、HLD 記載の挙動と現在の挙動が一致しているか確認できる。
# gNOI File.Get / FactoryReset を gnoic で叩く
gnoic -a 127.0.0.1:8080 --skip-verify file stat --file /etc/sonic/config_db.json
gnoic -a 127.0.0.1:8080 --skip-verify factory-reset start --factory-os --zero-fill
docker logs gnmi 2>&1 | tail -30
引用元¶
関連ページ¶
- Topic: gNMI / OpenConfig - gNOI / gNSI
- HLD: gNOI System APIs
- HLD: gNOI OS APIs
- HLD: gNOI healthz API
- HLD: SONiC gNMI Server インタフェース設計
運用入口¶
この HLD に対応する運用面の入口(CLI / CONFIG_DB / YANG / Runbook)を以下にまとめる。
関連 CLI¶
gnoi_client