Add OPCode_notify handler in go_push_handler top-level switch
(not inside handlePush) to receive resource value updates from
the controller via xce_notify_data_t/schedUpdateResvals.
- Add 8 CGO union accessors for xce_val_t (which, i32, i64,
u32, u64, fval, str, bool) since CGO cannot access union fields
- Add handleNotifyData() dispatching NotifyData_data_schedUpdateResvals
events, iterating xce_resval_list_t and calling cResvalToDistribution
- Add cResvalToDistribution in convert.go with 7 separate switch
cases for Value_u_* union discriminants (no combining i32/i64)
- Add rawResvalData + rawResvalToDistribution pure-Go version
in convert_pure.go for testability without CGO
- Add 10 TDD tests covering all 7 value types, nil val guard,
unknown discriminant, and boolean false
- All 42 backend tests passing
Add four function stubs to backend/stub.go for the !cgo build path:
- StartHeartbeat(ctx context.Context) — no-op (heartbeat not available)
- SetHeartbeatInterval(secs int) — no-op (interval update not available)
- EvalSelectForHost(hostname, selectExpr string) error — returns errNoCGO
- Cleanup() — no-op (no C resources to release without CGO)
TDD: four tests in stub_funcs_test.go verify stubs behave correctly
(no-op functions don't panic, error stubs return errNoCGO). All backend
tests passing.
Routes and RBAC entries already existed from prior P0-2a/2b work. This
adds three TDD tests that lock down the RBAC invariants:
- TestRBAC_HostControl_ClusterAdminOnly: cluster_admin has host:control
with domain=all; basic_user must NOT have host:control
- TestRBAC_HostView_BasicUserHasAccess: basic_user has host:view with
domain=all; queue_admin must NOT have host:view
- TestRBAC_HostControl_DomainTypeIsAll: cluster_admin host:control
domain type must be "all" (not hostgroup)
All apiserver tests passing.
Wires the remaining cluster_config_t data into the notification pipeline:
- dispatchConfigPush() extracted as a pure-Go helper (CGO-free, testable)
that drives OnQueueUpdated, OnResourceUpdated, OnHostConfigUpdated, and
OnClusterUpdated from a single config push event
- handleConfigPush() delegates to dispatchConfigPush via the new helper,
eliminating the previous inline loops
- OnHostConfigUpdated and OnClusterUpdated added to NotificationHandler
interface and implemented with partial-merge semantics in DefaultHandler
- rawHostConfigData/rawHostConfigToModel and rawClusterData/rawClusterToModel
added to convert_pure.go with their CGO extraction counterparts in convert.go
Safety fixes from code review:
- OnHostUpdated, OnHostConfigUpdated, OnClusterUpdated now copy *incoming to
a local merged value before mutation, closing the TOCTOU window between
store.Get and store.Put under concurrent pushes
- cClusterConfQueues and cClusterConfResources gain nil-pointer guards
matching the existing guard in cClusterConfHostConfigs
- handleConfigPush gains an explicit gHandler nil check
- cClusterConfToClusterInfo returns nil on empty clustername (prevents phantom
empty-key write to store.Clusters); handleConfigPush logs a warning when nil
- 36 unit tests passing (CGO_ENABLED=0)