Hi Julian,
We have a buildgraph that calls into RunJobsOnAllAgents.cs. Our agent isn’t running as a service but rather running the exe via task scheduler but don’t see how that could affect things
`<?xml version='1.0' ?>
`
`using UnrealBuildBase;
using Newtonsoft.Json;
using System.Net.Http;
using System;
using System.Collections.Generic;
using Gauntlet;
using System.Text;
namespace AutomationTool.Tasks
{
///
/// Run given job on all agents in given pool
///
[Help(“Run given job on all agents in given pool”)]
[ParamHelp(“targetJobId=”, “Job id to run”)]
[ParamHelp(“agentPool=”, “Pool to run job against”)]
[ParamHelp(“hordeServerUrl=”, “Horde Server URL”)]
public class RunJobOnAllAgents : BuildCommand
{
///
/// Entrance point for command
///
///
public override ExitCode Execute()
{
string targetJobId = ParseParamValue(“targetJobId”, String.Empty);
string agentPool = ParseParamValue(“agentPool”, String.Empty);
string hordeServerUrl = ParseParamValue(“hordeServerUrl”, String.Empty);
Dictionary<string, string> requiredArgs = new Dictionary<string, string>
{
{ nameof(targetJobId), targetJobId },
{ nameof(agentPool), agentPool },
{ nameof(hordeServerUrl), hordeServerUrl },
};
if (hordeServerUrl.EndsWith(“/”, StringComparison.OrdinalIgnoreCase))
{
hordeServerUrl = hordeServerUrl.TrimEnd(‘/’);
}
foreach (KeyValuePair<string, string> kvp in requiredArgs)
{
if (String.IsNullOrEmpty(kvp.Value))
{
Log.Error($“Error: Missing required arg ‘{kvp.Key}’”);
return ExitCode.Error_Arguments;
}
}
using (HttpClient client = new HttpClient())
{
client.Timeout = TimeSpan.FromMinutes(30);
client.DefaultRequestHeaders.ConnectionClose = true;
string token = Environment.GetEnvironmentVariable(“UE_HORDE_TOKEN”);
if (String.IsNullOrEmpty(token))
{
Log.Error(“Error: Couldn’t find Horde token”);
return ExitCode.Error_Unknown;
}
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(“Bearer”, token);
try
{
string agentsUrl = $“{hordeServerUrl}/api/v1/agents?poolId={agentPool}&includeDeleted=false&invalidateCache=false”;
HttpResponseMessage agentsResponse = client.GetAsync(agentsUrl).GetAwaiter().GetResult();
if (!agentsResponse.IsSuccessStatusCode)
{
string errorContent = agentsResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();
Log.Error($“Error fetching agents: {agentsResponse.StatusCode} - {agentsResponse.ReasonPhrase}”);
Log.Error($“Error details: {errorContent}”);
return ExitCode.Error_Unknown;
}
string agentsJson = agentsResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();
List<Dictionary<string, object>> agentsList = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(agentsJson);
Log.Info($“Found {agentsList.Count} agents in pool {agentPool}”);
string jobsUrl = $“{hordeServerUrl}/api/v1/jobs”;
string streamId = Environment.GetEnvironmentVariable(“UE_HORDE_STREAMID”);
string change = Environment.GetEnvironmentVariable(“uebp_CL”);
foreach (Dictionary<string, object> agent in agentsList)
{
string agentName = agent[“name”].ToString();
bool enabled = Convert.ToBoolean(agent[“enabled”]);
bool statusOk = agent[“status”].ToString() == “Ok”;
bool online = Convert.ToBoolean(agent[“online”]);
Log.Info($“agentName: {agentName}, enabled: {enabled}, statusOk: {statusOk}, online: {online}”);
if (!enabled || !statusOk || !online)
{
continue;
}
var jobPayload = new
{
streamId = streamId,
templateId = targetJobId,
priority = “Normal”,
parameters = new { },
updateIssues = false,
selectedAgent = agentName,
change = Int32.Parse(change)
};
string jobJson = JsonConvert.SerializeObject(jobPayload);
StringContent content = new StringContent(jobJson, Encoding.UTF8, “application/json”);
Log.Info($“Sending POST Url: {jobsUrl}, payload: {jobJson}”);
HttpResponseMessage jobResponse = client.PostAsync(jobsUrl, content).GetAwaiter().GetResult();
if (!jobResponse.IsSuccessStatusCode)
{
string errorContent = jobResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();
Log.Error($“Error posting job for agent {agentName}: {jobResponse.StatusCode} - {jobResponse.ReasonPhrase}”);
Log.Error($“Error details: {errorContent}”);
Log.Error($“Request payload: {jobJson}”);
}
else
{
Log.Info($“Posted job for agent {agentName}”);
}
content.Dispose();
}
return ExitCode.Success;
}
catch (Exception e)
{
Log.Error($“Unexpected Error: {e.Message}”);
return ExitCode.Error_Unknown;
}
finally
{
client.Dispose();
}
}
}
}
}`