5.8.0バージョンのHordeにアップグレード後、Horde Agent自動アップグレードが無限に実行されてしまう

再現手順にも記載しておりますが、5.8.0以降のHorde Agentでは.NET 10が必要となっています。

そして、Horde ServerにEnrollmentしているHorde Agentはバイナリだけ自動アップデートされますが

その際に、.NET 10が入っていないPCにおいては以下のようなアップグレードを試みるプロセスがループされます。

=== 中略 ===
[18:18:01 inf] Adding lease *******************
[18:18:01 inf] Handling lease ****************: type.googleapis.com/UpgradeTask
[18:18:01 inf] Setting log ***************** tail = -1, data = 0 bytes, 0 lines ('')
[18:18:01 inf] Writing log data: ************, -1, 0 bytes
[18:18:05 dbg] Written ***************/*************** (direct)
[18:18:05 inf] Updating log *************** to line 1, target *******************/******************
[18:18:05 inf] Disposing json log task
[18:18:05 inf] Cancelling long poll from client side (complete)
[18:18:05 inf] Log ************ tail next = -1
[18:18:05 inf] Finishing log tail task
[18:18:05 inf] Transitioning lease ********** to Completed, outcome=Success
[18:18:05 inf] Lease ***************** is setting session result to RunCallback
[18:18:05 inf] Session termination requested (result: RunCallback)
[18:18:05 inf] Querying agent capabilities... (may take up to 30 seconds)
[18:18:05 inf] Agent capabilities queried in 1 ms
[18:18:05 inf] Agent status is stopped; returning from session update loop with result Outcome=RunCallback Reason=Completed
[18:18:05 inf] Launching: dotnet D:\Horde_Agent\Upgrade\Extracted\HordeAgent.dll Service Upgrade -ProcessId=46408 -TargetDir="C:\Program Files\Epic Games\Horde\Agent" -Arguments=
You must install or update .NET to run this application.
 
App: D:\Horde_Agent\Upgrade\Extracted\HordeAgent.dll
Architecture: x64
Framework: 'Microsoft.NETCore.App', version '10.0.0' (x64)
.NET location: C:\Program Files\dotnet\
 
The following frameworks were found:
 6.0.28 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
 7.0.7 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
 8.0.12 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
 9.0.5 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
 
Learn more:
https://aka.ms/dotnet/app-launch-failed
 
To install missing framework, download:
https://aka.ms/dotnet-core-applaunch?framework=Microsoft.NETCore.App&framework_version=10.0.0&arch=x64&rid=win-x64&os=win10
[18:18:05 inf] Upgrade did not terminate initiating process; reconnecting to server...
[18:18:05 inf] WorkingDir: D:\Horde_Agent
=== 5分置きにこの無限ループ ===

これは.NET 10が必要になったことの他に、以下修正の影響もありそうです。

* Make upgrade of Windows agent more robust with retry logic
 
 Add retry for file deletion and move operations during agent self-upgrade to handle lingering file locks after service stop. (50350263)

ここまでは良いのですが、問題はこのエラーのわかりにくさにあります。

これらがわかっていると、Horde DashboardのAgent一覧画面からバージョンを見ることで対応可能なのですが

Dashboard上のAgent Leasesログには Successログと以下の内容しか書いてありません。

Upgrading from 5.7.4-0 to horde-agent:5.8.0-54390005

Horde Agent自体をコマンドプロンプトから起動していたりしないとエラー内容に気付きにくいため

Requirementを満たしておらず、該当バージョンにUpgrade出来ていなかった場合に

Agent Leasesで失敗扱いもしくはログからわかるようにしてほしいです。

その他、できれば.NET 10も入るようにしていただいたり、

アップグレードプロセスにも試行回数上限を設けていただくのも検討していただけないでしょうか?

以上、よろしくお願いいたします。

[Attachment Removed]

再現手順

  1. 5.7.4以前のHorde Server環境にて、.NET 10をインストールしていないHorde Agentをenrollmentする
  2. Horde Serverを5.8.0にアップグレードする
  3. .NET 10をインストールしていないHorde Agentに対し、5分毎でUpgradeプロセスを実行される
    [Attachment Removed]

お世話になっております。

ご報告いただいた事象についてエンジンソース(//UE5/Release-5.8)を確認いたしました。ご指摘の内容はいずれも正確で、コード上の実装から再現性のある動作であることを確認しております。以下、原因の詳細と回避策をご案内いたします。

  • .NET10要件について

Engine/Source/Programs/Horde/Directory.Build.propsにて全Hordeプロジェクトの

TargetFrameworkがnet10.0に設定されており、5.8のHordeAgentはframework-dependentビルドの場合.NET10ランタイムが必須となります。

  • 5分毎のループについて

サーバー側のUpgradeTaskSource.AssignLeaseAsync(Plugins/Compute/HordeServer.Compute/Tasks/UpgradeTaskSource.cs)は、AgentのバージョンがデプロイメントのバージョンとN一致しない限りUpgradeTaskを再発行し続ける実装となっております。同一バージョンへの直近のアップグレード試行から5分間(TimeSpan.FromMinutes(5.0))のクールダウンのみが設けられており、試行回数の上限は存在しません。ご観測の5分間隔のループはこの実装に起因します。

  • AgentLeasesでSuccessと表示される件について

Agent側のUpgradeHandler(HordeAgent/Leases/Handlers/UpgradeHandler.cs)では、新バージョンのダウンロードと展開が完了した時点でLeaseResult(SessionResult)を返しますが、このコンストラクタはOutcomeをLeaseOutcome.Successに固定しています。つまり新Agentプロセスの起動前にリースはSuccessとして完了扱いとなります。その後のRunUpgradeAsyncでは子プロセス(dotnet HordeAgent.dll Service Upgrade)のstdout/stderrをリダイレクトしておらず、終了コードも取得のみで判定に使用していないため、.NETランタイム不足のエラーはサーバーログに一切送信されず、ローカルコンソールでのみ確認可能となっております。エラーがDashboardから視認できないというご指摘はまさにこの実装によるものです。

  • CL50350263の影響について

ご言及のリトライ処理はServiceUpgrade.cs、すなわち新Agentプロセス側のファイル削除・移動処理に対するものです。本事象ではランタイム不足により新Agentプロセス自体が起動に失敗するため、当該コードは実行されておらず、今回のループの要因ではございません。

回避策

・Agentマシンに.NET10Runtime(x64)をインストールいただければ、次回のアップグレードサイクルで正常に完了します。

・ループを一時的に停止する場合は、該当Agentの自動アップデートを無効化するか、サーバー側のComputeプラグイン設定でEnableUpgradeTasks=false(デフォルトtrue)を設定してください。

いただいた3点のご要望(アップグレード失敗のAgentLeasesへの反映、試行回数上限の導入、ランタイム同梱もしくはself-containedビルドの配布)はいずれも妥当なものと考えており、上記の調査結果と併せて開発チームに要望として報告いたします。進展がありましたら本スレッドにてお知らせいたします。

お手数ですが、よろしくお願いします。

[Attachment Removed]

詳細なご回答をいただきありがとうございます!

CL50350263については今回の要因ではなかったとのことで失礼いたしました。

> サーバー側のComputeプラグイン設定でEnableUpgradeTasks=false(デフォルトtrue)を設定してください。

こちら当方で認知できていなかったので情報助かります!

また、開発フィームに要望としてフィードバックいただくとのことでありがとうございます…!

引き続きよろしくお願いいたします。

[Attachment Removed]