This commit is contained in:
gyptazy
2025-03-02 16:49:46 +01:00
parent 53723a0fdd
commit 0acc822777
4 changed files with 65 additions and 35 deletions

View File

@@ -145,23 +145,24 @@ The following options can be set in the configuration file `proxlb.yaml`:
| | ssl_verification | True | `Bool` | Validate SSL certificates (1) or ignore (0). (default: 1, type: bool) |
| | timeout | 10 | `Int` | Timeout for the Proxmox API in sec. (default: 10) |
| `proxmox_cluster` | | | | |
| | maintenance_nodes | ['virt66.example.com'] | `List` | A list of Proxmox nodes that are defined to be in a maintenance. |
| | ignore_nodes | [] | `List` | A list of Proxmox nodes that are defined to be ignored. |
| | overprovisioning | False | `Bool` | A list of Proxmox nodes that are defined to be ignored. |
| | maintenance_nodes | ['virt66.example.com'] | `List` | A list of Proxmox nodes that are defined to be in a maintenance. (default: []) |
| | ignore_nodes | [] | `List` | A list of Proxmox nodes that are defined to be ignored. (default: []) |
| | overprovisioning | False | `Bool` | Avoids balancing when nodes would become overprovisioned. |
| `balancing` | | | | |
| | enable | True | `Bool` | |
| | force | True | `Bool` | |
| | parallel | True | `Bool` | |
| | live | True | `Bool` | |
| | with_local_disks | True | `Bool` | |
| | balance_types | ['vm', 'ct'] | `List` | |
| | max_job_validation | 1800 | `Int` | Timeout for the Proxmox API in sec. (default: 10) |
| | balanciness | 1800 | `Int` | Timeout for the Proxmox API in sec. (default: 10) |
| | method | memory | `Str` | |
| | mode | rused | `Str` | |
| | enable | True | `Bool` | Enables the guest balancing. (default: True)|
| | force | True | `Bool` | Enforcing affinity/anti-affinity rules but balancing might become worse. (default: False) |
| | parallel | False | `Bool` | If guests should be moved in parallel or sequentially. (default: False)|
| | live | True | `Bool` | If guests should be moved live or shutdown. (default: True)|
| | with_local_disks | True | `Bool` | If balancing of guests should include local disks (default: True)|
| | balance_types | ['vm', 'ct'] | `List` | Defined the types of guests that should be honored. (default: ['vm', 'ct']) |
| | max_job_validation | 1800 | `Int` | How long a job validation may take in seconds. (default: 1800) |
| | balanciness | 10 | `Int` | The maximum delta of resource usage between node with highest and lowest usage. (default: 10) |
| | method | memory | `Str` | The balancing method that should be used. (default: memory | choices: memory, cpu, disk)|
| | mode | used | `Str` | The balancing mode that should be used. (default: used | choices: used, assigned)|
| `service` | | | | |
| | daemon | True | `Bool` | |
| | log_level | INFO | `Str` | |
| | daemon | False | `Bool` | If daemon mode should be activated (default: False)|
| | schedule | 12 | `Int` | How often rebalancing should occur in hours in daemon mode (default: 12)|
| | log_level | INFO | `Str` | Defines the default log level that should be logged. (default: INFO) |
An example of the configuration file looks like:
```
@@ -191,6 +192,7 @@ balancing:
service:
daemon: False
schedule: 12
log_level: DEBUG
```

View File

@@ -24,4 +24,5 @@ balancing:
service:
daemon: False
schedule: 12
log_level: DEBUG

View File

@@ -40,30 +40,34 @@ def main():
# Overwrite password after creating the API object
proxlb_config["proxmox_api"]["pass"] = "********"
# Get all required objects from the Proxmox cluster
meta = {"meta": proxlb_config}
nodes = Nodes.get_nodes(proxmox_api, proxlb_config)
guests = Guests.get_guests(proxmox_api, nodes)
groups = Groups.get_groups(guests, nodes)
while True:
# Get all required objects from the Proxmox cluster
meta = {"meta": proxlb_config}
nodes = Nodes.get_nodes(proxmox_api, proxlb_config)
guests = Guests.get_guests(proxmox_api, nodes)
groups = Groups.get_groups(guests, nodes)
# Merge obtained objects from the Proxmox cluster for further usage
proxlb_data = {**meta, **nodes, **guests, **groups}
Helper.log_node_metrics(proxlb_data)
# Merge obtained objects from the Proxmox cluster for further usage
proxlb_data = {**meta, **nodes, **guests, **groups}
Helper.log_node_metrics(proxlb_data)
# Update the initial node resource assignments
# by the previously created groups.
Calculations.set_node_assignments(proxlb_data)
Calculations.get_most_free_node(proxlb_data, cli_args.best_node)
Calculations.relocate_guests_on_maintenance_nodes(proxlb_data)
Calculations.get_balanciness(proxlb_data)
Calculations.relocate_guests(proxlb_data)
Helper.log_node_metrics(proxlb_data, init=False)
# Update the initial node resource assignments
# by the previously created groups.
Calculations.set_node_assignments(proxlb_data)
Calculations.get_most_free_node(proxlb_data, cli_args.best_node)
Calculations.relocate_guests_on_maintenance_nodes(proxlb_data)
Calculations.get_balanciness(proxlb_data)
Calculations.relocate_guests(proxlb_data)
Helper.log_node_metrics(proxlb_data, init=False)
# Perform balancing actions via Proxmox API
if not cli_args.dry_run:
Balancing(proxmox_api, proxlb_data)
# Perform balancing actions via Proxmox API
if not cli_args.dry_run:
Balancing(proxmox_api, proxlb_data)
logger.debug(f"Finished: __main__")
# Validate daemon mode
Helper.get_daemon_mode(proxlb_config)
logger.debug(f"Finished: __main__")
if __name__ == "__main__":

View File

@@ -5,6 +5,7 @@ classes.
import uuid
import sys
import time
import utils.version
from utils.logger import SystemdLogger
from typing import Dict, Any
@@ -80,3 +81,25 @@ class Helper:
if print_version:
print(f"{utils.version.__app_name__} version: {utils.version.__version__}\n(C) 2025 by {utils.version.__author__}\n{utils.version.__url__}")
sys.exit(0)
@staticmethod
def get_daemon_mode(proxlb_config: Dict[str, Any]) -> None:
"""
Checks if the daemon mode is active and handles the scheduling accordingly.
Parameters:
proxlb_config (Dict[str, Any]): A dictionary containing the ProxLB configuration.
Returns:
None
"""
logger.debug("Starting: get_daemon_mode.")
if proxlb_config.get("service", {}).get("daemon", False):
sleep_seconds = proxlb_config.get("service", {}).get("schedule", 12) * 3600
logger.info(f"Daemon mode active: Next run in: {proxlb_config.get('service', {}).get('schedule', 12)} hours.")
time.sleep(sleep_seconds)
else:
logger.debug("Daemon mode is not active.")
sys.exit(0)
logger.debug("Finished: get_daemon_mode.")