update documents
This commit is contained in:
parent
c705cadadc
commit
d70bf6a402
51 changed files with 995 additions and 1997 deletions
|
|
@ -8,9 +8,9 @@ xcecli (Go/Cobra) ──REST──► apiserver (Go/Gin) ──CGO──► C da
|
|||
↑↑↑ all linked against libxce (src/lib/)
|
||||
```
|
||||
|
||||
Request path inside apiserver: `Gin Router → Middleware (CORS/RateLimit/IPWhitelist/JWT) → RBAC Check → Controller → Services → In-Memory Store`
|
||||
Request path inside apiserver: `Gin Router → Middleware (WhitelistURL → WhitelistIP → RateLimit → JWT → CORS) → RBAC Check → Controller → Services → In-Memory Store`
|
||||
|
||||
All controller state is in-memory, seeded at startup from YAML config. No persistent database in the API tier. C daemons communicate via TCP using a custom messaging layer: iomgr (epoll-based I/O loop), vtaskmgr (thread pool for packet dispatch), and xce_request/xce_reply for non-blocking send/receive. WAL + checkpoint provide persistence at the controller level.
|
||||
All controller state is in-memory. No persistent database in the API tier; job/queue/host state is pushed live into the in-memory stores from the C controller backend over CGO (see Key Technical Decision #2), not loaded from a file. C daemons communicate via TCP using a custom messaging layer: iomgr (epoll-based I/O loop), vtaskmgr (thread pool for packet dispatch), and xce_request/xce_reply for non-blocking send/receive. WAL + checkpoint provide persistence at the controller level.
|
||||
|
||||
## Core Technologies
|
||||
|
||||
|
|
@ -52,18 +52,20 @@ nix build .#xcecli # CLI only
|
|||
### Controller Pattern (Go)
|
||||
|
||||
```go
|
||||
// Struct: {Resource}Controller
|
||||
type JobController struct { ... }
|
||||
// Struct: {Resource}Controller (typically an empty struct{})
|
||||
type JobController struct{}
|
||||
|
||||
// Handler: {Action}{Resource}
|
||||
func (c JobController) SubmitJob(ctx *gin.Context) {
|
||||
func (j JobController) CreateJob(ctx *gin.Context) {
|
||||
// Validate input
|
||||
req, err := preCheckSubmitJobRequest(ctx)
|
||||
if err != nil { ReturnError(ctx, code, err, nil); return }
|
||||
var req models.JobSubmitRequest
|
||||
if err := utils.BindJSONStrict(ctx, &req); err != nil { ReturnError(ctx, code, err.Error(), nil); return }
|
||||
parsedIndices, err := preCheckJobRequest(&req)
|
||||
if err != nil { ReturnError(ctx, code, err.Error(), nil); return }
|
||||
|
||||
// Business logic
|
||||
result, err := c.svc.Submit(req)
|
||||
if err != nil { ReturnError(ctx, code, err, nil); return }
|
||||
// Business logic — package-level services function, not a controller field
|
||||
err = services.SubmitJob(&newJob, arraySize)
|
||||
if err != nil { ReturnError(ctx, code, err.Error(), nil); return }
|
||||
|
||||
ReturnSuccess(ctx, code, "submitted", result)
|
||||
}
|
||||
|
|
@ -86,15 +88,15 @@ Early return on every error. Log with zap fields before returning.
|
|||
|
||||
### Auth and RBAC
|
||||
|
||||
- Auth backend set in `config/auth.yaml`. Supports: configfile, LDAP, OAuth2, PAM.
|
||||
- Permissions as `"action:scope"` strings: `"job:view:self"`, `"queue:submit:all"`.
|
||||
- Auth backend set in `config/auth.yaml` (`provider: config_file | pam | ldap | oauth2`). Only `config_file` and `pam` (Linux + CGO) are functional; `ldap` and `oauth2` are documented as future/stub providers whose `Authenticate()` always returns a "not yet implemented" error.
|
||||
- Permissions are a plain action string (e.g. `"job:view"`, `"queue:submit"`) paired with a separate structured `domain` list (e.g. `{type: self}`, `{type: all}`) in `rbac.yaml` — not a combined `"action:scope"` string. `controllers.RequirePermission()` checks the action string only; domain/scope is evaluated separately.
|
||||
- RBAC loaded from `config/rbac.yaml`, enforced by `controllers.RequirePermission()` middleware.
|
||||
|
||||
## Key Technical Decisions
|
||||
|
||||
1. **No Go workspace** — `apiserver` and `xcecli` are independent modules; changes to shared types require updating both.
|
||||
2. **In-memory API state** — no database in Go tier; state loaded from YAML at startup via `store.LoadBuiltinData()`.
|
||||
2. **In-memory API state** — no database in Go tier; `store.InitStores()` allocates empty per-resource stores at startup, and job/queue/host/etc. state is then pushed in live from the C controller backend over CGO (`backend.RegisterToBackend()` + `backend.StartNotificationListener()` in `cmd/main.go`). Only RBAC (`config/rbac.yaml`) and auth (`config/auth.yaml`) are actually loaded from YAML at startup.
|
||||
3. **CGO bridge** — `backend/` package wraps C library calls; unit tests run `CGO_ENABLED=0`, backend tests need `CGO_ENABLED=1` inside nix dev shell.
|
||||
4. **Swagger-first API docs** — `swaggo/swag` annotations on handlers; docs served at runtime by Gin.
|
||||
5. **Structured logging** — every log entry carries context via `zap.String()`, `zap.Error()`. Never use `fmt.Println` for operational output.
|
||||
6. **Single-writer HA** — controller is always one active primary; standby election via Raft-style consensus (term-based voting, freshness gates) in the `src/lib/raft/` shared module (`raft.c`/`raft.h`), with the single-writer constraint avoiding Raft log replication complexity.
|
||||
6. **Single-writer HA with full Raft log replication** — controller is always one active primary; standby election and log replication use a Raft protocol (term-based voting, freshness gates, `AppendEntries` request/reply, per-peer `next_index[]`/`match_index[]` progress vectors, `(term,index)` log matching/truncation, commit-index advance) implemented in the `src/lib/raft/` shared module (`raft.c`/`raft.h`) and validated by the `raft-log-replication`, `raft-commit-safety`, `raft-ha-core-safety`, and `ha-term-safety` specs.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue