@@ -78,7 +78,7 @@ def get_nodes(proxmox_api: any, proxlb_config: Dict[str, Any]) -> Dict[str, Any]
7878 nodes ["nodes" ][node ["node" ]]["cpu_pressure_some_spikes_percent" ] = Nodes .get_node_rrd_data (proxmox_api , node ["node" ], "cpu" , "some" , spikes = True )
7979 nodes ["nodes" ][node ["node" ]]["cpu_pressure_full_spikes_percent" ] = Nodes .get_node_rrd_data (proxmox_api , node ["node" ], "cpu" , "full" , spikes = True )
8080 nodes ["nodes" ][node ["node" ]]["cpu_pressure_hot" ] = False
81- nodes ["nodes" ][node ["node" ]]["memory_total" ] = node ["maxmem" ]
81+ nodes ["nodes" ][node ["node" ]]["memory_total" ] = Nodes . set_node_resource_reservation ( node ["node" ], node [ " maxmem" ], proxlb_config , "memory" )
8282 nodes ["nodes" ][node ["node" ]]["memory_assigned" ] = 0
8383 nodes ["nodes" ][node ["node" ]]["memory_used" ] = node ["mem" ]
8484 nodes ["nodes" ][node ["node" ]]["memory_free" ] = node ["maxmem" ] - node ["mem" ]
@@ -103,7 +103,6 @@ def get_nodes(proxmox_api: any, proxlb_config: Dict[str, Any]) -> Dict[str, Any]
103103 nodes ["nodes" ][node ["node" ]]["disk_pressure_full_spikes_percent" ] = Nodes .get_node_rrd_data (proxmox_api , node ["node" ], "disk" , "full" , spikes = True )
104104 nodes ["nodes" ][node ["node" ]]["disk_pressure_hot" ] = False
105105
106- Nodes .apply_resource_reservation (nodes ["nodes" ][node ["node" ]]["name" ], proxlb_config , nodes ["nodes" ][node ["node" ]])
107106 # Evaluate if node should be set to maintenance mode
108107 if Nodes .set_node_maintenance (proxmox_api , proxlb_config , node ["node" ]):
109108 nodes ["nodes" ][node ["node" ]]["maintenance" ] = True
@@ -257,51 +256,56 @@ def get_node_pve_version(proxmox_api, node_name: str) -> float:
257256 return version ["version" ]
258257
259258 @staticmethod
260- def apply_resource_reservation (node_name , proxlb_config : Dict [ str , Any ], node_data : Dict [ str , Any ] ) -> None :
259+ def set_node_resource_reservation (node_name , resource_value , proxlb_config , resource_type ) -> int :
261260 """
262- Check if there is a a configured resource reservation for the current nodes and apply it as needed.
261+ Check if there is a configured resource reservation for the current node and apply it as needed.
263262 Checks for a node specific config first, then if there is any configured default and if neither then nothing is reserved.
264- Reservations are applied by directly modifying the data gathered from the nodes .
263+ Reservations are applied by directly modifying the resource value .
265264
266265 Args:
267- node_name: (str) the name of the node
268- proxlb_config (Dict[str, Any]): A dictionary containing the ProxLB configuration.
269- node_data: (Dict[str, Any]): Dict containing the current nodes data
270- Returns: none
266+ node_name (str): The name of the node.
267+ resource_value (int): The total resource value in bytes.
268+ proxlb_config (Dict[str, Any]): A dictionary containing the ProxLB configuration.
269+ resource_type (str): The type of resource ('memory', 'disk', etc.).
270+
271+ Returns:
272+ int: The resource value after applying any configured reservations.
271273 """
272274 logger .debug (f"Starting: apply_resource_reservation" )
275+
273276 balancing_cfg = proxlb_config .get ("balancing" , {})
274277 reserve_cfg = balancing_cfg .get ("node_resource_reserve" , {})
275- reserved_memory_gb_node = reserve_cfg .get (node_name , {}).get ("memory" )
276- reserved_memory_gb_default = reserve_cfg .get ("defaults" , {}).get ("memory" , 0 )
277-
278- # Make sure the reservation is a numeric value - check for both, default and node specific
279- if not isinstance (reserved_memory_gb_default , (int , float )):
280- if reserved_memory_gb_default is not None :
281- logger .info ("Invalid default memory reservation: Found a string while expecting a numeric value - skipping default reservation" )
282- reserved_memory_gb_default = 0
283-
284- if not isinstance (reserved_memory_gb_node , (int , float )):
285- if reserved_memory_gb_node is not None :
286- logger .info (f"Invalid memory reservation: Found a string while expecting a numeric value - applying current default of { reserved_memory_gb_default } Bytes" )
287- reserved_memory_gb_node = reserved_memory_gb_default
288-
289- # Make sure the reservation is positive
290- if reserved_memory_gb_node < 0 :
291- logger .info (f"{ nodes ['nodes' ][node ['node' ]]['name' ]} : Invalid assigned memory reservation, applying defaults" )
292- reserved_memory_gb_node = reserved_memory_gb_default
293-
294- # Convert the reservation from GB to Bytes, get the current nodes physical memory
295- reserved_memory_node = int (round (reserved_memory_gb_node * 1024 ** 3 ))
296- total_mem = node_data .get ("memory_total" )
297-
298- # Check if the reservation doesnt exceed the nodes total memory
299- if reserved_memory_node > total_mem :
300- logger .debug (f"Reservation of { reserved_memory_node } Bytes exceeds available memory of { total_mem } Bytes- skipping reservation" )
301- reserved_memory_node = 0
302- reserved_memory_gb_node = 0
303-
304- logger .debug (f"Reserved Memory: { reserved_memory_gb_node } GB ({ reserved_memory_node } Bytes)" )
305- node_data ["memory_total" ] -= reserved_memory_node
306- Helper .update_node_resource_percentages (node_data )
307- logger .debug (f"Finished: apply_resource_reservation" )
278+ node_resource_reservation = reserve_cfg .get (node_name , {}).get (resource_type , 0 )
279+ default_resource_reservation = reserve_cfg .get ("defaults" , {}).get (resource_type , 0 )
280+
281+ if reserve_cfg .get ("defaults" , None ):
282+ logger .debug (f"Applying resource reservation from config." )
283+
284+ # Ensure reservations are numeric values
285+ node_resource_reservation = node_resource_reservation if isinstance (node_resource_reservation , (int , float )) else 0
286+ default_resource_reservation = default_resource_reservation if isinstance (default_resource_reservation , (int , float )) else 0
287+
288+ # Apply node specific reservation if set
289+ if node_resource_reservation > 0 :
290+ if resource_value < (node_resource_reservation * 1024 ** 3 ):
291+ logger .critical (f"Configured resource reservation for node { node_name } of type { resource_type } with { node_resource_reservation } GB is higher than available resource value { resource_value / (1024 ** 3 ):.2f} GB. Not applying..." )
292+ return resource_value
293+ else :
294+ logger .debug (f"Applying node specific reservation for { node_name } of type { resource_type } with { node_resource_reservation } GB" )
295+ resource_value -= (node_resource_reservation * 1024 ** 3 )
296+ return resource_value
297+
298+ # Apply default reservation if set and no node specific reservation has been performed
299+ elif default_resource_reservation > 0 :
300+ if resource_value < (default_resource_reservation * 1024 ** 3 ):
301+ logger .critical (f"Configured default reservation for node { node_name } of type { resource_type } with { default_resource_reservation } GB is higher than available resource value { resource_value / (1024 ** 3 ):.2f} GB. Not applying..." )
302+ return resource_value
303+ else :
304+ logger .debug (f"Applying default reservation for { node_name } of type { resource_type } with { default_resource_reservation } GB" )
305+ resource_value -= (default_resource_reservation * 1024 ** 3 )
306+ return resource_value
307+
308+ else :
309+ logger .debug (f"No default or node specific resource reservation for node { node_name } found. Skipping..." )
310+ logger .debug (f"Finished: apply_resource_reservation" )
311+ return resource_value
0 commit comments