kanade-agent 自身のアップデート
agent の self-update は唯一 OBJECT_APP_PACKAGES + script_object ジョブを 使わない コンポーネントです。agent は ssh なしで現在実行中の自分自身のバイナリを差し替える必要があり、汎用 install ジョブよりタイトなループのため専用の仕組みを持っています。
仕組み
| バケット / キー | 用途 |
|---|---|
OBJECT_AGENT_RELEASES | agent バイナリ。キーは <version>。rollout watcher が agent アップデートだけに反応するように、OBJECT_APP_PACKAGES とは別バケット。 |
agent_config.<scope>.target_version | 各スコープ (global / グループ / pc) があるべきバージョン。agent の self_update ループがこれを watch しています。 |
フロー:
1. agent.self_update watches agent_config for target_version
2. If target_version != my agent_version:
a. Pull `OBJECT_AGENT_RELEASES/<target_version>` to <exe>.new
b. Sha-verify against the bucket's recorded digest
c. Atomic swap: <exe> ← <exe>.new (via SCM stop/start)
d. New binary boots, watcher arms again, loop closes
rollout watcher は cold broker (ホスト再起動後に agent と broker が同時に立ち上がる、など) に耐えなければなりません。#226 以前は最初の get_object_store 呼び出しで Err(_) => return; してしまうと watcher が恒久的に死んでいて、その起動セッション中は agent が二度と self-update しませんでした。#226 以降は watcher が backoff で再試行し、broker に到達できるまであきらめません。
ステップごとの手順
1. agent をビルド
cargo build --release -p kanade-agent
出力: target/release/kanade-agent.exe。
2. publish
kanade agent publish target/release/kanade-agent.exe
CLI は PE VERSIONINFO リソースからバージョンを自動抽出します — --version フラグ不要、ラベルとバイナリの不一致もあり得ません。
3. roll out
スコープを選びます。canary 1 台から:
kanade agent rollout 0.42.2 --pcs canary-01
ping で確認:
kanade ping canary-01 # agent_version should flip to 0.42.2
# within a few seconds
問題なければ範囲を広げる:
kanade agent rollout 0.42.2 --groups office --jitter 5m
# or fleet-wide
kanade agent rollout 0.42.2 --global --jitter 30m
--jitterは実際の swap タイミングをある幅で分散させ、大きな fan-out 時に全ホストの OS サービスマネージャを同時に叩かないようにします。100 台以上の fleet では推奨。
4. 確認
kanade agent current
# → target_version = 0.42.2 (global)
あとは SPA の Agents ページ (もしくは /api/agents) で fleet 全体をスポットチェック: agent_version 列は jitter + 約 30 秒の heartbeat 間隔以内に新バージョンに収束するはず。
ありがちなトラブル
| 症状 | 原因 | 対処 |
|---|---|---|
kanade agent rollout が "version not in OBJECT_AGENT_RELEASES" と言う | typo もしくはスコープ違い | kanade agent current と kanade jetstream object list agent_releases で再確認。 |
数分経っても kanade ping <host> が古いバージョンを返す | agent が self-update しなかった — watcher が死んでいる (#226 以前の agent) か、ホストが broker に到達できない | 対象ホストの %ProgramData%\Kanade\log\agent.*.log をチェック。self_update が無言なら (「checking target_version」ログがない)、agent が古すぎる; deploy-agent.ps1 で手動ブートストラップ。 |
agent が flap する: 起動するも exit_code: 1 ですぐ落ちる | このホストでは新バイナリが起動できない (config の不整合、依存欠落など)。SCM の failure-actions により再起動が試みられるが再びクラッシュする — Event Viewer に Service Control Manager のエラーが連続して記録される | ロールバック: kanade agent rollout <prev-version> --pcs <host>。次の watcher tick でホストは元のバージョンに戻ります。 |
なぜ別のバケット / スコープか?
OBJECT_APP_PACKAGES は <name>/<version> をキーにした汎用 blob ストアです。agent rollout パターンに必要なのは:
- agent の変更だけに反応する watcher (たくさんの名前が入ったバケットを poll するのではなく、特定の 1 つの KV キーを安価に watch)。
- 「既知の全バージョン」ではなくスコープごとの「現在の target」セマンティクス —
agent_config.<scope>.target_versionこそが「自分は何を動かすべきか」の答えで、agent 側で列挙する必要がない。 - operator 向け UX (
kanade agent publish/rollout) がkanade app publishとは別サブコマンドツリーに分けるに足るくらい違う。
というわけで agent は OBJECT_AGENT_RELEASES + レイヤード config KV を、他のコンポーネントは OBJECT_APP_PACKAGES + アプリ別ジョブを共有します。