summaryrefslogtreecommitdiff
path: root/src/marlin.web/Controllers/Api/DispatchController.cs
diff options
context:
space:
mode:
authorMelodi <62381002+Melodi17@users.noreply.github.com>2026-10-27 23:04:59 +1000
committerMelodi <62381002+Melodi17@users.noreply.github.com>2026-10-27 23:04:59 +1000
commitecd5f5d13936dd097b12766cb95a568ad5b073a9 (patch)
treef360b08e656a98faca4f2b9f10dc44602e6ca289 /src/marlin.web/Controllers/Api/DispatchController.cs
parent88ee626cb3686dc176cd7911b073c4e65fa54d34 (diff)
feat: lots of stuff
Diffstat (limited to 'src/marlin.web/Controllers/Api/DispatchController.cs')
-rw-r--r--src/marlin.web/Controllers/Api/DispatchController.cs69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/marlin.web/Controllers/Api/DispatchController.cs b/src/marlin.web/Controllers/Api/DispatchController.cs
new file mode 100644
index 0000000..076c4dd
--- /dev/null
+++ b/src/marlin.web/Controllers/Api/DispatchController.cs
@@ -0,0 +1,69 @@
+namespace marlin.web.Controllers.Api;
+
+using marlin.core.models;
+using marlin.core.util;
+using marlin.web.Data;
+using marlin.web.Models;
+using marlin.web.Util;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+
+[Route("api/dispatch")]
+[ApiController]
+[Authorize(Policy = "Agent")]
+public class DispatchController(ApplicationDbContext dbContext) : ControllerBase
+{
+ [HttpPost("handshake")]
+ public async Task<ActionResult<AgentConfiguration>> Handshake(AgentStatus status, CancellationToken ct)
+ {
+ var agentId = this.User.RequireAgentId();
+
+ var agent = await dbContext.Agents
+ .FirstAsync(x => x.Id == agentId, ct);
+
+ foreach (var capability in status.CapabilitySet.Items)
+ agent.Capabilities.Items[capability.Key] = capability.Value;
+
+ await dbContext.SaveChangesAsync(ct);
+
+ return new AgentConfiguration(
+ Name: agent.Name,
+ MaxConcurrentJobs: agent.MaxConcurrentJobs
+ );
+ }
+
+ [HttpGet("queue")]
+ public async Task<ActionResult<DispatchJob?>> Queue(CancellationToken ct)
+ {
+ var agentId = this.User.RequireAgentId();
+
+ var nextJob = await dbContext
+ .Jobs
+ .Include(x => x.Source)
+ .Include(x => x.Branch)
+ .Include(x => x.Commit)
+ .Where(x => x.Status == JobStatus.Pending && x.AgentId == null)
+ .OrderBy(x => x.CreatedAt)
+ .FirstOrDefaultAsync(ct);
+
+ if (nextJob == null)
+ return (DispatchJob?)null;
+
+ string claimToken = SecureTokenGenerator.CreateClaimToken();
+ nextJob.ClaimToken = claimToken;
+ nextJob.AgentId = agentId;
+
+ await dbContext.SaveChangesAsync(ct);
+
+ return new DispatchJob(
+ Id: nextJob.Id,
+ Token: claimToken,
+ Vcs: nextJob.Source.UpstreamUrl,
+ Ref: nextJob.Branch.Name,
+ Commit: nextJob.Commit.Hash,
+ Recipe: nextJob.Recipe
+ );
+ }
+}
+