Skip to content

Commit 6edb4f9

Browse files
committed
add volcanojob
Signed-off-by: hudekai <2812840067@qq.com>
1 parent 4594ca0 commit 6edb4f9

File tree

5 files changed

+475
-0
lines changed

5 files changed

+475
-0
lines changed
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
apiVersion: config.karmada.io/v1alpha1
2+
kind: ResourceInterpreterCustomization
3+
metadata:
4+
name: declarative-configuration-job
5+
spec:
6+
target:
7+
apiVersion: batch.volcano.sh/v1alpha1
8+
kind: Job
9+
customizations:
10+
healthInterpretation:
11+
luaScript: >
12+
function InterpretHealth(observedObj)
13+
if observedObj.status == nil or observedObj.status.state == nil then
14+
return false
15+
end
16+
local phase = observedObj.status.state.phase
17+
if phase == nil or phase == '' then
18+
return false
19+
end
20+
if phase == 'Running' or phase == 'Completed' or phase == "Pending" or
21+
phase == "Aborting" or phase == "Aborted" or phase == "Restarting" or
22+
phase == "Completing" or phase == "Terminating" or phase == "Terminated" then
23+
return true
24+
end
25+
return false
26+
end
27+
componentResource:
28+
luaScript: |
29+
local kube = require("kube")
30+
local function get(obj, path)
31+
local cur = obj
32+
for i = 1, #path do
33+
if cur == nil then return nil end
34+
cur = cur[path[i]]
35+
end
36+
return cur
37+
end
38+
39+
local function to_num(v, default)
40+
if v == nil or v == '' then
41+
return default
42+
end
43+
local n = tonumber(v)
44+
if n ~= nil then return n end
45+
return default
46+
end
47+
48+
function GetComponents(observedObj)
49+
local components = {}
50+
51+
local tasks = get(observedObj, {"spec","tasks"})
52+
if tasks == nil then
53+
return components
54+
end
55+
56+
for _, task in ipairs(tasks) do
57+
local replicas = to_num(task.minAvailable, 1)
58+
requires = kube.accuratePodRequirements(task.template)
59+
60+
table.insert(components, {
61+
name = task.name,
62+
replicas = replicas,
63+
replicaRequirements = requires
64+
})
65+
end
66+
67+
return components
68+
end
69+
statusAggregation:
70+
luaScript: >
71+
local function durationVal(d)
72+
if type(d) == "number" then
73+
return d
74+
end
75+
if type(d) ~= "string" then
76+
return 0
77+
end
78+
local totalSeconds = 0
79+
for num, unit in string.gmatch(d, "([%d%.]+)([hms])") do
80+
num = tonumber(num)
81+
if unit == "h" then
82+
totalSeconds = totalSeconds + num * 3600
83+
elseif unit == "m" then
84+
totalSeconds = totalSeconds + num * 60
85+
elseif unit == "s" then
86+
totalSeconds = totalSeconds + num
87+
end
88+
end
89+
if totalSeconds > 0 then
90+
return totalSeconds
91+
end
92+
return tonumber(d) or 0
93+
end
94+
local function omitEmpty(t)
95+
if t == nil then return nil end
96+
local out = {}
97+
for k, v in pairs(t) do
98+
if type(v) == "table" then
99+
local inner = omitEmpty(v)
100+
if inner ~= nil and next(inner) ~= nil then
101+
out[k] = inner
102+
end
103+
elseif v ~= nil and not (v == 0 or v == "" or v == "0s") then
104+
out[k] = v
105+
end
106+
end
107+
if next(out) ~= nil then
108+
return out
109+
else
110+
return nil
111+
end
112+
end
113+
114+
function AggregateStatus(desiredObj, statusItems)
115+
if statusItems == nil then return desiredObj end
116+
if desiredObj.status == nil then desiredObj.status = {} end
117+
118+
if #statusItems == 1 then
119+
desiredObj.status = statusItems[1].status
120+
return desiredObj
121+
end
122+
123+
local failedClusters = {}
124+
local completedClusters = 0
125+
local latestTransition = {}
126+
local successfulClusters = 0
127+
local hasFailed = false
128+
local failedConditions = {}
129+
local failedPhases = {
130+
Failed = true,
131+
Aborted = true,
132+
Aborting = true,
133+
Terminated = true,
134+
Terminating = true,
135+
}
136+
local status = {
137+
state = {},
138+
minAvailable = 0,
139+
taskStatusCount = {},
140+
pending = 0,
141+
running = 0,
142+
succeeded = 0,
143+
failed = 0,
144+
terminating = 0,
145+
unknown = 0,
146+
version = 0,
147+
retryCount = 0,
148+
controlledResources = {},
149+
conditions = {},
150+
runningDuration = "0s",
151+
}
152+
153+
for i = 1, #statusItems do
154+
local s = statusItems[i].status
155+
if s ~= nil then
156+
status.minAvailable = status.minAvailable + (s.minAvailable or 0)
157+
status.pending = status.pending + (s.pending or 0)
158+
status.running = status.running + (s.running or 0)
159+
status.succeeded = status.succeeded + (s.succeeded or 0)
160+
status.failed = status.failed + (s.failed or 0)
161+
status.terminating = status.terminating + (s.terminating or 0)
162+
status.unknown = status.unknown + (s.unknown or 0)
163+
status.version = math.max(status.version, s.version or 0)
164+
status.retryCount = status.retryCount + (s.retryCount or 0)
165+
if durationVal(s.runningDuration) > durationVal(status.runningDuration) then
166+
status.runningDuration = s.runningDuration
167+
end
168+
169+
if s.taskStatusCount ~= nil then
170+
for taskName, taskStatus in pairs(s.taskStatusCount) do
171+
if status.taskStatusCount[taskName] == nil then
172+
status.taskStatusCount[taskName] = { phase = {} }
173+
end
174+
if taskStatus.phase ~= nil then
175+
for phaseName, count in pairs(taskStatus.phase) do
176+
status.taskStatusCount[taskName].phase[phaseName] = (status.taskStatusCount[taskName].phase[phaseName] or 0) + count
177+
end
178+
end
179+
end
180+
end
181+
182+
if s.controlledResources then
183+
for k, v in pairs(s.controlledResources) do
184+
status.controlledResources[k] = v
185+
end
186+
end
187+
188+
if s.conditions then
189+
local clusterHasFailed = false
190+
for _, c in ipairs(s.conditions) do
191+
if failedPhases[c.status] then
192+
clusterHasFailed = true
193+
hasFailed = true
194+
end
195+
if not clusterHasFailed then
196+
local exist = latestTransition[c.status]
197+
if exist == nil or c.lastTransitionTime > exist.lastTransitionTime then
198+
latestTransition[c.status] = c
199+
end
200+
end
201+
end
202+
if clusterHasFailed and #failedConditions == 0 then
203+
failedConditions = s.conditions
204+
end
205+
end
206+
207+
if s.state ~= nil then
208+
local st = s.state
209+
if st.phase == "Completed" then
210+
successfulClusters = successfulClusters + 1
211+
elseif st.phase == "Failed" or st.phase == "Aborted" then
212+
table.insert(failedClusters, statusItems[i].clusterName)
213+
end
214+
end
215+
end
216+
end
217+
218+
if #failedClusters > 0 then
219+
status.state.phase = "Failed"
220+
status.state.reason = "VolcanoJobFailed"
221+
status.state.message = "Job failed in clusters: " .. table.concat(failedClusters, ",")
222+
status.state.lastTransitionTime = os.date("!%Y-%m-%dT%H:%M:%SZ")
223+
end
224+
225+
if successfulClusters == #statusItems and successfulClusters > 0 then
226+
status.state.phase = "Completed"
227+
status.state.reason = "Completed"
228+
status.state.message = "Job completed successfully"
229+
status.state.lastTransitionTime = os.date("!%Y-%m-%dT%H:%M:%SZ")
230+
end
231+
232+
if hasFailed then
233+
status.conditions = failedConditions
234+
else
235+
for _, v in pairs(latestTransition) do
236+
table.insert(status.conditions, v)
237+
end
238+
end
239+
240+
desiredObj.status = omitEmpty(status) or {}
241+
return desiredObj
242+
end
243+
statusReflection:
244+
luaScript: >
245+
function ReflectStatus(observedObj)
246+
local status = {}
247+
248+
if observedObj == nil or observedObj.status == nil then
249+
return status
250+
end
251+
252+
local s = observedObj.status
253+
status.minAvailable = s.minAvailable
254+
status.pending = s.pending
255+
status.running = s.running
256+
status.succeeded = s.succeeded
257+
status.failed = s.failed
258+
status.terminating = s.terminating
259+
status.unknown = s.unknown
260+
status.version = s.version
261+
status.retryCount = s.retryCount
262+
status.runningDuration = s.runningDuration
263+
264+
status.taskStatusCount = {}
265+
if s.taskStatusCount ~= nil then
266+
for k, v in pairs(s.taskStatusCount) do
267+
status.taskStatusCount[k] = v
268+
end
269+
end
270+
271+
status.controlledResources = {}
272+
if s.controlledResources ~= nil then
273+
for k, v in pairs(s.controlledResources) do
274+
status.controlledResources[k] = v
275+
end
276+
end
277+
278+
if s.state ~= nil then
279+
status.state = s.state
280+
end
281+
282+
status.conditions = {}
283+
if type(s.conditions) == "table" then
284+
for _, cond in ipairs(s.conditions) do
285+
table.insert(status.conditions, cond)
286+
end
287+
end
288+
289+
return status
290+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
tests:
2+
- desiredInputPath: testdata/desired-job.yaml
3+
statusInputPath: testdata/status-file.yaml
4+
operation: AggregateStatus
5+
- observedInputPath: testdata/observed-job.yaml
6+
operation: InterpretHealth
7+
- observedInputPath: testdata/observed-job.yaml
8+
operation: InterpretStatus
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
apiVersion: batch.volcano.sh/v1alpha1
2+
kind: Job
3+
metadata:
4+
name: dk-job
5+
spec:
6+
maxRetry: 3
7+
minAvailable: 3
8+
plugins:
9+
env: []
10+
ssh: []
11+
svc:
12+
- --disable-network-policy=true
13+
queue: default
14+
schedulerName: volcano
15+
tasks:
16+
- minAvailable: 1
17+
name: job-nginx1
18+
replicas: 1
19+
template:
20+
metadata:
21+
name: nginx1
22+
spec:
23+
containers:
24+
- args:
25+
- sleep 10
26+
command:
27+
- bash
28+
- -c
29+
image: nginx:latest
30+
imagePullPolicy: IfNotPresent
31+
name: nginx
32+
resources:
33+
requests:
34+
cpu: 100m
35+
nodeSelector:
36+
kubernetes.io/os: linux
37+
restartPolicy: OnFailure
38+
- minAvailable: 2
39+
name: job-nginx2
40+
replicas: 3
41+
template:
42+
metadata:
43+
name: nginx2
44+
spec:
45+
containers:
46+
- args:
47+
- sleep 30
48+
command:
49+
- bash
50+
- -c
51+
image: nginx:latest
52+
imagePullPolicy: IfNotPresent
53+
name: nginx
54+
resources:
55+
requests:
56+
cpu: 100m
57+
nodeSelector:
58+
kubernetes.io/os: linux
59+
restartPolicy: OnFailure

0 commit comments

Comments
 (0)