Skip to content

Commit ee2820e

Browse files
committed
feat(rest): add K8s resource requests & limits to info endpoint (#724)
Expose default and maximum values for Kubernetes CPU and Memory requests and limits in `info` endpoint. Closes reanahub/reana#883
1 parent 26f511e commit ee2820e

File tree

5 files changed

+247
-16
lines changed

5 files changed

+247
-16
lines changed

docs/openapi.json

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,14 +366,38 @@
366366
"title": "Default workspace",
367367
"value": "/usr/share"
368368
},
369+
"kubernetes_cpu_limit": {
370+
"title": "Default CPU limit for Kubernetes jobs",
371+
"value": "2"
372+
},
373+
"kubernetes_cpu_request": {
374+
"title": "Default CPU request for Kubernetes jobs",
375+
"value": "1"
376+
},
377+
"kubernetes_max_cpu_limit": {
378+
"title": "Maximum allowed CPU limit for Kubernetes jobs",
379+
"value": "4"
380+
},
381+
"kubernetes_max_cpu_request": {
382+
"title": "Maximum allowed CPU request for Kubernetes jobs",
383+
"value": "2"
384+
},
369385
"kubernetes_max_memory_limit": {
370386
"title": "Maximum allowed memory limit for Kubernetes jobs",
371387
"value": "10Gi"
372388
},
389+
"kubernetes_max_memory_request": {
390+
"title": "Maximum allowed memory request for Kubernetes jobs",
391+
"value": "5Gi"
392+
},
373393
"kubernetes_memory_limit": {
374394
"title": "Default memory limit for Kubernetes jobs",
375395
"value": "3Gi"
376396
},
397+
"kubernetes_memory_request": {
398+
"title": "Default memory request for Kubernetes jobs",
399+
"value": "1Gi"
400+
},
377401
"maximum_kubernetes_jobs_timeout": {
378402
"title": "Maximum timeout for Kubernetes jobs",
379403
"value": "1209600"
@@ -408,6 +432,30 @@
408432
},
409433
"type": "object"
410434
},
435+
"default_kubernetes_cpu_limit": {
436+
"properties": {
437+
"title": {
438+
"type": "string"
439+
},
440+
"value": {
441+
"type": "string",
442+
"x-nullable": true
443+
}
444+
},
445+
"type": "object"
446+
},
447+
"default_kubernetes_cpu_request": {
448+
"properties": {
449+
"title": {
450+
"type": "string"
451+
},
452+
"value": {
453+
"type": "string",
454+
"x-nullable": true
455+
}
456+
},
457+
"type": "object"
458+
},
411459
"default_kubernetes_jobs_timeout": {
412460
"properties": {
413461
"title": {
@@ -425,7 +473,20 @@
425473
"type": "string"
426474
},
427475
"value": {
476+
"type": "string",
477+
"x-nullable": true
478+
}
479+
},
480+
"type": "object"
481+
},
482+
"default_kubernetes_memory_request": {
483+
"properties": {
484+
"title": {
428485
"type": "string"
486+
},
487+
"value": {
488+
"type": "string",
489+
"x-nullable": true
429490
}
430491
},
431492
"type": "object"
@@ -441,6 +502,30 @@
441502
},
442503
"type": "object"
443504
},
505+
"kubernetes_max_cpu_limit": {
506+
"properties": {
507+
"title": {
508+
"type": "string"
509+
},
510+
"value": {
511+
"type": "string",
512+
"x-nullable": true
513+
}
514+
},
515+
"type": "object"
516+
},
517+
"kubernetes_max_cpu_request": {
518+
"properties": {
519+
"title": {
520+
"type": "string"
521+
},
522+
"value": {
523+
"type": "string",
524+
"x-nullable": true
525+
}
526+
},
527+
"type": "object"
528+
},
444529
"kubernetes_max_memory_limit": {
445530
"properties": {
446531
"title": {
@@ -453,6 +538,18 @@
453538
},
454539
"type": "object"
455540
},
541+
"kubernetes_max_memory_request": {
542+
"properties": {
543+
"title": {
544+
"type": "string"
545+
},
546+
"value": {
547+
"type": "string",
548+
"x-nullable": true
549+
}
550+
},
551+
"type": "object"
552+
},
456553
"maximum_interactive_session_inactivity_period": {
457554
"properties": {
458555
"title": {

reana_server/config.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
#
33
# This file is part of REANA.
4-
# Copyright (C) 2017, 2018, 2019, 2020, 2021, 2022, 2023 CERN.
4+
# Copyright (C) 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2025 CERN.
55
#
66
# REANA is free software; you can redistribute it and/or modify it
77
# under the terms of the MIT License; see LICENSE file for more details.
@@ -58,21 +58,46 @@
5858
os.getenv("LOGIN_PROVIDERS_SECRETS", "{}")
5959
)
6060

61+
REANA_KUBERNETES_JOBS_CPU_REQUEST = os.getenv("REANA_KUBERNETES_JOBS_CPU_REQUEST")
62+
"""Default cpu request for user job containers."""
63+
64+
REANA_KUBERNETES_JOBS_CPU_LIMIT = os.getenv("REANA_KUBERNETES_JOBS_CPU_LIMIT")
65+
"""Default cpu limit for user job containers."""
66+
67+
REANA_KUBERNETES_JOBS_MEMORY_REQUEST = os.getenv("REANA_KUBERNETES_JOBS_MEMORY_REQUEST")
68+
"""Default memory request for user job containers."""
69+
6170
REANA_KUBERNETES_JOBS_MEMORY_LIMIT = os.getenv("REANA_KUBERNETES_JOBS_MEMORY_LIMIT")
62-
"""Maximum memory limit for user job containers for workflow complexity estimation."""
71+
"""Default memory limit for user job containers."""
6372

64-
REANA_KUBERNETES_JOBS_MEMORY_LIMIT_IN_BYTES = (
65-
kubernetes_memory_to_bytes(REANA_KUBERNETES_JOBS_MEMORY_LIMIT)
66-
if REANA_KUBERNETES_JOBS_MEMORY_LIMIT
67-
else 0
73+
REANA_KUBERNETES_JOBS_MAX_USER_CPU_REQUEST = os.getenv(
74+
"REANA_KUBERNETES_JOBS_MAX_USER_CPU_REQUEST"
6875
)
69-
"""Maximum memory limit for user job containers in bytes."""
76+
"""Maximum cpu request that users can assign to their job containers."""
77+
78+
REANA_KUBERNETES_JOBS_MAX_USER_CPU_LIMIT = os.getenv(
79+
"REANA_KUBERNETES_JOBS_MAX_USER_CPU_LIMIT"
80+
)
81+
"""Maximum cpu limit that users can assign to their job containers."""
82+
83+
REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_REQUEST = os.getenv(
84+
"REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_REQUEST"
85+
)
86+
"""Maximum memory request that users can assign to their job containers."""
7087

7188
REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_LIMIT = os.getenv(
7289
"REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_LIMIT"
7390
)
7491
"""Maximum memory limit that users can assign to their job containers."""
7592

93+
94+
REANA_KUBERNETES_JOBS_MEMORY_LIMIT_IN_BYTES = (
95+
kubernetes_memory_to_bytes(REANA_KUBERNETES_JOBS_MEMORY_LIMIT)
96+
if REANA_KUBERNETES_JOBS_MEMORY_LIMIT
97+
else 0
98+
)
99+
"""Maximum memory limit for user job containers in bytes."""
100+
76101
REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_LIMIT_IN_BYTES = (
77102
kubernetes_memory_to_bytes(REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_LIMIT)
78103
if REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_LIMIT

reana_server/rest/info.py

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
#
33
# This file is part of REANA.
4-
# Copyright (C) 2021, 2022 CERN.
4+
# Copyright (C) 2021, 2022, 2025 CERN.
55
#
66
# REANA is free software; you can redistribute it and/or modify it
77
# under the terms of the MIT License; see LICENSE file for more details.
@@ -19,7 +19,13 @@
1919
from reana_server.config import (
2020
SUPPORTED_COMPUTE_BACKENDS,
2121
WORKSPACE_RETENTION_PERIOD,
22+
REANA_KUBERNETES_JOBS_MAX_USER_CPU_REQUEST,
23+
REANA_KUBERNETES_JOBS_MAX_USER_CPU_LIMIT,
24+
REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_REQUEST,
2225
REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_LIMIT,
26+
REANA_KUBERNETES_JOBS_CPU_REQUEST,
27+
REANA_KUBERNETES_JOBS_CPU_LIMIT,
28+
REANA_KUBERNETES_JOBS_MEMORY_REQUEST,
2329
REANA_KUBERNETES_JOBS_MEMORY_LIMIT,
2430
REANA_KUBERNETES_JOBS_TIMEOUT_LIMIT,
2531
REANA_KUBERNETES_JOBS_MAX_USER_TIMEOUT_LIMIT,
@@ -71,12 +77,37 @@ def info(user, **kwargs): # noqa
7177
value:
7278
type: string
7379
type: object
80+
default_kubernetes_cpu_request:
81+
properties:
82+
title:
83+
type: string
84+
value:
85+
type: string
86+
x-nullable: true
87+
type: object
88+
default_kubernetes_cpu_limit:
89+
properties:
90+
title:
91+
type: string
92+
value:
93+
type: string
94+
x-nullable: true
95+
type: object
96+
default_kubernetes_memory_request:
97+
properties:
98+
title:
99+
type: string
100+
value:
101+
type: string
102+
x-nullable: true
103+
type: object
74104
default_kubernetes_memory_limit:
75105
properties:
76106
title:
77107
type: string
78108
value:
79109
type: string
110+
x-nullable: true
80111
type: object
81112
default_workspace:
82113
properties:
@@ -85,6 +116,30 @@ def info(user, **kwargs): # noqa
85116
value:
86117
type: string
87118
type: object
119+
kubernetes_max_cpu_request:
120+
properties:
121+
title:
122+
type: string
123+
value:
124+
type: string
125+
x-nullable: true
126+
type: object
127+
kubernetes_max_cpu_limit:
128+
properties:
129+
title:
130+
type: string
131+
value:
132+
type: string
133+
x-nullable: true
134+
type: object
135+
kubernetes_max_memory_request:
136+
properties:
137+
title:
138+
type: string
139+
value:
140+
type: string
141+
x-nullable: true
142+
type: object
88143
kubernetes_max_memory_limit:
89144
properties:
90145
title:
@@ -145,10 +200,34 @@ def info(user, **kwargs): # noqa
145200
"slurmcern"
146201
]
147202
},
203+
"kubernetes_cpu_request": {
204+
"title": "Default CPU request for Kubernetes jobs",
205+
"value": "1"
206+
},
207+
"kubernetes_cpu_limit": {
208+
"title": "Default CPU limit for Kubernetes jobs",
209+
"value": "2"
210+
},
211+
"kubernetes_memory_request": {
212+
"title": "Default memory request for Kubernetes jobs",
213+
"value": "1Gi"
214+
},
148215
"kubernetes_memory_limit": {
149216
"title": "Default memory limit for Kubernetes jobs",
150217
"value": "3Gi"
151218
},
219+
"kubernetes_max_cpu_request": {
220+
"title": "Maximum allowed CPU request for Kubernetes jobs",
221+
"value": "2"
222+
},
223+
"kubernetes_max_cpu_limit": {
224+
"title": "Maximum allowed CPU limit for Kubernetes jobs",
225+
"value": "4"
226+
},
227+
"kubernetes_max_memory_request": {
228+
"title": "Maximum allowed memory request for Kubernetes jobs",
229+
"value": "5Gi"
230+
},
152231
"kubernetes_max_memory_limit": {
153232
"title": "Maximum allowed memory limit for Kubernetes jobs",
154233
"value": "10Gi"
@@ -193,10 +272,34 @@ def info(user, **kwargs): # noqa
193272
title="List of supported compute backends",
194273
value=SUPPORTED_COMPUTE_BACKENDS,
195274
),
275+
default_kubernetes_cpu_request=dict(
276+
title="Default CPU request for Kubernetes jobs",
277+
value=REANA_KUBERNETES_JOBS_CPU_REQUEST,
278+
),
279+
default_kubernetes_cpu_limit=dict(
280+
title="Default CPU limit for Kubernetes jobs",
281+
value=REANA_KUBERNETES_JOBS_CPU_LIMIT,
282+
),
283+
default_kubernetes_memory_request=dict(
284+
title="Default memory request for Kubernetes jobs",
285+
value=REANA_KUBERNETES_JOBS_MEMORY_REQUEST,
286+
),
196287
default_kubernetes_memory_limit=dict(
197288
title="Default memory limit for Kubernetes jobs",
198289
value=REANA_KUBERNETES_JOBS_MEMORY_LIMIT,
199290
),
291+
kubernetes_max_cpu_request=dict(
292+
title="Maximum allowed CPU request for Kubernetes jobs",
293+
value=REANA_KUBERNETES_JOBS_MAX_USER_CPU_REQUEST,
294+
),
295+
kubernetes_max_cpu_limit=dict(
296+
title="Maximum allowed CPU limit for Kubernetes jobs",
297+
value=REANA_KUBERNETES_JOBS_MAX_USER_CPU_LIMIT,
298+
),
299+
kubernetes_max_memory_request=dict(
300+
title="Maximum allowed memory request for Kubernetes jobs",
301+
value=REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_REQUEST,
302+
),
200303
kubernetes_max_memory_limit=dict(
201304
title="Maximum allowed memory limit for Kubernetes jobs",
202305
value=REANA_KUBERNETES_JOBS_MAX_USER_MEMORY_LIMIT,
@@ -252,7 +355,13 @@ class InfoSchema(Schema):
252355
workspaces_available = fields.Nested(ListStringInfoValue)
253356
default_workspace = fields.Nested(StringInfoValue)
254357
compute_backends = fields.Nested(ListStringInfoValue)
358+
default_kubernetes_cpu_request = fields.Nested(StringNullableInfoValue)
359+
default_kubernetes_cpu_limit = fields.Nested(StringNullableInfoValue)
360+
default_kubernetes_memory_request = fields.Nested(StringNullableInfoValue)
255361
default_kubernetes_memory_limit = fields.Nested(StringInfoValue)
362+
kubernetes_max_cpu_request = fields.Nested(StringNullableInfoValue)
363+
kubernetes_max_cpu_limit = fields.Nested(StringNullableInfoValue)
364+
kubernetes_max_memory_request = fields.Nested(StringNullableInfoValue)
256365
kubernetes_max_memory_limit = fields.Nested(StringNullableInfoValue)
257366
maximum_workspace_retention_period = fields.Nested(StringNullableInfoValue)
258367
default_kubernetes_jobs_timeout = fields.Nested(StringInfoValue)

0 commit comments

Comments
 (0)