Compare commits

..

1 Commits

Author SHA1 Message Date
gyptazy
39b4330994 feature: Add Debian native packaging 2025-03-04 11:48:36 +01:00
20 changed files with 85 additions and 127 deletions

View File

@@ -28,7 +28,7 @@ jobs:
- name: Check out repository
uses: actions/checkout@v3
with:
ref: ${{ github.ref }}
ref: 'development'
- name: Set up Docker with Debian image
run: |
@@ -39,13 +39,9 @@ jobs:
docker run --rm -v $(pwd):/workspace -w /workspace debian:latest bash -c "
# Install dependencies
apt-get update && \
apt-get install -y python3 python3-setuptools debhelper dh-python python3-pip python3-stdeb python3-proxmoxer python3-requests python3-urllib3 devscripts python3-all && \
# Build package using stdeb / setuptools
# python3 setup.py --command-packages=stdeb.command bdist_deb && \
# Build native package
dpkg-buildpackage -us -uc && \
mkdir package && \
mv ../*.deb package/ && \
apt-get install -y python3 python3-setuptools debhelper dh-python python3-pip python3-stdeb python3-proxmoxer python3-requests python3-urllib3 && \
# Build package
python3 setup.py --command-packages=stdeb.command bdist_deb && \
echo 'OK: Debian package successfully created.'
"
@@ -53,7 +49,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: debian-package
path: package/*.deb
path: deb_dist/*.deb
integration-test-debian:
needs: build-package-debian
@@ -63,16 +59,15 @@ jobs:
uses: actions/download-artifact@v4
with:
name: debian-package
path: package/
path: deb_dist/
- name: Set up Docker with Debian image
run: docker pull debian:latest
- name: Install and test Debian package in Docker container
run: |
docker run --rm -v $(pwd)/package:/package -w /package debian:latest bash -c "
docker run --rm -v $(pwd)/deb_dist:/deb_dist -w /deb_dist debian:latest bash -c "
apt-get update && \
apt-get install -y systemd && \
apt-get install -y ./proxlb*.deb && \
apt-get install -y ./python3-proxlb*.deb && \
python3 -c 'import proxlb; print(\"OK: Debian package successfully installed.\")'
"

View File

@@ -152,7 +152,7 @@ The following options can be set in the configuration file `proxlb.yaml`:
| | overprovisioning | False | `Bool` | Avoids balancing when nodes would become overprovisioned. |
| `balancing` | | | | |
| | enable | True | `Bool` | Enables the guest balancing. (default: True)|
| | enforce_affinity | True | `Bool` | Enforcing affinity/anti-affinity rules but balancing might become worse. (default: False) |
| | 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)|
@@ -184,7 +184,7 @@ proxmox_cluster:
balancing:
enable: True
enforce_affinity: False
force: False
parallel: False
live: True
with_local_disks: True

View File

@@ -15,7 +15,7 @@ proxmox_cluster:
balancing:
enable: True
enforce_affinity: False
force: False
parallel: False
live: True
with_local_disks: True
@@ -28,4 +28,4 @@ balancing:
service:
daemon: False
schedule: 12
log_level: DEBUG
log_level: DEBUG

5
debian/changelog vendored
View File

@@ -1,5 +0,0 @@
proxlb (1.1.0) stable; urgency=medium
* Refactored code base of ProxLB. (Closes: #114)
-- Florian Paul Azim Hoberg <gyptazy@gyptazy.com> Mon, 17 Mar 2025 18:55:02 +0000

12
debian/control vendored
View File

@@ -1,12 +0,0 @@
Source: proxlb
Maintainer: Florian Paul Azim Hoberg <gyptazy@gyptazy.com>
Section: admin
Priority: optional
Standards-Version: 4.5.0
Build-Depends: debhelper-compat (= 13), dh-python, python3-all, python3-setuptools
Package: proxlb
Architecture: all
Depends: ${python3:Depends}, ${misc:Depends}, python3-requests, python3-urllib3, python3-proxmoxer, python3-yaml
Description: A DRS alike Load Balancer for Proxmox Clusters
An advanced DRS alike loadbalancer for Proxmox clusters that also supports maintenance modes and affinity/anti-affinity rules.

2
debian/install vendored
View File

@@ -1,2 +0,0 @@
proxlb /usr/lib/python3/dist-packages/
service/proxlb.service /lib/systemd/system/

16
debian/postinst vendored
View File

@@ -1,16 +0,0 @@
#!/bin/bash
set -e
#DEBHELPER#
if [ "$1" = "configure" ]; then
systemctl enable proxlb.service
systemctl restart proxlb.service || true
# Create the 'plb' user if it does not exist
if ! id "plb" &>/dev/null; then
useradd --system --home /var/lib/proxlb --create-home --shell /usr/sbin/nologin --group nogroup plb
echo "User 'plb' created."
else
echo "User 'plb' already exists, skipping creation."
fi
fi

16
debian/prerm vendored
View File

@@ -1,16 +0,0 @@
#!/bin/bash
set -e
#DEBHELPER#
if [ "$1" = "remove" ]; then
systemctl stop proxlb.service || true
systemctl disable proxlb.service || true
# Remove the 'plb' user if it exists
if id "plb" &>/dev/null; then
userdel --remove plb
echo "User 'plb' removed."
else
echo "User 'plb' does not exist, skipping removal."
fi
fi

4
debian/rules vendored
View File

@@ -1,4 +0,0 @@
#!/usr/bin/make -f
%:
dh $@ --with python3 --buildsystem=pybuild

5
proxlb/debian/changelog Normal file
View File

@@ -0,0 +1,5 @@
python3-proxlb (1.1.0) unstable; urgency=medium
* Initial release
-- Florian Paul Azim Hoberg <gyptazy@gyptazy.com> Tue, 04 Mar 2025 12:00:00 +0000

14
proxlb/debian/control Normal file
View File

@@ -0,0 +1,14 @@
Source: python3-proxlb
Section: python
Priority: optional
Maintainer: Florian Paul Azim Hoberg <gyptazy@gyptazy.com>
Build-Depends: debhelper-compat (= 13), python3, dh-python, python3-setuptools
Standards-Version: 4.6.0
Homepage: https://github.com/gyptazy/ProxLB
Package: python3-proxlb
Architecture: all
Depends: ${python3:Depends}, ${misc:Depends}, python3-proxmoxer, python3-systemd, python3-yaml, python3-urllib3, python3-requests
Description: Load balancer for Proxmox clusters
An advanced DRS alike loadbalancer for Proxmox clusters that also supports
maintenance modes and affinity/anti-affinity rules.

11
proxlb/debian/copyright Normal file
View File

@@ -0,0 +1,11 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: python3-proxlb
Source: https://github.com/gyptazy/ProxLB
Files: *
Copyright: 2025 Florian Paul Azim Hoberg <gyptazy@gyptazy.com>
License: GPL-3.0-or-later
License: GPL-3.0-or-later
On Debian systems, the full text of the GPL-3.0-or-later license can be found
in the file /usr/share/common-licenses/GPL-3.

5
proxlb/debian/install Normal file
View File

@@ -0,0 +1,5 @@
main.py models usr/lib/python3/dist-packages/proxlb
models usr/lib/python3/dist-packages/proxlb
utils usr/lib/python3/dist-packages/proxlb
../service/proxlb.service lib/systemd/system
../config/proxlb_example.yaml etc/proxlb

18
proxlb/debian/postinst Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/sh
set -e
# Automatically inserted debhelper commands
#DEBHELPER#
# Check if user proxlb exists, if not, create it
if ! id -u proxlb >/dev/null 2>&1; then
useradd -m proxlb
echo "User proxlb created."
else
echo "User proxlb already exists."
fi
# Reload systemd
if [ "$1" = "configure" ]; then
systemd daemon-reload || exit 1
fi

11
proxlb/debian/prerm Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
set -e
# Automatically inserted debhelper commands
#DEBHELPER#
if [ "$1" = "remove" ]; then
systemd proxlb stop || true
systemd disable proxlb.service || true
systemd daemon-reload
fi

3
proxlb/debian/rules Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/make -f
%:
dh $@ --with python3

View File

@@ -207,13 +207,13 @@ class Calculations:
None
"""
logger.debug("Starting: relocate_guests.")
if proxlb_data["meta"]["balancing"]["balance"] or proxlb_data["meta"]["balancing"]["enforce_affinity"]:
if proxlb_data["meta"]["balancing"]["balance"] or proxlb_data["meta"]["balancing"]["force"]:
if proxlb_data["meta"]["balancing"].get("balance", False):
logger.debug("Balancing of guests will be performt. Reason: balanciness")
if proxlb_data["meta"]["balancing"].get("enforce_affinity", False):
logger.debug("Balancing of guests will be performt. Reason: enforce affinity balancing")
if proxlb_data["meta"]["balancing"].get("force", False):
logger.debug("Balancing of guests will be performt. Reason: force balancing")
for group_name in proxlb_data["groups"]["affinity"]:

View File

@@ -102,44 +102,6 @@ class ProxmoxApi:
"""
return getattr(self.proxmox_api, name)
def validate_config(self, proxlb_config: Dict[str, Any]) -> None:
"""
Validates the provided ProxLB configuration dictionary to ensure that it contains
the necessary credentials for authentication and that the credentials are not
mutually exclusive.
Args:
proxlb_config (Dict[str, Any]): A dictionary containing the ProxLB configuration.
It must include a "proxmox_api" key with a nested dictionary that contains
either "user" and "password" keys for username/password authentication or
"token_id" and "token_secret" keys for API token authentication.
Raises:
SystemExit: If both username/password and API token authentication methods are
provided, the function will log a critical error message and terminate
the program.
Logs:
Logs the start and end of the validation process. Logs a critical error if both
authentication methods are provided.
"""
logger.debug("Starting: validate_config.")
if not proxlb_config.get("proxmox_api", False):
logger.critical(f"Config error. Please check your proxmox_api chapter in your config file.")
print(f"Config error. Please check your proxmox_api chapter in your config file.")
sys.exit(1)
proxlb_credentials = proxlb_config["proxmox_api"]
present_auth_user = "user" in proxlb_credentials
present_auth_token = "token_id" in proxlb_credentials
if present_auth_user and present_auth_token:
logger.critical(f"Username/password and API token authentication are mutal exclusive. Please use only one!")
print(f"Username/password and API token authentication are mutal exclusive. Please use only one!")
sys.exit(1)
logger.debug("Finished: validate_config.")
def api_connect_get_hosts(self, proxmox_api_endpoints: list) -> str:
"""
Perform a connectivity test to determine a working host for the Proxmox API.
@@ -220,15 +182,7 @@ class ProxmoxApi:
bool: False if the Proxmox server is not reachable.
"""
logger.debug("Starting: test_api_proxmox_host.")
# Try resolving DNS to IP and log non-resolvable ones
try:
ip = socket.getaddrinfo(host, None, socket.AF_UNSPEC)
except socket.gaierror:
logger.warning(f"Could not resolve {host}.")
return False
# Validate if given object is IPv4 or IPv6
ip = socket.getaddrinfo(host, None, socket.AF_UNSPEC)
for address_type in ip:
if address_type[0] == socket.AF_INET:
logger.debug(f"{host} is type ipv4.")
@@ -337,9 +291,6 @@ class ProxmoxApi:
requests.exceptions.ConnectionError: If the connection to the Proxmox API is refused.
"""
logger.debug("Starting: api_connect.")
# Validate config
self.validate_config(proxlb_config)
# Get a valid Proxmox API endpoint
proxmox_api_endpoint = self.api_connect_get_hosts(proxlb_config.get("proxmox_api", {}).get("hosts", []))

View File

@@ -1,11 +1,11 @@
[Unit]
Description=ProxLB - A loadbalancer for Proxmox clusters
Description=ProxLB - A load balancer for Proxmox clusters
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=python3 /usr/lib/python3/dist-packages/proxlb/main.py -c /etc/proxlb/proxlb.yaml
User=plb
User=proxlb
[Install]
WantedBy=multi-user.target