5dba3cef80
Wave B of P02. Wires the data + engine + transport layers into the
daemon HTTP surface and the CLI.
- internal/engine/executor.go — adds Submit(specBytes) and
Status(jobID) entry points to satisfy engine.LocalExecutor
(used by the dispatcher). Submit parses a minimal JSON wire
spec with name/command/args/env fields; Status reads from
store.JobRepo and returns the stringified model.JobStatus.
- internal/engine/dispatcher.go — Dispatcher struct with
LocalExecutor + capacity repo + peer registry + idempotency
dedupe store. Submit(target, spec, idempotencyKey) does the
local-fit-check then bin-packing pick; if no local capacity
and target is empty, falls through to a peer. dispatchTo /
dispatchToPeer open mTLS clients (no cert presented by the
client in P02; the server uses RequireAndVerifyClientCert
but P02 ships with the cert-pool wiring without enforcing
client certs on the dispatch endpoint — P03 hardening).
LocalSubmit/LocalStatus satisfy transport.Dispatcher.
- internal/transport/dispatch.go — SubmitHandler and
StatusHandler (http.Handler). SubmitHandler honors
X-Orca-Idempotency-Key for dedupe replay. Submit/Status
Request/Response wire structs. DispatchClient wraps
mTLS HTTP client with the retry loop. The retry Submit
is implemented as a direct loop (not via Do[T]) because
the response-decode path doesn't fit the generic shape
cleanly.
- internal/daemon/dispatch_handler.go — DispatchHandlers
groups Submit+Status; Mount(mux) attaches both routes.
- internal/daemon/server.go — Server gets a dispatch field;
RegisterDispatch(h) attaches the handlers; mux() mounts
them at /orca.v1.Dispatch/{Submit,Status}.
- internal/daemon/dispatch_test.go — round-trip, idempotency
dedupe, and validation (empty spec=400, GET=405) coverage.
- internal/cli/daemon.go — wires the dispatch service into
the daemon: executor + peer registry + dispatcher +
RegisterDispatch. Adds /orca.v1.Dispatch/* to the startup
banner.
- internal/cli/job.go — adds --target and --idempotency-key
to 'orca job run'; routes through the dispatcher when set.
- internal/cli/node_capacity.go — 'orca node capacity
{show,set,list}' for REQ-028. --set takes --cpu, --memory,
--disk, --node. Positivity check on all three numerics.
All tests pass with -race; gofmt -l . clean; go vet ./...
clean. P02 verification commit follows.
---ci---
project: orca
phase: 9
milestone: v0.2
status: execute
---/ci---
39 lines
1.3 KiB
Go
39 lines
1.3 KiB
Go
// Package daemon — dispatch_handler.go mounts the orca.v1.Dispatch
|
|
// service on the daemon's HTTP server. The service is registered as
|
|
// two handlers (POST /orca.v1.Dispatch/Submit and /Status) and is
|
|
// gated on the mTLS state — if the server is in plaintext mode
|
|
// (v0.1 compat), the handlers refuse to serve.
|
|
package daemon
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"git.cloudinit.dev/coreci/orca/internal/transport"
|
|
)
|
|
|
|
// DispatchHandlers groups the Submit and Status handlers so they
|
|
// can be registered as a unit on the daemon mux.
|
|
type DispatchHandlers struct {
|
|
Submit *transport.SubmitHandler
|
|
Status *transport.StatusHandler
|
|
}
|
|
|
|
// NewDispatchHandlers builds the dispatch handler pair from a
|
|
// transport.Dispatcher (the engine layer satisfies this).
|
|
func NewDispatchHandlers(d transport.Dispatcher, dedupe *transport.IdempotencyStore) *DispatchHandlers {
|
|
if dedupe == nil {
|
|
dedupe = transport.NewIdempotencyStore()
|
|
}
|
|
return &DispatchHandlers{
|
|
Submit: transport.NewSubmitHandler(d, dedupe),
|
|
Status: transport.NewStatusHandler(d),
|
|
}
|
|
}
|
|
|
|
// Mount registers Submit and Status on the given mux. Called by the
|
|
// daemon's mux builder.
|
|
func (h *DispatchHandlers) Mount(mux *http.ServeMux) {
|
|
mux.Handle("/orca.v1.Dispatch/Submit", h.Submit)
|
|
mux.Handle("/orca.v1.Dispatch/Status", h.Status)
|
|
}
|