Skip to content

Commit 714ae7c

Browse files
authored
feat: new container specs, allow decimal CPUs units (#337)
* feat: prices for new container specs * fix: remove wrong price tier * fix: allow decimals cpu usage * fix: use 512m instead of 0.5g in resources specs * chore: inc ver
1 parent 31f5098 commit 714ae7c

File tree

7 files changed

+42
-10
lines changed

7 files changed

+42
-10
lines changed

extensions/business/container_apps/container_app_runner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2065,7 +2065,7 @@ def start_container(self):
20652065

20662066
self.P(log_str)
20672067

2068-
nano_cpu_limit = self._cpu_limit * 1_000_000_000
2068+
nano_cpu_limit = int(self._cpu_limit * 1_000_000_000)
20692069
mem_reservation = f"{parse_memory_to_mb(self._mem_limit, 0.9)}m"
20702070

20712071
run_kwargs = dict(

extensions/business/container_apps/container_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def _setup_resource_limits_and_ports(self):
307307

308308
container_resources = self.cfg_container_resources
309309
if isinstance(container_resources, dict) and len(container_resources) > 0:
310-
self._cpu_limit = int(container_resources.get("cpu", DEFAULT_CPU_LIMIT))
310+
self._cpu_limit = float(container_resources.get("cpu", DEFAULT_CPU_LIMIT))
311311
self._gpu_limit = container_resources.get("gpu", DEFAULT_GPU_LIMIT)
312312
self._mem_limit = container_resources.get("memory", DEFAULT_MEM_LIMIT)
313313

@@ -417,7 +417,7 @@ def _setup_resource_limits_and_ports(self):
417417
# endif main_port_mapped
418418
else:
419419
# No container resources specified, use defaults
420-
self._cpu_limit = DEFAULT_CPU_LIMIT
420+
self._cpu_limit = float(DEFAULT_CPU_LIMIT)
421421
self._gpu_limit = DEFAULT_GPU_LIMIT
422422
self._mem_limit = DEFAULT_MEM_LIMIT
423423

extensions/business/deeploy/deeploy_const.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ class DEFAULT_CONTAINER_RESOURCES:
144144

145145
JOB_TYPE_RESOURCE_SPECS = {
146146
# Generic Apps
147+
53: {DEEPLOY_RESOURCES.CPU: 0.25, DEEPLOY_RESOURCES.MEMORY: '512m', DEEPLOY_RESOURCES.STORAGE: '2g'}, # micro
148+
54: {DEEPLOY_RESOURCES.CPU: 0.5, DEEPLOY_RESOURCES.MEMORY: '1g', DEEPLOY_RESOURCES.STORAGE: '4g'}, # lite
147149
1: {DEEPLOY_RESOURCES.CPU: 1, DEEPLOY_RESOURCES.MEMORY: '2g', DEEPLOY_RESOURCES.STORAGE: '8g'}, # entry
148150
2: {DEEPLOY_RESOURCES.CPU: 2, DEEPLOY_RESOURCES.MEMORY: '4g', DEEPLOY_RESOURCES.STORAGE: '16g'}, # low1
149151
3: {DEEPLOY_RESOURCES.CPU: 2, DEEPLOY_RESOURCES.MEMORY: '8g', DEEPLOY_RESOURCES.STORAGE: '32g'}, # low2

extensions/business/deeploy/deeploy_manager_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ def create_pipeline(
447447
For CONTAINER_APP_RUNNER:
448448
- IMAGE : str (required)
449449
- CONTAINER_RESOURCES : dict (required)
450-
- cpu : int
450+
- cpu : int | float
451451
- memory : str (e.g., "4096m", "4g")
452452
- CR, PORT, ENV, VOLUMES, TUNNEL_ENGINE_ENABLED, etc.
453453
For native plugins:

extensions/business/deeploy/deeploy_mixin.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,13 @@ def _validate_plugin_instance_for_signature(self, signature: str, plugin_instanc
728728
f"{DEEPLOY_ERRORS.REQUEST6}. Plugin instance{index_str} with signature '{signature}': 'CONTAINER_RESOURCES.cpu' is required."
729729
)
730730

731+
try:
732+
self._parse_cpu_value(resources.get(DEEPLOY_RESOURCES.CPU), default=None)
733+
except ValueError:
734+
raise ValueError(
735+
f"{DEEPLOY_ERRORS.REQUEST6}. Plugin instance{index_str} with signature '{signature}': 'CONTAINER_RESOURCES.cpu' must be a number."
736+
)
737+
731738
if DEEPLOY_RESOURCES.MEMORY not in resources:
732739
raise ValueError(
733740
f"{DEEPLOY_ERRORS.REQUEST6}. Plugin instance{index_str} with signature '{signature}': 'CONTAINER_RESOURCES.memory' is required."
@@ -1087,6 +1094,17 @@ def deeploy_get_auth_result(self, inputs):
10871094
}
10881095
return result
10891096

1097+
def _parse_cpu_value(self, value, default=None):
1098+
"""
1099+
Parse CPU value as float, allowing numeric strings.
1100+
"""
1101+
if value is None:
1102+
return default
1103+
try:
1104+
return float(value)
1105+
except (TypeError, ValueError):
1106+
raise ValueError(f"{DEEPLOY_ERRORS.REQUEST6}. 'CONTAINER_RESOURCES.cpu' must be a number.")
1107+
10901108
def _aggregate_container_resources(self, inputs):
10911109
"""
10921110
Aggregate container resources across all CONTAINER_APP_RUNNER plugin instances.
@@ -1110,11 +1128,17 @@ def _aggregate_container_resources(self, inputs):
11101128
self.Pd("Using legacy format (app_params) for resource aggregation")
11111129
app_params = inputs.get(DEEPLOY_KEYS.APP_PARAMS, {})
11121130
legacy_resources = app_params.get(DEEPLOY_RESOURCES.CONTAINER_RESOURCES, {})
1131+
if isinstance(legacy_resources, dict):
1132+
legacy_resources = self.deepcopy(legacy_resources)
1133+
if DEEPLOY_RESOURCES.CPU in legacy_resources:
1134+
legacy_resources[DEEPLOY_RESOURCES.CPU] = self._parse_cpu_value(
1135+
legacy_resources.get(DEEPLOY_RESOURCES.CPU)
1136+
)
11131137
self.Pd(f"Legacy resources: {legacy_resources}")
11141138
return legacy_resources
11151139

11161140
self.Pd(f"Processing {len(plugins_array)} plugin instances from plugins array")
1117-
total_cpu = 0
1141+
total_cpu = 0.0
11181142
total_memory_mb = 0
11191143

11201144
# Iterate through plugins array (simplified format - each object is an instance)
@@ -1125,7 +1149,7 @@ def _aggregate_container_resources(self, inputs):
11251149
# Only aggregate for CONTAINER_APP_RUNNER and WORKER_APP_RUNNER plugins
11261150
if signature in CONTAINERIZED_APPS_SIGNATURES:
11271151
resources = plugin_instance.get(DEEPLOY_RESOURCES.CONTAINER_RESOURCES, {})
1128-
cpu = resources.get(DEEPLOY_RESOURCES.CPU, 0)
1152+
cpu = self._parse_cpu_value(resources.get(DEEPLOY_RESOURCES.CPU, 0))
11291153
memory = resources.get(DEEPLOY_RESOURCES.MEMORY, "0m")
11301154

11311155
self.Pd(f" Container resources: cpu={cpu}, memory={memory}")

extensions/business/deeploy/deeploy_target_nodes_mixin.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,10 @@ def __find_suitable_nodes_for_container_app(self, nodes_with_resources, containe
164164
self.Pd(f"Starting __find_suitable_nodes_for_container_app with {len(nodes_with_resources)} candidate nodes")
165165
suitable_nodes = {}
166166

167-
required_cpu = container_requested_resources.get(DEEPLOY_RESOURCES.CPU, DEFAULT_CONTAINER_RESOURCES.CPU)
167+
required_cpu = self._parse_cpu_value(
168+
container_requested_resources.get(DEEPLOY_RESOURCES.CPU, DEFAULT_CONTAINER_RESOURCES.CPU),
169+
default=DEFAULT_CONTAINER_RESOURCES.CPU,
170+
)
168171
required_mem = container_requested_resources.get(DEEPLOY_RESOURCES.MEMORY, DEFAULT_CONTAINER_RESOURCES.MEMORY)
169172
required_mem_bytes = self._parse_memory(required_mem)
170173

@@ -225,10 +228,13 @@ def __find_suitable_nodes_for_container_app(self, nodes_with_resources, containe
225228
continue
226229
self.Pd(f"Node {addr} has {self.json_dumps(used_container_resources)} used container resources.")
227230
# Sum up resources used by node.
228-
used_cpu = 0
231+
used_cpu = 0.0
229232
used_memory = 0
230233
for res in used_container_resources:
231-
cpu = int(res.get(DEEPLOY_RESOURCES.CPU, DEFAULT_CONTAINER_RESOURCES.CPU))
234+
cpu = self._parse_cpu_value(
235+
res.get(DEEPLOY_RESOURCES.CPU, DEFAULT_CONTAINER_RESOURCES.CPU),
236+
default=DEFAULT_CONTAINER_RESOURCES.CPU,
237+
)
232238
memory = res.get(DEEPLOY_RESOURCES.MEMORY, DEFAULT_CONTAINER_RESOURCES.MEMORY)
233239
used_cpu += cpu
234240
used_memory += self._parse_memory(memory)

ver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__VER__ = '2.9.973'
1+
__VER__ = '2.9.974'

0 commit comments

Comments
 (0)