merge: sync Rongsong's scheduler-framework (c5b172c7..3442a57d, 781 commits)
Merge origin/scheduler-framework into merge-sf-20260903 (97 commits on ours: bug-1490/1494/1498/1509/1513/1521/1522 fixes, PEND-reason P1, scheduler-agent Phase 2, bug-924 owner-pid shim). Bookkeeping excluded per policy: .kiro/, .wolf/, CHANGES.md, reports/ (92 files dropped); .claude/ + CLAUDE.md keep ours. Key theirs-side changes absorbed: - bug-1938/1960: QUEUE_STAT_CLOSED no longer gates dispatch (closed queue refuses new submissions only; pending jobs still run) -- supersedes our QUEUE_CLOSED preason on the dispatch path; sched_queue_status_reason drops that branch - bug-1846: config push now stashes and applies between scheduling rounds (sched_stash_config/sched_apply_pending_config), applied at the same main-thread round boundary that preserves bug-1513 serialization - bug-1760: sched_check_pending_rejoin exposed + xcecli_is_connection_broken public predicate - bug-1936: execuser/exechome/execcwd/exdata carried on submission (superset of our bug-1500 execuser fallback; our job-typed resolveExecUser removed as dead code) - bug-1945~1962: apiserver auth hardening (HS256 pinning, default- secret rejection, logout revocation, bcrypt, RBAC) -- our API-key branch folded into controllers.ParseTokenClaims so both coexist - bug-1736: rawRunUsage job run-usage fields in the Go model - xce_test relocated src/controller/testsuite/test.c -> src/harness/test.c; controller suite split into controller_test.c + fixtures; their clitest fixtures spawn xce_test mid-suite under `meson test -j` Ours preserved across the merge: - PEND-reason P1 (codes 1-9, preason.h, job_preason machinery) -- gate re-ported into their relocated allocator (sched_election.c) after plugin_job_election, with attach on the allocator thread only (bug-1521 race discipline) - PEND-reason P0 main_reason semantics RECONCILED to theirs: the merge initially re-carried our first-detail-add-promotes-main_reason fallback in add_job_preason (4e2ac86), but their whole trace/verify stack treats "detail-only => main_reason 0" as a contract -- sched_trace_capture counts main_reason as its own occurrence ("Expected 2 Was 3" in test_trace_capture), the outcome renderer prints "main reason: none" for detail-only PENDs (test_repl_trace_e2e), and the committed .replay/.sim_verify baselines encode main_reason=0 (test_repl_trace_baseline byte compare, test_trace_equivalence off-vs-traced). The fallback is dropped from the shared lib; the user-visible "overall reason" survives as an API-layer view: rawJobToModel (convert_pure.go) promotes the first detail row to main_reason_name when main_reason is 0 (main_reason VALUE marshals unchanged). add_job_preason keeps only the NULL-reasons guard - bug-1498: sched_job_is_ready rejects non-PEND/suspended jobs - bug-1490/1781: xce_jobctrl_t.action as capnp union discriminant (their jobCtrlUnionDiscriminant, same semantics) - xcecli typed PendingReason field (53c00834), bug-1522 reconnect resend, xcecli_force_reconnect + their is_connection_broken both exported in client.h/libclient - t1/t2/t3 test-node hostconfig in src/configs/hosts.yaml (bug-1494), /xce/v1/events + /xce/v1/apikeys whitelist routes (agent Phase 2) - lib ASAN_OPTIONS=detect_leaks=0 test env + their oom-test block - drop-audit: our bug-1504 fix covered by their bug-1680 (no action) bug-924 follow-up (replaces the67f3f6adscratch-dir wipe): the take-theirs audit's one "drop" was re-evaluated and REVERTED instead of re-applied -- a global `find /tmp -name 'xce_*' -exec rm -rf` at suite start/exit races the LIVE /tmp/xce_* fixtures of sibling suites under `meson test -j` (harness_unit_test's clitest fixtures spawn xce_test as a child mid-suite; the wipe destroyed the parent's fixtures -> test_test_cli failures). Coverage instead: - mkdtemp_clean shim gains mkdtemp_clean_mark/sweep_since (testsuite_support/mkdtemp_clean.[ch]) - new case_scratch_sweep.[ch]: aggregate runners (controller_test.c, harness_test.c -- hundreds of cases per process) call case_scratch_sweep_begin/_end_ok from setUp/tearDown; a PASSED case's dirs are swept immediately in tearDown (after engine reaping), FAILED cases keep their dirs for post-mortem; XCE_MKDTEMP_KEEP_ALL=1 disables. One full controller_unit_test run was observed to leak 12G+ to ENOSPC without this, cascading into unrelated "Expected Non-NULL" failures - harness_unit_test_deps links the shim library as well Test reconciliations on adopt: - core-ready-gates: sched_queue_is_ready now gates only INACT_ADMIN|INACT_WINDOW (bug-1938/1960); CLOSED queues elect -- covered end-to-end by test_queue_admin_control.c - test_worker_resync: the 4 restart-replay RUN assertions predate the bug-1509 B3 marking (8858afed) landing on the same lineage; replayed RUN jobs now assert RUN|UNKWN|TRANSIENT (TWR_ASSERT_REPLAYED_RUN); terminal DONE/EXIT assertions unchanged - convert_pure.go: our job-typed resolveExecUser deleted (superseded by their bug-1780/1936 two-arg version) - test_preason: the 3 P0-promotion assertions reverted to the detail-keeps-main-0 contract; new tests cover limit-code detail rows and explicit-main-wins-over-later-details; apiserver convert_test.go gains the detail-only name-promotion cases Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
commit
0c8607345e
663 changed files with 139848 additions and 13614 deletions
|
|
@ -7,46 +7,46 @@ import (
|
|||
|
||||
func TestClusterInfo_NewFields(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
name string
|
||||
cluster ClusterInfo
|
||||
field string
|
||||
field string
|
||||
want interface{}
|
||||
}{
|
||||
{
|
||||
name: "HeartbeatInterval field exists and serializes",
|
||||
name: "HeartbeatInterval field exists and serializes",
|
||||
cluster: ClusterInfo{ClusterName: "test", HeartbeatInterval: 30},
|
||||
field: "heartbeat_interval",
|
||||
want: float64(30),
|
||||
field: "heartbeat_interval",
|
||||
want: float64(30),
|
||||
},
|
||||
{
|
||||
name: "Vcpus field exists and serializes",
|
||||
name: "Vcpus field exists and serializes",
|
||||
cluster: ClusterInfo{ClusterName: "test", Vcpus: 16},
|
||||
field: "vcpus",
|
||||
want: float64(16),
|
||||
field: "vcpus",
|
||||
want: float64(16),
|
||||
},
|
||||
{
|
||||
name: "InactiveHeartbeatCount field exists and serializes",
|
||||
name: "InactiveHeartbeatCount field exists and serializes",
|
||||
cluster: ClusterInfo{ClusterName: "test", InactiveHeartbeatCount: 3},
|
||||
field: "inactive_heartbeat_count",
|
||||
want: float64(3),
|
||||
field: "inactive_heartbeat_count",
|
||||
want: float64(3),
|
||||
},
|
||||
{
|
||||
name: "HeartbeatInterval zero value serializes as 0 not omitted",
|
||||
name: "HeartbeatInterval zero value serializes as 0 not omitted",
|
||||
cluster: ClusterInfo{ClusterName: "test", HeartbeatInterval: 0, Vcpus: 0, InactiveHeartbeatCount: 0},
|
||||
field: "heartbeat_interval",
|
||||
want: float64(0),
|
||||
field: "heartbeat_interval",
|
||||
want: float64(0),
|
||||
},
|
||||
{
|
||||
name: "Vcpus zero value serializes as 0 not omitted",
|
||||
name: "Vcpus zero value serializes as 0 not omitted",
|
||||
cluster: ClusterInfo{ClusterName: "test", HeartbeatInterval: 0, Vcpus: 0, InactiveHeartbeatCount: 0},
|
||||
field: "vcpus",
|
||||
want: float64(0),
|
||||
field: "vcpus",
|
||||
want: float64(0),
|
||||
},
|
||||
{
|
||||
name: "InactiveHeartbeatCount zero value serializes as 0 not omitted",
|
||||
name: "InactiveHeartbeatCount zero value serializes as 0 not omitted",
|
||||
cluster: ClusterInfo{ClusterName: "test", HeartbeatInterval: 0, Vcpus: 0, InactiveHeartbeatCount: 0},
|
||||
field: "inactive_heartbeat_count",
|
||||
want: float64(0),
|
||||
field: "inactive_heartbeat_count",
|
||||
want: float64(0),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -122,4 +122,4 @@ func mapKeys(m map[string]interface{}) []string {
|
|||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
package models
|
||||
|
||||
const (
|
||||
CONTROL_JOB = 1
|
||||
CONTROL_HOST = 2
|
||||
CONTROL_QUEUE = 3
|
||||
CONTROL_CLUSTER = 4
|
||||
CONTROL_DEBUG = 5
|
||||
)
|
||||
|
||||
type ActionControl struct {
|
||||
TargetType int `json:"target_type"`
|
||||
ActionType int `json:"action_type"`
|
||||
Content Jsonb `json:"content"`
|
||||
SubmitTime int64 `json:"submit_time"`
|
||||
Submitter string `json:"submitter"`
|
||||
}
|
||||
package models
|
||||
|
||||
const (
|
||||
CONTROL_JOB = 1
|
||||
CONTROL_HOST = 2
|
||||
CONTROL_QUEUE = 3
|
||||
CONTROL_CLUSTER = 4
|
||||
CONTROL_DEBUG = 5
|
||||
)
|
||||
|
||||
type ActionControl struct {
|
||||
TargetType int `json:"target_type"`
|
||||
ActionType int `json:"action_type"`
|
||||
Content Jsonb `json:"content"`
|
||||
SubmitTime int64 `json:"submit_time"`
|
||||
Submitter string `json:"submitter"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,9 +88,9 @@ type HostInfo struct {
|
|||
NumSSusp int `json:"num_ssusp"`
|
||||
NumUSusp int `json:"num_ususp"`
|
||||
//NumRsv int `json:"num_rsv"`
|
||||
NumDone int `json:"num_done"`
|
||||
Topology string `json:"topology"` // JSONB
|
||||
SchedStop string `json:"sched_stop"` // JSONB
|
||||
NumDone int `json:"num_done"`
|
||||
Topology string `json:"topology"` // JSONB
|
||||
SchedStop string `json:"sched_stop"` // JSONB
|
||||
ResourceValues []ResourceDistributionInfo `json:"resource_values"` // per-worker resource values
|
||||
//RealLoad string `json:"real_load"` // JSONB
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,4 +68,4 @@ func TestHostStateStr(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,9 +125,12 @@ var JobKillSignalControlMap = map[int][]int{
|
|||
JOB_KILL: {JOBSTAT["RUN"], JOBSTAT["PEND"], JOBSTAT["SSUSP"], JOBSTAT["USUSP"], JOBSTAT["PSUSP"]},
|
||||
}
|
||||
|
||||
// DefaultActionSignal names each action's default signal. bug-1957: kill and
|
||||
// stop name the last signal of their graceful sequences (backend
|
||||
// jobCtrlParams sends them with the configured grace period).
|
||||
var DefaultActionSignal = map[string]string{
|
||||
"kill": "TERM",
|
||||
"stop": "TSTP",
|
||||
"kill": "KILL",
|
||||
"stop": "STOP",
|
||||
"resume": "CONT",
|
||||
}
|
||||
|
||||
|
|
@ -175,8 +178,8 @@ var JOB_SUPPORT_FILTERS = []string{
|
|||
"job_id",
|
||||
//"user_group",
|
||||
//"job_group",
|
||||
//"project_name",
|
||||
//"license_project",
|
||||
"project_name", // bug-1935: xcecli jobs list -P
|
||||
"license_project", // bug-1935: xcecli jobs list --license-project
|
||||
//"sla",
|
||||
"submit_time",
|
||||
"queue_time",
|
||||
|
|
@ -485,6 +488,11 @@ var JobFieldMappings = map[string]string{
|
|||
}
|
||||
|
||||
type JobInfo struct {
|
||||
// Provisional marks a record the apiserver stored itself when the
|
||||
// controller accepted the submit, before the controller's own
|
||||
// OnJobCreated/array push arrived (bug-1894); that push replaces it.
|
||||
// Not a column: json "-" keeps it out of query results.
|
||||
Provisional bool `json:"-"`
|
||||
Unique_JobID int64 `json:"unique_job_id"`
|
||||
JobID int64 `json:"job_id"`
|
||||
ArrayIdx int `json:"array_idx"` //new
|
||||
|
|
@ -542,18 +550,29 @@ type JobInfo struct {
|
|||
ReserveTime int64 `json:"reserve_time"`
|
||||
Duration int `json:"duration"`
|
||||
CPUTime int `json:"cpu_time"`
|
||||
ExitStatus Jsonb `json:"exit_status"` //change type, JSONB as []byte
|
||||
ExecHosts Jsonb `json:"exec_hosts"` //change type, JSONB as []byte
|
||||
ExecUID int `json:"exec_uid"`
|
||||
ExecHome string `json:"exec_home"`
|
||||
ExecCWD string `json:"exec_cwd"`
|
||||
ExecUser string `json:"exec_user"` //name change
|
||||
ChargedSaap string `json:"charged_saap"`
|
||||
RunTime int `json:"run_time"`
|
||||
RunTimeEstimation int `json:"run_time_estimation"`
|
||||
PendingReason Jsonb `json:"pending_reason"` //change type, JSONB as []byte
|
||||
PIDInfo Jsonb `json:"pid_info"` // JSONB as []byte
|
||||
JobRusage Jsonb `json:"job_rusage"` // JSONB as []byte
|
||||
// Run usage (bug-1736), from the controller's accumulated job usage with
|
||||
// LSF bjobs -l definitions; zero until the first usage report.
|
||||
MaxMem float64 `json:"max_mem"` // MB
|
||||
AvgMem float64 `json:"avg_mem"` // MB
|
||||
UsedMem float64 `json:"used_mem"` // MB, latest
|
||||
PeakCPU float64 `json:"peak_cpu"` // highest cores used at once
|
||||
PeakCPUTime int `json:"peak_cpu_time"` // peak_cpu rounded
|
||||
PeakCPUDuration float64 `json:"peak_cpu_duration"` // seconds, the interval that set the peak
|
||||
MemEfficiency float64 `json:"mem_efficiency"` // percent of the rusage[mem] request
|
||||
AvgCPUEfficiency float64 `json:"avg_cpu_efficiency"` // percent, cpu_time / elapsed / slots
|
||||
PeakCPUEfficiency float64 `json:"peak_cpu_efficiency"` // percent, peak_cpu / slots
|
||||
ExitStatus Jsonb `json:"exit_status"` //change type, JSONB as []byte
|
||||
ExecHosts Jsonb `json:"exec_hosts"` //change type, JSONB as []byte
|
||||
ExecUID int `json:"exec_uid"`
|
||||
ExecHome string `json:"exec_home"`
|
||||
ExecCWD string `json:"exec_cwd"`
|
||||
ExecUser string `json:"exec_user"` //name change
|
||||
ChargedSaap string `json:"charged_saap"`
|
||||
RunTime int `json:"run_time"`
|
||||
RunTimeEstimation int `json:"run_time_estimation"`
|
||||
PendingReason Jsonb `json:"pending_reason"` //change type, JSONB as []byte
|
||||
PIDInfo Jsonb `json:"pid_info"` // JSONB as []byte
|
||||
JobRusage Jsonb `json:"job_rusage"` // JSONB as []byte
|
||||
}
|
||||
|
||||
type JobExecHosts struct {
|
||||
|
|
@ -587,32 +606,25 @@ type ArrayJobInfo struct {
|
|||
}
|
||||
|
||||
type JobAdditionalFields struct {
|
||||
JobID int64 `json:"job_id"`
|
||||
SubmitUser string `json:"submit_user"`
|
||||
JobStatus int `json:"job_status"`
|
||||
JobID int64 `json:"job_id"`
|
||||
SubmitUser string `json:"submit_user"`
|
||||
JobStatus int `json:"job_status"`
|
||||
SubmitTime int64 `json:"submit_time"`
|
||||
FromHost string `json:"from_host"`
|
||||
ExecHosts string `json:"exec_hosts"`
|
||||
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
JobRusage Jsonb `json:"job_rusage"`
|
||||
MaxMem float64 `json:"max_mem"`
|
||||
AvgMem float64 `json:"avg_mem"`
|
||||
UsedMem float64 `json:"used_mem"`
|
||||
CPUTime int `json:"cpu_time"`
|
||||
PeakCPUTime int `json:"peak_cpu_time"`
|
||||
PeakCPUDuration float64 `json:"peak_cpu_duration"`
|
||||
MemEfficiency float64 `json:"mem_efficiency"` // Memory efficiency in percentage
|
||||
AvgCPUEfficiency float64 `json:"avg_cpu_efficiency"` // Average CPU efficiency in percentage
|
||||
PeakCPUEfficiency float64 `json:"peak_cpu_efficiency"` // Peak CPU efficiency in percentage
|
||||
NumHosts int `json:"num_hosts"` // Number of hosts used by the job
|
||||
FirstHost string `json:"first_host"` // First host where the job ran
|
||||
AllocSlot string `json:"alloc_slots"` // Allocated slot information
|
||||
PIDInfo Jsonb `json:"pid_info"`
|
||||
Pids []int `json:"pids"` // List of process IDs associated with the job
|
||||
Pgids []int `json:"pgids"` // List of process group IDs associated with the job
|
||||
InteractiveJobURL string `json:"interactive_job_url"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
JobRusage Jsonb `json:"job_rusage"`
|
||||
// max_mem/avg_mem/used_mem/cpu_time/peak_cpu*/..._efficiency are
|
||||
// JobInfo columns now (bug-1736).
|
||||
NumHosts int `json:"num_hosts"` // Number of hosts used by the job
|
||||
FirstHost string `json:"first_host"` // First host where the job ran
|
||||
AllocSlot string `json:"alloc_slots"` // Allocated slot information
|
||||
PIDInfo Jsonb `json:"pid_info"`
|
||||
Pids []int `json:"pids"` // List of process IDs associated with the job
|
||||
Pgids []int `json:"pgids"` // List of process group IDs associated with the job
|
||||
InteractiveJobURL string `json:"interactive_job_url"`
|
||||
// CoreLimit/MemLimit: JobInfo has no equivalent field (these are
|
||||
// submission-time resource limits, not job-state fields), but xcecli's
|
||||
// JobFieldsMap accepts them as valid -o/-l display fields (bug-1674) --
|
||||
|
|
@ -662,8 +674,9 @@ type JobSubmitRequest struct {
|
|||
ChkpntPeriod int `json:"chkpnt_period,omitempty"`
|
||||
ChkpntDir string `json:"chkpnt_dir,omitempty"`
|
||||
InitChkpntPeriod int `json:"init_chkpnt_period,omitempty"`
|
||||
CWD string `json:"cwd,omitempty"`
|
||||
FromHost string `json:"from_host,omitempty"` // client-asserted submitting hostname (bug-1676) -- passed through unchanged, not derived server-side
|
||||
CWD string `json:"cwd,omitempty"` // absolute; the job runs here on the worker (bug-1936)
|
||||
ExecHome string `json:"exec_home,omitempty" example:"/home/alice"` // absolute; HOME of the job on the worker (bug-1936)
|
||||
FromHost string `json:"from_host,omitempty"` // client-asserted submitting hostname (bug-1676) -- passed through unchanged, not derived server-side
|
||||
OutDir string `json:"out_dir,omitempty"`
|
||||
InFile string `json:"in_file,omitempty"`
|
||||
OutFile string `json:"out_file,omitempty"`
|
||||
|
|
@ -703,10 +716,13 @@ type ShellLimit struct {
|
|||
}
|
||||
|
||||
type JobSubmitResponse struct {
|
||||
JobID int64 `json:"jobid"`
|
||||
JobID int64 `json:"jobid"`
|
||||
JobIDHuman string `json:"job_id_human"` // cluster-apiserver-timestamp-seq, for xce_test/xcecli cross-reference
|
||||
QueueName string `json:"queue_name"`
|
||||
Message string `json:"message"`
|
||||
QueueName string `json:"queue_name"`
|
||||
Message string `json:"message"`
|
||||
// ArraySize is the number of elements of a submitted array; omitted
|
||||
// for an ordinary job (3.2, 3.3).
|
||||
ArraySize int `json:"array_size,omitempty"`
|
||||
}
|
||||
|
||||
// Job query struct in C lib
|
||||
|
|
@ -748,18 +764,18 @@ type JobControlFilter struct {
|
|||
type JobControlRequest struct {
|
||||
Filter JobControlFilter `json:"filter" binding:"required"`
|
||||
Action string `json:"action" binding:"required"`
|
||||
Signal string `json:"signal,omitempty"`
|
||||
Signal string `json:"signal,omitempty"` // kill only: send this signal once instead of the graceful sequence
|
||||
Comment string `json:"comment,omitempty"`
|
||||
ForceKill bool `json:"force_kill,omitempty"`
|
||||
Method string `json:"method,omitempty"` // "criu" as default
|
||||
ForceKill bool `json:"force_kill,omitempty"` // kill: SIGKILL at once (no graceful sequence)
|
||||
Method string `json:"method,omitempty"` // "criu" as default
|
||||
}
|
||||
|
||||
type JobControlJobIDRequest struct {
|
||||
Action string `json:"action" binding:"required"`
|
||||
Signal string `json:"signal,omitempty"` // signal value
|
||||
Signal string `json:"signal,omitempty"` // kill only: send this signal once instead of the graceful sequence
|
||||
Comment string `json:"comment,omitempty"`
|
||||
ForceKill bool `json:"force_kill,omitempty"`
|
||||
Method string `json:"method,omitempty"` // "criu" as default
|
||||
ForceKill bool `json:"force_kill,omitempty"` // kill: SIGKILL at once (no graceful sequence)
|
||||
Method string `json:"method,omitempty"` // "criu" as default
|
||||
}
|
||||
|
||||
type JobControlEvent struct {
|
||||
|
|
|
|||
|
|
@ -1,139 +1,139 @@
|
|||
package models
|
||||
|
||||
type ValueType int
|
||||
|
||||
const (
|
||||
STRING ValueType = iota // Bool value
|
||||
NUMERIC // Numeric value
|
||||
BOOLEAN // String value
|
||||
)
|
||||
|
||||
// String returns the string representation of ValueType
|
||||
func (v ValueType) String() string {
|
||||
switch v {
|
||||
case BOOLEAN:
|
||||
return "Boolean"
|
||||
case NUMERIC:
|
||||
return "Numeric"
|
||||
case STRING:
|
||||
return "String"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
type OrderType int
|
||||
|
||||
const (
|
||||
INCR OrderType = iota
|
||||
DECR
|
||||
NA
|
||||
)
|
||||
|
||||
// String returns the string representation of OrderType
|
||||
func (o OrderType) String() string {
|
||||
switch o {
|
||||
case INCR:
|
||||
return "Incr"
|
||||
case DECR:
|
||||
return "Decr"
|
||||
case NA:
|
||||
return "NA"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
var RESOURCE_DEFAULT_COLUMN = []string{
|
||||
"res_name",
|
||||
"description",
|
||||
"value_type",
|
||||
"order_type",
|
||||
"flag",
|
||||
"interval",
|
||||
}
|
||||
|
||||
var RESOURCE_DISTRIBUTION_DEFAULT_COLUMN = []string{
|
||||
"res_name",
|
||||
"numeric_value",
|
||||
"location",
|
||||
"is_dynamic",
|
||||
}
|
||||
|
||||
var RESOURCE_DEFINITION_DEFAULT_COLUMN = []string{
|
||||
"res_name",
|
||||
"description",
|
||||
"value_type",
|
||||
"order_type",
|
||||
"flag",
|
||||
"interval",
|
||||
}
|
||||
|
||||
var ResourceFieldMappings = map[string]string{
|
||||
// API field name → struct field name
|
||||
"value": "numeric_value",
|
||||
}
|
||||
|
||||
var ResourcesAvailableTypes = []string{"static", "dynamic"}
|
||||
|
||||
const (
|
||||
BUILTIN = 0x01
|
||||
DYNAMIC = 0x02
|
||||
RELEASE = 0x20
|
||||
CONSUMABLE = 0x80
|
||||
)
|
||||
|
||||
type FlagValue int
|
||||
|
||||
// ToJSON returns the JSON object representation of FlagValue
|
||||
func (f FlagValue) ToJSON() map[string]bool {
|
||||
return map[string]bool{
|
||||
"builtin": f&BUILTIN != 0,
|
||||
"dynamic": f&DYNAMIC != 0,
|
||||
"release": f&RELEASE != 0,
|
||||
"consumable": f&CONSUMABLE != 0,
|
||||
}
|
||||
}
|
||||
|
||||
type ResourceInfo struct {
|
||||
ResName string
|
||||
Description string
|
||||
ValueType ValueType
|
||||
OrderType OrderType
|
||||
Flag int
|
||||
Interval int
|
||||
}
|
||||
|
||||
// queues info query supported filter
|
||||
var RESOURCE_DISTRIBUTION_SUPPORT_FILTERS = []string{
|
||||
"res_name",
|
||||
"is_dynamic",
|
||||
"location",
|
||||
}
|
||||
|
||||
var RESOURCE_DEFINITION_SUPPORT_FILTERS = []string{
|
||||
"res_name",
|
||||
}
|
||||
|
||||
type ResourceDistributionInfo struct {
|
||||
ResourceName string `json:"res_name"`
|
||||
IsDynamic bool `json:"is_dynamic"`
|
||||
ValueType int `json:"value_type"`
|
||||
BooleanValue bool `json:"boolean_value"`
|
||||
StringValue string `json:"string_value"`
|
||||
NumericValue float64 `json:"numeric_value"`
|
||||
Location string `json:"location"`
|
||||
}
|
||||
|
||||
type ResourceDefinitionInfo struct {
|
||||
ResourceName string `json:"res_name"`
|
||||
Description string `json:"description"`
|
||||
ValueType int `json:"value_type"`
|
||||
OrderType int `json:"order_type"`
|
||||
Flag int `json:"flag"`
|
||||
Interval int `json:"interval"`
|
||||
}
|
||||
|
||||
var RESOURCE_DISTRIBUTION_SUPPORT_SORT = []string{
|
||||
"res_name",
|
||||
}
|
||||
package models
|
||||
|
||||
type ValueType int
|
||||
|
||||
const (
|
||||
STRING ValueType = iota // Bool value
|
||||
NUMERIC // Numeric value
|
||||
BOOLEAN // String value
|
||||
)
|
||||
|
||||
// String returns the string representation of ValueType
|
||||
func (v ValueType) String() string {
|
||||
switch v {
|
||||
case BOOLEAN:
|
||||
return "Boolean"
|
||||
case NUMERIC:
|
||||
return "Numeric"
|
||||
case STRING:
|
||||
return "String"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
type OrderType int
|
||||
|
||||
const (
|
||||
INCR OrderType = iota
|
||||
DECR
|
||||
NA
|
||||
)
|
||||
|
||||
// String returns the string representation of OrderType
|
||||
func (o OrderType) String() string {
|
||||
switch o {
|
||||
case INCR:
|
||||
return "Incr"
|
||||
case DECR:
|
||||
return "Decr"
|
||||
case NA:
|
||||
return "NA"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
var RESOURCE_DEFAULT_COLUMN = []string{
|
||||
"res_name",
|
||||
"description",
|
||||
"value_type",
|
||||
"order_type",
|
||||
"flag",
|
||||
"interval",
|
||||
}
|
||||
|
||||
var RESOURCE_DISTRIBUTION_DEFAULT_COLUMN = []string{
|
||||
"res_name",
|
||||
"numeric_value",
|
||||
"location",
|
||||
"is_dynamic",
|
||||
}
|
||||
|
||||
var RESOURCE_DEFINITION_DEFAULT_COLUMN = []string{
|
||||
"res_name",
|
||||
"description",
|
||||
"value_type",
|
||||
"order_type",
|
||||
"flag",
|
||||
"interval",
|
||||
}
|
||||
|
||||
var ResourceFieldMappings = map[string]string{
|
||||
// API field name → struct field name
|
||||
"value": "numeric_value",
|
||||
}
|
||||
|
||||
var ResourcesAvailableTypes = []string{"static", "dynamic"}
|
||||
|
||||
const (
|
||||
BUILTIN = 0x01
|
||||
DYNAMIC = 0x02
|
||||
RELEASE = 0x20
|
||||
CONSUMABLE = 0x80
|
||||
)
|
||||
|
||||
type FlagValue int
|
||||
|
||||
// ToJSON returns the JSON object representation of FlagValue
|
||||
func (f FlagValue) ToJSON() map[string]bool {
|
||||
return map[string]bool{
|
||||
"builtin": f&BUILTIN != 0,
|
||||
"dynamic": f&DYNAMIC != 0,
|
||||
"release": f&RELEASE != 0,
|
||||
"consumable": f&CONSUMABLE != 0,
|
||||
}
|
||||
}
|
||||
|
||||
type ResourceInfo struct {
|
||||
ResName string
|
||||
Description string
|
||||
ValueType ValueType
|
||||
OrderType OrderType
|
||||
Flag int
|
||||
Interval int
|
||||
}
|
||||
|
||||
// queues info query supported filter
|
||||
var RESOURCE_DISTRIBUTION_SUPPORT_FILTERS = []string{
|
||||
"res_name",
|
||||
"is_dynamic",
|
||||
"location",
|
||||
}
|
||||
|
||||
var RESOURCE_DEFINITION_SUPPORT_FILTERS = []string{
|
||||
"res_name",
|
||||
}
|
||||
|
||||
type ResourceDistributionInfo struct {
|
||||
ResourceName string `json:"res_name"`
|
||||
IsDynamic bool `json:"is_dynamic"`
|
||||
ValueType int `json:"value_type"`
|
||||
BooleanValue bool `json:"boolean_value"`
|
||||
StringValue string `json:"string_value"`
|
||||
NumericValue float64 `json:"numeric_value"`
|
||||
Location string `json:"location"`
|
||||
}
|
||||
|
||||
type ResourceDefinitionInfo struct {
|
||||
ResourceName string `json:"res_name"`
|
||||
Description string `json:"description"`
|
||||
ValueType int `json:"value_type"`
|
||||
OrderType int `json:"order_type"`
|
||||
Flag int `json:"flag"`
|
||||
Interval int `json:"interval"`
|
||||
}
|
||||
|
||||
var RESOURCE_DISTRIBUTION_SUPPORT_SORT = []string{
|
||||
"res_name",
|
||||
}
|
||||
|
|
|
|||
10
src/frontend/apiserver/models/usergroups.go
Normal file
10
src/frontend/apiserver/models/usergroups.go
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package models
|
||||
|
||||
// UserGroupInfo is a user group from the cluster configuration
|
||||
// (users.yaml usergroups). A member is a user name, another group's name or
|
||||
// "all"; ExMembers are removed from the group (bug-1934).
|
||||
type UserGroupInfo struct {
|
||||
Name string `json:"name"`
|
||||
Members []string `json:"members"`
|
||||
ExMembers []string `json:"exclude_members"`
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue