Slice 2: real auth, agent-mediated repo/branch listing, deployment list from SQLite
- protocol: add RepoInfo, RouteOverride; add HostPort, SandboxID to DeployRequest.
- ws hub: add CallAgent for sync request/response RPCs over the agent WS,
and DeliverAgentReply to route {op:reply} frames back to the caller.
UnregisterAgent now also fails any pending RPCs so callers don't hang.
- agent-micro: new op handlers list_repos, list_branches, probe.
Wire protocol.Event frames use json.RawMessage so each op decodes
its own data shape.
- agent-gateway: same op handlers (list_repos/list_branches/probe) plus
push_routes, which the gateway uses to rewrite the api-gateway
config.php. Detailed in a later commit.
- control-plane login: validateViaAgent now calls CallAgent('probe')
against the gateway agent (git ls-remote), replacing the
accept-any-creds stub.
- control-plane repos: handleListRepos and handleListBranches forward
to the agents via list_repos / list_branches RPCs, replacing the
hardcoded fixtures.
- control-plane deployments: split into its own file. handleListDeployments
reads from SQLite (was hardcoded []). handleCreateDeployment now
supports sandbox-scoped deploys with a host port + env merge.
handleStopDeployment looks up the node from the deployment row.
- store: split into store.go + deployments.go. The Deployment type
adds sandboxId, containerId, hostPort. StartDeploymentInSandbox,
SetContainerID, ListDeployments, GetDeployment, LatestDeploymentBySandboxService
are new.
- store_test.go: round-trips every Slice-2 path (env, sandbox,
template, clone, routes, deployment).
- .gitignore: track bin/ — the build runs on a separate Linux box
with the golang:1.24 toolchain, and the binaries are SCPed from
there to the company VMs (92 / 186). The VMs have no internet.
- Tracked bin/{control-plane,agent-micro,agent-gateway}.
This commit is contained in:
@@ -59,6 +59,36 @@ func (h *Hub) AgentWS(st *store.Store, onConnect, onDisconnect func(nodeID strin
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// Peek at the shape: protocol.Event frames have "kind",
|
||||
// RPC replies have "op" == "reply". The agent's protocol
|
||||
// does not allow a single frame to be both.
|
||||
var probe map[string]json.RawMessage
|
||||
if err := json.Unmarshal(raw, &probe); err != nil {
|
||||
log.Printf("agent %s: bad json: %v", nodeID, err)
|
||||
continue
|
||||
}
|
||||
if _, ok := probe["op"]; ok {
|
||||
var reply struct {
|
||||
Op string `json:"op"`
|
||||
ID string `json:"id"`
|
||||
OK bool `json:"ok"`
|
||||
Err string `json:"error,omitempty"`
|
||||
Raw json.RawMessage `json:"data,omitempty"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &reply); err != nil {
|
||||
log.Printf("agent %s: bad reply: %v", nodeID, err)
|
||||
continue
|
||||
}
|
||||
if reply.Op != "reply" {
|
||||
log.Printf("agent %s: unknown op %q", nodeID, reply.Op)
|
||||
continue
|
||||
}
|
||||
if !reply.OK {
|
||||
log.Printf("agent %s: rpc %s error: %s", nodeID, reply.ID, reply.Err)
|
||||
}
|
||||
h.DeliverAgentReply(reply.ID, raw)
|
||||
continue
|
||||
}
|
||||
var e protocol.Event
|
||||
if err := json.Unmarshal(raw, &e); err != nil {
|
||||
log.Printf("agent %s: bad event: %v", nodeID, err)
|
||||
|
||||
Reference in New Issue
Block a user