Skip to content

Commit 44f7928

Browse files
add method to retrieve the IP address for procmox runners
1 parent 125c7d3 commit 44f7928

2 files changed

Lines changed: 113 additions & 3 deletions

File tree

ApiController.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using GithubActionsOrchestrator.Database;
22
using GithubActionsOrchestrator.Models;
3+
using GithubActionsOrchestrator.CloudControllers;
34
using Microsoft.AspNetCore.Mvc;
45
using Microsoft.EntityFrameworkCore;
56
using Npgsql.Internal;
@@ -69,7 +70,7 @@ public async Task<IResult> GetPotentialRunners(int jobId)
6970
}
7071

7172
[Route("provision/{provisionId}")]
72-
public async Task<IResult> GetProvisionScript(string provisionId,[FromHeader(Name = "X-API-KEY")] string apiKey)
73+
public async Task<IResult> GetProvisionScript(string provisionId,[FromHeader(Name = "X-API-KEY")] string apiKey, [FromServices] IServiceProvider serviceProvider)
7374
{
7475
/*// Check if API key is provided
7576
if (string.IsNullOrEmpty(apiKey))
@@ -87,6 +88,29 @@ public async Task<IResult> GetProvisionScript(string provisionId,[FromHeader(Nam
8788
var runner = await db.Runners.Where(x => x.ProvisionId.ToLower() == provisionId).FirstOrDefaultAsync();
8889
if(runner == null)
8990
return Results.NotFound();
91+
92+
// Update the runner's IP address if using Proxmox and IP is still dummy
93+
if (runner.Cloud == "pve" && (string.IsNullOrEmpty(runner.IPv4) || runner.IPv4 == "0.0.0.0/0"))
94+
{
95+
try
96+
{
97+
var proxmoxController = serviceProvider.GetService<ProxmoxCloudController>();
98+
if (proxmoxController != null)
99+
{
100+
var actualIpAddress = await proxmoxController.UpdateRunnerIpAddressAsync(runner.CloudServerId);
101+
if (actualIpAddress != "0.0.0.0/0")
102+
{
103+
runner.IPv4 = actualIpAddress;
104+
await db.SaveChangesAsync();
105+
}
106+
}
107+
}
108+
catch (Exception ex)
109+
{
110+
// Log the error but don't fail the provision request
111+
Console.WriteLine($"Failed to update IP for runner {runner.RunnerId}: {ex.Message}");
112+
}
113+
}
90114

91115
return Results.Content(runner.ProvisionPayload);
92116

CloudControllers/ProxmoxCloudController.cs

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,93 @@ private async Task<string> WaitForTaskCompletionAsync(string taskId, string node
215215
}
216216
}
217217

218-
await Task.Delay(1000);
218+
await Task.Delay(500);
219+
}
220+
}
221+
222+
private async Task<string> GetVmIpAddressAsync(int vmId, string node, int timeoutSeconds = 120)
223+
{
224+
var endTime = DateTime.UtcNow.AddSeconds(timeoutSeconds);
225+
226+
while (DateTime.UtcNow < endTime)
227+
{
228+
try
229+
{
230+
var response = await MakeApiCallAsync($"/nodes/{node}/qemu/{vmId}/agent/network-get-interfaces");
231+
var networkJson = JsonSerializer.Deserialize<JsonElement>(response);
232+
233+
if (networkJson.TryGetProperty("data", out var dataElement) && dataElement.TryGetProperty("result", out var interfaces))
234+
{
235+
foreach (var iface in interfaces.EnumerateArray())
236+
{
237+
if (iface.TryGetProperty("name", out var nameElement) &&
238+
nameElement.GetString() != "lo" &&
239+
iface.TryGetProperty("ip-addresses", out var ipAddresses))
240+
{
241+
foreach (var ipAddr in ipAddresses.EnumerateArray())
242+
{
243+
if (ipAddr.TryGetProperty("ip-address-type", out var typeElement) &&
244+
typeElement.GetString() == "ipv4" &&
245+
ipAddr.TryGetProperty("ip-address", out var ipElement))
246+
{
247+
var ip = ipElement.GetString();
248+
if (!ip.StartsWith("169.254.") && !ip.StartsWith("127."))
249+
{
250+
_logger.LogInformation($"Retrieved IP address for VM {vmId}: {ip}");
251+
return ip;
252+
}
253+
}
254+
}
255+
}
256+
}
257+
}
258+
}
259+
catch (Exception ex)
260+
{
261+
_logger.LogDebug($"Failed to get IP for VM {vmId}, retrying... Error: {ex.Message}");
262+
}
263+
264+
await Task.Delay(3000);
265+
}
266+
267+
_logger.LogWarning($"Timeout waiting for IP address for VM {vmId}, falling back to dummy IP");
268+
return "0.0.0.0/0";
269+
}
270+
271+
public async Task<string> UpdateRunnerIpAddressAsync(long cloudServerId)
272+
{
273+
await _semaphore.WaitAsync();
274+
try
275+
{
276+
var resourcesResponse = await MakeApiCallAsync("/cluster/resources?type=vm");
277+
var resourcesJson = JsonSerializer.Deserialize<JsonElement>(resourcesResponse);
278+
279+
string selectedNode = null;
280+
281+
if (resourcesJson.TryGetProperty("data", out var dataArray))
282+
{
283+
foreach (var resource in dataArray.EnumerateArray())
284+
{
285+
if (resource.TryGetProperty("vmid", out var vmidElement) &&
286+
vmidElement.GetInt32() == cloudServerId)
287+
{
288+
selectedNode = resource.GetProperty("node").GetString();
289+
break;
290+
}
291+
}
292+
}
293+
294+
if (selectedNode == null)
295+
{
296+
_logger.LogWarning($"Unable to find VM with ID {cloudServerId} in Proxmox for IP update");
297+
return "0.0.0.0/0";
298+
}
299+
300+
return await GetVmIpAddressAsync((int)cloudServerId, selectedNode);
301+
}
302+
finally
303+
{
304+
_semaphore.Release();
219305
}
220306
}
221307

@@ -230,7 +316,7 @@ public async Task<Machine> CreateNewRunner(string arch, string size, string runn
230316
await _semaphore.WaitAsync();
231317
string macaddress = string.Empty;
232318
int newVmId;
233-
319+
234320
try
235321
{
236322
string selectedNode = _mainNode;

0 commit comments

Comments
 (0)