To fix a bug in the check_esxi_hardware monitoring plugin, I needed to find a way to do a "version check" in a condition. If the detected version (in semantic versioning format "X.Y.Z") is newer than a certain version number, then the executed code should be different. Luckily there's a fairly easy way to do this in Python.
Older versions of the Python pywbem module used the internal functions pywbem.cim_operations and pywbem.cim_http, which could be used as exception handlers and detect errors. For example authentication errors could be caught using pywbem.cim_http.AuthError.
But starting with pywbem 1.0.0, these internal functions were renamed and were prefixed with an underscore:
pywbem < 1.0.0 |
pywbem >= 1.0.0 |
pywbem.cim_operations | pywbem._cim_operations |
pywbem.cim_http.AuthError | pywbem._cim_http.AuthError |
Unfortunately this renaming causes a conflict now.
The original code would throw a Python traceback when executed with pywbem 1.0.0 or newer:
Traceback (most recent call last):
File "./check_esxi_hardware.py", line 757, in <module>
except pywbem.cim_operations.CIMError as args:
^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'pywbem' has no attribute 'cim_operations'. Did you mean: '_cim_operations'?
On the other hand, if the newer pywbem functions (with the prefixed underscore) is used on older pywbem versions (prior to 1.0.0), the following error shows up:
Traceback (most recent call last):
File "./check_esxi_hardware.py", line 796, in <module>
except pywbem._cim_operations.CIMError as args:
AttributeError: module 'pywbem' has no attribute '_cim_operations'
As, IMHO, monitoring plugins should be backward compatible as much as possible and support ongoing LTS versions (EL 8 and EL 9 distributions ship pywbem packages older than 1.0.0), I have to fix this and execute the relevant pywbem functions based on the detected pywbem version.
The most efficient (and easiest to implement) way to compare two versions is by using the packaging module, which contains a version sub-module. This sub-module is made for that specific purpose (handling versioning, doing comparisons, etc).
Here's an easy example:
ck@mint ~ $ cat /tmp/versioncomparison.py
#!/usr/bin/python3
import pywbem
from packaging.version import Version
pywbemversion = pywbem.__version__
print("Found pywbem version {}".format(pywbemversion))
if Version(pywbemversion) > Version("1.0.0"):
print("pywbem version {} is newer than 1.0.0".format(pywbemversion))
else:
print("pywbem version {} is older than 1.0.0".format(pywbemversion))
Code explained:
Let's run this thing:
ck@mint ~ $ /tmp/versioncomparison.py
Found pywbem version 1.7.2
pywbem version 1.7.2 is newer than 1.0.0
If I run the same code on a Rocky Linux 8 (with python3-packaging installed):
ck@rocky8 ~ $ /tmp/versioncomparison.py
Found pywbem version 0.11.0
pywbem version 0.11.0 is older than 1.0.0
Awesome. It worked.
Now I can go on and apply the same logic in check_esxi_hardware.
No comments yet.
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Influx Internet Java KVM Kibana Kodi Kubernetes LVM LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Observability Office OpenSearch PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder