mirror of
https://github.com/gyptazy/ProxLB.git
synced 2026-04-05 20:31:57 +02:00
Fixes: #114 Fixes: #132 Fixes: #130 Fixes: #129 Fixes: #128 Fixes: #127 Fixes: #123 Fixes: #102
111 lines
6.2 KiB
Python
111 lines
6.2 KiB
Python
"""
|
|
The groups class is responsible for handling the correlations between the guests
|
|
and their groups like affinity and anti-affinity groups. To ensure a proper balancing
|
|
guests will ge grouped and then evaluated for further balancing.
|
|
"""
|
|
|
|
from typing import Dict, Any
|
|
from utils.logger import SystemdLogger
|
|
from utils.helper import Helper
|
|
|
|
logger = SystemdLogger()
|
|
|
|
|
|
class Groups:
|
|
"""
|
|
The groups class is responsible for handling the correlations between the guests
|
|
and their groups like affinity and anti-affinity groups. To ensure a proper balancing
|
|
guests will ge grouped and then evaluated for further balancing.
|
|
"""
|
|
|
|
def __init__(self, proxlb_data: Dict[str, Any]):
|
|
"""
|
|
Initializes the Groups class with the provided ProxLB data.
|
|
|
|
Args:
|
|
proxlb_data (Dict[str, Any]): The data required for balancing VMs and CTs.
|
|
"""
|
|
|
|
@staticmethod
|
|
def get_groups(guests: Dict[str, Any], nodes: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""
|
|
Generates and returns a dictionary of affinity and anti-affinity groups based on the provided data.
|
|
|
|
Args:
|
|
guests (Dict[str, Any]): A dictionary containing the guest data.
|
|
nodes (Dict[str, Any]): A dictionary containing the nodes data.
|
|
|
|
Returns:
|
|
Dict[str, Any]: A dictionary containing the created groups that includes:
|
|
* Affinity groups (or a randon and uniq group)
|
|
* Anti-affinity groups
|
|
* A list of guests that are currently placed on a node which
|
|
is defined to be in maintenance.
|
|
"""
|
|
logger.debug("Starting: get_groups.")
|
|
groups = {'groups': {'affinity': {}, 'anti_affinity': {}, 'maintenance': []}}
|
|
|
|
for guest_name, guest_meta in guests["guests"].items():
|
|
# Create affinity grouping
|
|
# Use an affinity group if available for the guest
|
|
if len(guest_meta["affinity_groups"]) > 0:
|
|
for affinity_group in guest_meta["affinity_groups"]:
|
|
group_name = affinity_group
|
|
logger.debug(f'Affinity group {affinity_group} for {guest_name} will be used.')
|
|
else:
|
|
# Generate a random uniq group name for the guest if
|
|
# the guest does not belong to any affinity group
|
|
random_group = Helper.get_uuid_string()
|
|
group_name = random_group
|
|
logger.debug(f'Random uniq group {random_group} for {guest_name} will be used.')
|
|
|
|
if not groups["groups"]["affinity"].get(group_name, False):
|
|
# Create group template with initial guest meta information
|
|
groups["groups"]["affinity"][group_name] = {}
|
|
groups["groups"]["affinity"][group_name]["guests"] = []
|
|
groups["groups"]["affinity"][group_name]["guests"].append(guest_name)
|
|
groups["groups"]["affinity"][group_name]["counter"] = 1
|
|
# Create groups resource template by the guests resources
|
|
groups["groups"]["affinity"][group_name]["cpu_total"] = guest_meta["cpu_total"]
|
|
groups["groups"]["affinity"][group_name]["cpu_used"] = guest_meta["cpu_used"]
|
|
groups["groups"]["affinity"][group_name]["memory_total"] = guest_meta["memory_total"]
|
|
groups["groups"]["affinity"][group_name]["memory_used"] = guest_meta["cpu_used"]
|
|
groups["groups"]["affinity"][group_name]["disk_total"] = guest_meta["disk_total"]
|
|
groups["groups"]["affinity"][group_name]["disk_used"] = guest_meta["cpu_used"]
|
|
else:
|
|
# Update group templates by guest meta information
|
|
groups["groups"]["affinity"][group_name]["guests"].append(guest_name)
|
|
groups["groups"]["affinity"][group_name]["counter"] += 1
|
|
# Update group resources by guest resources
|
|
groups["groups"]["affinity"][group_name]["cpu_total"] += guest_meta["cpu_total"]
|
|
groups["groups"]["affinity"][group_name]["cpu_used"] += guest_meta["cpu_used"]
|
|
groups["groups"]["affinity"][group_name]["memory_total"] += guest_meta["memory_total"]
|
|
groups["groups"]["affinity"][group_name]["memory_used"] += guest_meta["cpu_used"]
|
|
groups["groups"]["affinity"][group_name]["disk_total"] += guest_meta["disk_total"]
|
|
groups["groups"]["affinity"][group_name]["disk_used"] += guest_meta["cpu_used"]
|
|
|
|
# Create anti-affinity grouping
|
|
if len(guest_meta["anti_affinity_groups"]) > 0:
|
|
for anti_affinity_group in guest_meta["anti_affinity_groups"]:
|
|
anti_affinity_group_name = anti_affinity_group
|
|
logger.debug(f'Anti-affinity group {anti_affinity_group_name} for {guest_name} will be used.')
|
|
|
|
if not groups["groups"]["anti_affinity"].get(anti_affinity_group_name, False):
|
|
groups["groups"]["anti_affinity"][anti_affinity_group_name] = {}
|
|
groups["groups"]["anti_affinity"][anti_affinity_group_name]["guests"] = []
|
|
groups["groups"]["anti_affinity"][anti_affinity_group_name]["guests"].append(guest_name)
|
|
groups["groups"]["anti_affinity"][anti_affinity_group_name]["counter"] = 1
|
|
groups["groups"]["anti_affinity"][anti_affinity_group_name]["used_nodes"] = []
|
|
else:
|
|
groups["groups"]["anti_affinity"][anti_affinity_group_name]["guests"].append(guest_name)
|
|
groups["groups"]["anti_affinity"][anti_affinity_group_name]["counter"] += 1
|
|
|
|
# Create grouping of guests that are currently located on nodes that are
|
|
# marked as in maintenance and must be migrated
|
|
if nodes["nodes"][guest_meta["node_current"]]["maintenance"]:
|
|
logger.debug(f'{guest_name} will be migrated to another node because the underlying node {guest_meta["node_current"]} is defined to be in maintenance.')
|
|
groups["groups"]["maintenance"].append(guest_name)
|
|
|
|
logger.debug("Finished: get_groups.")
|
|
return groups
|