Skip to content

Commit 55c8851

Browse files
authored
Merge pull request #382 from gyptazy/fix/275-add-overprovisioning-safety-guard
fix(calculations): Add safety guard to avoid overprovisioning of nodes by memory
2 parents 490fb55 + 3d9f0eb commit 55c8851

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fixed:
2+
- Fixed missing overprovisioning safety guard to avoid node overprovisioning (@gyptazy). [#275]

‎proxlb/models/calculations.py‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,10 @@ def relocate_guests(proxlb_data: Dict[str, Any]):
387387
for guest_name in proxlb_data["groups"]["affinity"][group_name]["guests"]:
388388
mode = proxlb_data["meta"]["balancing"].get("mode", "used")
389389

390+
if not Calculations.validate_node_resources(proxlb_data, guest_name):
391+
logger.warning(f"Skipping relocation of guest {guest_name} due to insufficient resources on target node {proxlb_data['meta']['balancing']['balance_next_node']}. This might affect affinity group {group_name}.")
392+
continue
393+
390394
if mode == 'psi':
391395
logger.debug(f"Evaluating guest relocation based on {mode} mode.")
392396
method = proxlb_data["meta"]["balancing"].get("method", "memory")
@@ -707,3 +711,40 @@ def validate_current_anti_affinity(proxlb_data: Dict[str, Any], guest_name: str)
707711
return False
708712

709713
return True
714+
715+
@staticmethod
716+
def validate_node_resources(proxlb_data: Dict[str, Any], guest_name: str) -> bool:
717+
"""
718+
Validate that the target node has sufficient resources to host the specified guest.
719+
720+
This function checks if the target node, determined by the balancing logic,
721+
has enough CPU, memory, and disk resources available to accommodate the guest.
722+
723+
Args:
724+
proxlb_data (Dict[str, Any]): A dictionary containing the complete ProxLB state including:
725+
- "nodes": Dictionary with node resource information
726+
- "guests": Dictionary with guest resource requirements
727+
- "meta": Dictionary with balancing information including target node
728+
guest_name (str): The name of the guest to validate resources for
729+
Returns:
730+
bool: True if the target node has sufficient resources, False otherwise
731+
"""
732+
logger.debug("Starting: validate_node_resources.")
733+
node_target = proxlb_data["meta"]["balancing"]["balance_next_node"]
734+
735+
node_memory_free = proxlb_data["nodes"][node_target]["memory_free"]
736+
node_cpu_free = proxlb_data["nodes"][node_target]["cpu_free"]
737+
node_disk_free = proxlb_data["nodes"][node_target]["disk_free"]
738+
739+
guest_memory_required = proxlb_data["guests"][guest_name]["memory_used"]
740+
guest_cpu_required = proxlb_data["guests"][guest_name]["cpu_used"]
741+
guest_disk_required = proxlb_data["guests"][guest_name]["disk_used"]
742+
743+
if guest_memory_required < node_memory_free:
744+
logger.debug(f"Node '{node_target}' has sufficient resources for guest '{guest_name}'.")
745+
logger.debug("Finished: validate_node_resources.")
746+
return True
747+
else:
748+
logger.debug(f"Node '{node_target}' lacks sufficient resources for guest '{guest_name}'.")
749+
logger.debug("Finished: validate_node_resources.")
750+
return False

0 commit comments

Comments
 (0)