From 620bef47c680498c9022d29ab591ec58fa583e8f Mon Sep 17 00:00:00 2001 From: Software Management Team Date: Thu, 30 May 2024 12:46:46 +0200 Subject: [PATCH 01/15] Eliminate use of obsolete %patchN syntax (#2283636) --- ganglia.spec | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ganglia.spec b/ganglia.spec index 9bc2e09..199eb34 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -142,10 +142,10 @@ programmers can use to build scalable cluster or grid applications %prep %setup -q -%patch0 -p1 -%patch1 -p1 +%patch -P0 -p1 +%patch -P1 -p1 %if 0%{?fedora} || 0%{?rhel} > 7 -%patch10 -p1 +%patch -P10 -p1 %endif # fix broken systemd support install -m 0644 %{SOURCE2} gmond/gmond.service.in @@ -154,8 +154,8 @@ install -m 0644 %{SOURCE3} gmetad/gmetad.service.in %setup -q -T -D -a 1 mv ganglia-web-%{webver} web pushd web -%patch20 -p1 -%patch21 -p1 +%patch -P20 -p1 +%patch -P21 -p1 popd %build From 349830c918fde037676ece3b0f24ce9f1e4af8ca Mon Sep 17 00:00:00 2001 From: Terje Rosten Date: Mon, 24 Jun 2024 19:07:28 +0200 Subject: [PATCH 02/15] Add Python 3 support in gmond --- ganglia-3.7.2-autoconf-python3.patch | 32 + ganglia-gmond-python2to3-modules.patch | 1048 ++++++++++++++++++++++++ ganglia-gmond-python2to3.patch | 176 ++++ ganglia.spec | 89 +- 4 files changed, 1325 insertions(+), 20 deletions(-) create mode 100644 ganglia-3.7.2-autoconf-python3.patch create mode 100644 ganglia-gmond-python2to3-modules.patch create mode 100644 ganglia-gmond-python2to3.patch diff --git a/ganglia-3.7.2-autoconf-python3.patch b/ganglia-3.7.2-autoconf-python3.patch new file mode 100644 index 0000000..8fd84f4 --- /dev/null +++ b/ganglia-3.7.2-autoconf-python3.patch @@ -0,0 +1,32 @@ +diff --git a/configure.ac b/configure.ac +index fe7983b..d0a6d18 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -319,22 +319,17 @@ if test x"$enable_python" = xyes; then + if test -n "$PYTHON_BIN"; then + # find out python version + AC_MSG_CHECKING(Python version) +- PyVERSION=`$PYTHON_BIN -c ['import sys; print sys.version[:3]'`] +- PyMAJVERSION=`$PYTHON_BIN -c ['import sys; print sys.version[:1]'`] ++ PyVERSION=`$PYTHON_BIN -c ['import sys; print("%s.%s%s" % (sys.version_info.major, sys.version_info.minor, sys.abiflags))'`] ++ PyMAJVERSION=`$PYTHON_BIN -c ['import sys; print(sys.version_info.major)'`] + AC_MSG_RESULT($PyVERSION) + PYTHON_VERSION=$PyVERSION + AC_SUBST(PYTHON_VERSION) +- +- PyEXEC_INSTALLDIR=`$PYTHON_BIN -c "import sys; print sys.exec_prefix"` +- if test -f "$PyEXEC_INSTALLDIR/include/python/Python.h"; then +- PYTHON_INCLUDES="-I$PyEXEC_INSTALLDIR/include/python" ++ PyINC_DIR=`$PYTHON_BIN -c ['import sysconfig; print(sysconfig.get_paths()["include"])'`] ++ if test -f "$PyINC_DIR/Python.h"; then ++ PYTHON_INCLUDES="-I$PyINC_DIR" + else +- if test -f "$PyEXEC_INSTALLDIR/include/python$PyVERSION/Python.h"; then +- PYTHON_INCLUDES="-I$PyEXEC_INSTALLDIR/include/python$PyVERSION" +- else + PYTHON_INCLUDES="" + enable_python="no" +- fi + fi + AC_SUBST(PYTHON_INCLUDES) + else diff --git a/ganglia-gmond-python2to3-modules.patch b/ganglia-gmond-python2to3-modules.patch new file mode 100644 index 0000000..9d8ffeb --- /dev/null +++ b/ganglia-gmond-python2to3-modules.patch @@ -0,0 +1,1048 @@ +diff --git a/gmond/python_modules/apache_status/apache_status.py b/gmond/python_modules/apache_status/apache_status.py +index e33e5ea..bfc2bae 100755 +--- a/gmond/python_modules/apache_status/apache_status.py ++++ b/gmond/python_modules/apache_status/apache_status.py +@@ -4,7 +4,7 @@ + import os + import threading + import time +-import urllib2 ++import urllib.request, urllib.error, urllib.parse + import traceback + import re + import copy +@@ -44,7 +44,7 @@ Scoreboard = { + NAME_PREFIX + 'idle' : {'key': 'I', 'desc': 'Idle cleanup of worker'}, + NAME_PREFIX + 'open_slot' : {'key': '.', 'desc': 'Open slot with no current process'}, + } +-Scoreboard_bykey = dict([(v["key"], k) for (k, v) in Scoreboard.iteritems()]) ++Scoreboard_bykey = dict([(v["key"], k) for (k, v) in Scoreboard.items()]) + + SSL_REGEX = re.compile('^(cache type:) (.*)()(?P[0-9]+)( bytes, current sessions: )(?P[0-9]+)(
subcaches: )(?P[0-9]+)(, indexes per subcache: )(?P[0-9]+)(
)(.*)(
index usage: )(?P[0-9]+)(%, cache usage: )(?P[0-9]+)(%
total sessions stored since starting: )(?P[0-9]+)(
total sessions expired since starting: )(?P[0-9]+)(
total \(pre-expiry\) sessions scrolled out of the cache: )(?P[0-9]+)(
total retrieves since starting: )(?P[0-9]+)( hit, )(?P[0-9]+)( miss
total removes since starting: )(?P[0-9]+)( hit, )(?P[0-9]+)') + # Good for Apache 2.2 +@@ -67,17 +67,17 @@ def get_metrics(): + + if (time.time() - METRICS['time']) > METRICS_CACHE_MAX: + +- metrics = dict([(k, 0) for k in Scoreboard.keys()]) ++ metrics = dict([(k, 0) for k in list(Scoreboard.keys())]) + + # This is the short server-status. Lacks SSL metrics + try: +- req = urllib2.Request(SERVER_STATUS_URL + "?auto") ++ req = urllib.request.Request(SERVER_STATUS_URL + "?auto") + + # Download the status file + if sys.version_info < (2, 6): +- res = urllib2.urlopen(req) ++ res = urllib.request.urlopen(req) + else: +- res = urllib2.urlopen(req, timeout=2) ++ res = urllib.request.urlopen(req, timeout=2) + + for line in res: + split_line = line.rstrip().split(": ") +@@ -92,20 +92,20 @@ def get_metrics(): + metric_name = long_metric_name + metrics[metric_name] = split_line[1] + +- except urllib2.URLError: ++ except urllib.error.URLError: + traceback.print_exc() + + # If we are collecting SSL metrics we'll do + if COLLECT_SSL: + + try: +- req2 = urllib2.Request(SERVER_STATUS_URL) ++ req2 = urllib.request.Request(SERVER_STATUS_URL) + + # Download the status file + if sys.version_info < (2, 6): +- res = urllib2.urlopen(req2) ++ res = urllib.request.urlopen(req2) + else: +- res = urllib2.urlopen(req2, timeout=2) ++ res = urllib.request.urlopen(req2, timeout=2) + + for line in res: + regMatch = SSL_REGEX.match(line) +@@ -115,7 +115,7 @@ def get_metrics(): + #print SSL_NAME_PREFIX + key + "=" + linebits[key] + metrics[SSL_NAME_PREFIX + key] = linebits[key] + +- except urllib2.URLError: ++ except urllib.error.URLError: + traceback.print_exc() + + LAST_METRICS = copy.deepcopy(METRICS) +@@ -134,7 +134,7 @@ def get_value(name): + + try: + result = metrics['data'][name] +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -155,7 +155,7 @@ def get_delta(name): + try: + delta = multiplier * (float(curr_metrics['data'][name]) - float(last_metrics['data'][name])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -165,7 +165,7 @@ def get_delta(name): + + def create_desc(prop): + d = Desc_Skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -173,8 +173,8 @@ def create_desc(prop): + def metric_init(params): + global descriptors, Desc_Skel, SERVER_STATUS_URL, COLLECT_SSL + +- print '[apache_status] Received the following parameters' +- print params ++ print('[apache_status] Received the following parameters') ++ print(params) + + if "metric_group" not in params: + params["metric_group"] = "apache" +@@ -261,7 +261,7 @@ def metric_init(params): + "description": "Uptime", + })) + +- for k, v in Scoreboard.iteritems(): ++ for k, v in Scoreboard.items(): + descriptors.append(create_desc({ + "name" : k, + "call_back" : get_value, +@@ -400,9 +400,9 @@ if __name__ == '__main__': + for d in descriptors: + v = d['call_back'](d['name']) + if d['name'] == NAME_PREFIX + "rps": +- print 'value for %s is %.4f' % (d['name'], v) ++ print('value for %s is %.4f' % (d['name'], v)) + else: +- print 'value for %s is %s' % (d['name'], v) ++ print('value for %s is %s' % (d['name'], v)) + time.sleep(15) + except KeyboardInterrupt: + os._exit(1) +diff --git a/gmond/python_modules/cpu/cpu_stats.py b/gmond/python_modules/cpu/cpu_stats.py +index 5a8ebb8..16d6165 100644 +--- a/gmond/python_modules/cpu/cpu_stats.py ++++ b/gmond/python_modules/cpu/cpu_stats.py +@@ -75,7 +75,7 @@ def get_value(name): + + try: + result = metrics['data'][name][0] +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -97,7 +97,7 @@ def get_delta(name): + try: + delta = (float(curr_metrics['data'][name][0]) - float(last_metrics['data'][name][0])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -124,7 +124,7 @@ def get_softirq_delta(name): + try: + delta = (float(curr_metrics['data']['softirq'][index]) - float(last_metrics['data']['softirq'][index])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -134,7 +134,7 @@ def get_softirq_delta(name): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -279,6 +279,6 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print '%s = %s' % (d['name'], v) +- print 'Sleeping 15 seconds' ++ print('%s = %s' % (d['name'], v)) ++ print('Sleeping 15 seconds') + time.sleep(5) +diff --git a/gmond/python_modules/db/DBUtil.py b/gmond/python_modules/db/DBUtil.py +index 2504c24..66f8a78 100644 +--- a/gmond/python_modules/db/DBUtil.py ++++ b/gmond/python_modules/db/DBUtil.py +@@ -51,7 +51,7 @@ except: + args = tuple() + else: + args = self.default_factory, +- return type(self), args, None, None, self.items() ++ return type(self), args, None, None, list(self.items()) + def copy(self): + return self.__copy__() + def __copy__(self): +@@ -59,7 +59,7 @@ except: + def __deepcopy__(self, memo): + import copy + return type(self)(self.default_factory, +- copy.deepcopy(self.items())) ++ copy.deepcopy(list(self.items()))) + def __repr__(self): + return 'defaultdict(%s, %s)' % (self.default_factory, + dict.__repr__(self)) +@@ -77,7 +77,7 @@ def is_hex(s): + def longish(x): + if len(x): + try: +- return long(x) ++ return int(x) + except ValueError: + if(x.endswith(',')): + return longish(x[:-1]) +@@ -92,7 +92,7 @@ def longish(x): + def hexlongish(x): + if len(x): + try: +- return long(str(x), 16) ++ return int(str(x), 16) + except ValueError: + return longish(x[:-1]) + else: +@@ -101,7 +101,7 @@ def hexlongish(x): + def parse_innodb_status(innodb_status_raw, innodb_version="1.0"): + def sumof(status): + def new(*idxs): +- return sum(map(lambda x: longish(status[x]), idxs)) ++ return sum([longish(status[x]) for x in idxs]) + return new + + innodb_status = defaultdict(int) +@@ -280,5 +280,6 @@ if __name__ == '__main__': + cursor.close() + + conn.close() +- except MySQLdb.OperationalError, (errno, errmsg): ++ except MySQLdb.OperationalError as xxx_todo_changeme: ++ (errno, errmsg) = xxx_todo_changeme.args + raise +diff --git a/gmond/python_modules/db/mysql.py b/gmond/python_modules/db/mysql.py +index 7b5ab59..065a6cd 100644 +--- a/gmond/python_modules/db/mysql.py ++++ b/gmond/python_modules/db/mysql.py +@@ -154,7 +154,7 @@ def update_stats(get_innodb=True, get_master=True, get_slave=True): + cursor.execute("SHOW SLAVE STATUS") + res = cursor.fetchone() + if res: +- for (k,v) in res.items(): ++ for (k,v) in list(res.items()): + slave_status[k.lower()] = v + else: + get_slave = False +@@ -165,7 +165,8 @@ def update_stats(get_innodb=True, get_master=True, get_slave=True): + cursor.close() + + conn.close() +- except MySQLdb.OperationalError, (errno, errmsg): ++ except MySQLdb.OperationalError as xxx_todo_changeme: ++ (errno, errmsg) = xxx_todo_changeme.args + logging.error('error updating stats') + logging.error(errmsg) + return False +@@ -1097,9 +1098,9 @@ def metric_init(params): + + for stats_descriptions in (innodb_stats_descriptions, master_stats_descriptions, misc_stats_descriptions, slave_stats_descriptions): + for label in stats_descriptions: +- if mysql_stats.has_key(label): ++ if label in mysql_stats: + format = '%u' +- if stats_descriptions[label].has_key('value_type'): ++ if 'value_type' in stats_descriptions[label]: + if stats_descriptions[label]['value_type'] == "float": + format = '%f' + +@@ -1165,7 +1166,7 @@ if __name__ == '__main__': + for d in descriptors: + v = d['call_back'](d['name']) + if not options.quiet: +- print ' %s: %s %s [%s]' % (d['name'], v, d['units'], d['description']) ++ print(' %s: %s %s [%s]' % (d['name'], v, d['units'], d['description'])) + + if options.gmetric: + if d['value_type'] == 'uint': +diff --git a/gmond/python_modules/db/redis.py b/gmond/python_modules/db/redis.py +index 4e682b7..9101b49 100755 +--- a/gmond/python_modules/db/redis.py ++++ b/gmond/python_modules/db/redis.py +@@ -83,7 +83,7 @@ def metric_handler(name): + v = cps + #logging.debug("submittincg metric %s is %s" % (n, int(v))) + metric_handler.info[n] = int(v) # TODO Use value_type. +- except Exception, e: ++ except Exception as e: + #logging.debug("caught exception %s" % e) + pass + s.close() +@@ -121,7 +121,7 @@ def metric_init(params={}): + "db0": {"units": "keys"}, + } + metric_handler.descriptors = {} +- for name, updates in metrics.iteritems(): ++ for name, updates in metrics.items(): + descriptor = { + "name": name, + "call_back": metric_handler, +@@ -135,7 +135,7 @@ def metric_init(params={}): + } + descriptor.update(updates) + metric_handler.descriptors[name] = descriptor +- return metric_handler.descriptors.values() ++ return list(metric_handler.descriptors.values()) + + + def metric_cleanup(): +diff --git a/gmond/python_modules/db/riak.py b/gmond/python_modules/db/riak.py +index 908b480..499a04f 100755 +--- a/gmond/python_modules/db/riak.py ++++ b/gmond/python_modules/db/riak.py +@@ -24,7 +24,7 @@ import os + import sys + import threading + import time +-import urllib2 ++import urllib.request, urllib.error, urllib.parse + import traceback + import json + +@@ -37,7 +37,7 @@ Debug = False + + def dprint(f, *v): + if Debug: +- print >>sys.stderr, "DEBUG: " + f % v ++ print("DEBUG: " + f % v, file=sys.stderr) + + + def floatable(str): +@@ -84,18 +84,18 @@ class UpdateMetricThread(threading.Thread): + + def update_metric(self): + try: +- req = urllib2.Request(url=self.url) +- res = urllib2.urlopen(req) ++ req = urllib.request.Request(url=self.url) ++ res = urllib.request.urlopen(req) + stats = res.read() + dprint("%s", stats) + json_stats = json.loads(stats) +- for (key, value) in json_stats.iteritems(): ++ for (key, value) in json_stats.items(): + dprint("%s = %s", key, value) + if value == 'undefined': + self.metric[self.mp + '_' + key] = 0 + else: + self.metric[self.mp + '_' + key] = value +- except urllib2.URLError: ++ except urllib.error.URLError: + traceback.print_exc() + else: + res.close() +@@ -116,7 +116,7 @@ def metric_init(params): + if "metrix_prefix" not in params: + params["metrix_prefix"] = "riak" + +- print params ++ print(params) + + # initialize skeleton of descriptors + Desc_Skel = { +@@ -1035,7 +1035,7 @@ def metric_init(params): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -1057,7 +1057,7 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print ('value for %s is ' + d['format']) % (d['name'], v) ++ print(('value for %s is ' + d['format']) % (d['name'], v)) + time.sleep(5) + except KeyboardInterrupt: + time.sleep(0.2) +diff --git a/gmond/python_modules/disk/diskfree.py b/gmond/python_modules/disk/diskfree.py +index 70d5d41..8f7442d 100644 +--- a/gmond/python_modules/disk/diskfree.py ++++ b/gmond/python_modules/disk/diskfree.py +@@ -152,4 +152,4 @@ if __name__ == '__main__': + } + descriptors = metric_init(PARAMS) + for d in descriptors: +- print (('%s = %s') % (d['name'], d['format'])) % (d['call_back'](d['name'])) ++ print((('%s = %s') % (d['name'], d['format'])) % (d['call_back'](d['name']))) +diff --git a/gmond/python_modules/disk/diskstat.py b/gmond/python_modules/disk/diskstat.py +index 4cde607..79962ca 100644 +--- a/gmond/python_modules/disk/diskstat.py ++++ b/gmond/python_modules/disk/diskstat.py +@@ -532,7 +532,7 @@ if __name__ == '__main__': + for d in descriptors: + v = d['call_back'](d['name']) + if not options.quiet: +- print ' %s: %s %s [%s]' % (d['name'], v, d['units'], d['description']) ++ print(' %s: %s %s [%s]' % (d['name'], v, d['units'], d['description'])) + + if options.gmetric: + if d['value_type'] == 'uint': +@@ -544,5 +544,5 @@ if __name__ == '__main__': + (options.gmetric_bin, options.gmond_conf, v, d['units'], value_type, d['name'], d['slope']) + os.system(cmd) + +- print 'Sleeping 15 seconds' ++ print('Sleeping 15 seconds') + time.sleep(15) +diff --git a/gmond/python_modules/disk/multidisk.py b/gmond/python_modules/disk/multidisk.py +index 5dff161..86bf456 100644 +--- a/gmond/python_modules/disk/multidisk.py ++++ b/gmond/python_modules/disk/multidisk.py +@@ -30,7 +30,7 @@ + #* Author: Brad Nicholes (bnicholes novell.com) + #******************************************************************************/ + +-import statvfs ++#import statvfs + import os + import ganglia + +@@ -118,7 +118,7 @@ def metric_init(params): + continue + + if ganglia.get_debug_msg_level() > 1: +- print 'Discovered device %s' % line[1] ++ print('Discovered device %s' % line[1]) + + descriptors.append(Init_Metric(line, 'disk_total', int(1200), + 'double', 'GB', 'both', '%.3f', +@@ -140,4 +140,4 @@ if __name__ == '__main__': + metric_init(None) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %f' % (d['name'], v) ++ print('value for %s is %f' % (d['name'], v)) +diff --git a/gmond/python_modules/example/example.py b/gmond/python_modules/example/example.py +index c35d40d..82faa30 100644 +--- a/gmond/python_modules/example/example.py ++++ b/gmond/python_modules/example/example.py +@@ -54,8 +54,8 @@ def metric_init(params): + global Constant_Value + random.seed() + +- print '[pyexample] Received the following parameters' +- print params ++ print('[pyexample] Received the following parameters') ++ print(params) + + if 'RandomMax' in params: + Random_Max = int(params['RandomMax']) +@@ -97,4 +97,4 @@ if __name__ == '__main__': + metric_init(params) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %u' % (d['name'], v) ++ print('value for %s is %u' % (d['name'], v)) +diff --git a/gmond/python_modules/example/spfexample.py b/gmond/python_modules/example/spfexample.py +index 0baf97e..31e0af4 100644 +--- a/gmond/python_modules/example/spfexample.py ++++ b/gmond/python_modules/example/spfexample.py +@@ -133,5 +133,5 @@ if __name__ == '__main__': + d = metric_init(params) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %s' % (d['name'], str(v)) +- print d ++ print('value for %s is %s' % (d['name'], str(v))) ++ print(d) +diff --git a/gmond/python_modules/memcached/memcached.py b/gmond/python_modules/memcached/memcached.py +index 7db7616..8bdb57c 100644 +--- a/gmond/python_modules/memcached/memcached.py ++++ b/gmond/python_modules/memcached/memcached.py +@@ -19,7 +19,7 @@ Debug = False + + def dprint(f, *v): + if Debug: +- print >>sys.stderr, "DEBUG: " + f % v ++ print("DEBUG: " + f % v, file=sys.stderr) + + + def floatable(str): +@@ -86,7 +86,7 @@ class UpdateMetricThread(threading.Thread): + rfd, wfd, xfd = select.select([sock], [], [], self.timeout) + + if not rfd: +- print >>sys.stderr, "ERROR: select timeout" ++ print("ERROR: select timeout", file=sys.stderr) + break + + for fd in rfd: +@@ -94,19 +94,19 @@ class UpdateMetricThread(threading.Thread): + try: + data = fd.recv(8192) + msg += data +- except (IOError, OSError), e: ++ except (IOError, OSError) as e: + if e.errno != errno.EINTR: + raise + + if msg.find("END"): + break +- except select.error, e: ++ except select.error as e: + if e[0] != errno.EINTR: + raise + + sock.close() +- except socket.error, e: +- print >>sys.stderr, "ERROR: %s" % e ++ except socket.error as e: ++ print("ERROR: %s" % e, file=sys.stderr) + + for m in msg.split("\r\n"): + d = m.split(" ") +@@ -140,7 +140,7 @@ class UpdateMetricThread(threading.Thread): + def metric_init(params): + global descriptors, Desc_Skel, _Worker_Thread, Debug + +- print '[memcached] memcached protocol "stats"' ++ print('[memcached] memcached protocol "stats"') + if "type" not in params: + params["type"] = "memcached" + +@@ -150,7 +150,7 @@ def metric_init(params): + elif params["type"] == "Tokyo Tyrant": + params["metrix_prefix"] = "tt" + +- print params ++ print(params) + + # initialize skeleton of descriptors + Desc_Skel = { +@@ -362,7 +362,7 @@ def metric_init(params): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -391,7 +391,7 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print ('value for %s is ' + d['format']) % (d['name'], v) ++ print(('value for %s is ' + d['format']) % (d['name'], v)) + time.sleep(5) + except KeyboardInterrupt: + time.sleep(0.2) +diff --git a/gmond/python_modules/memory/mem_stats.py b/gmond/python_modules/memory/mem_stats.py +index 932a85b..b0cdc16 100644 +--- a/gmond/python_modules/memory/mem_stats.py ++++ b/gmond/python_modules/memory/mem_stats.py +@@ -43,7 +43,7 @@ def metrics_handler(name): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -384,4 +384,4 @@ if __name__ == '__main__': + metric_init({}) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %f' % (d['name'], v) ++ print('value for %s is %f' % (d['name'], v)) +diff --git a/gmond/python_modules/network/multi_interface.py b/gmond/python_modules/network/multi_interface.py +index 3f9b45d..f1da60a 100644 +--- a/gmond/python_modules/network/multi_interface.py ++++ b/gmond/python_modules/network/multi_interface.py +@@ -74,7 +74,7 @@ net_stats_file = "/proc/net/dev" + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -242,7 +242,7 @@ def get_aggregates(name): + try: + delta = (float(curr_metrics['data'][iface][index]) - float(last_metrics['data'][iface][index])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -300,7 +300,7 @@ def get_delta(name): + try: + delta = (float(curr_metrics['data'][iface][index]) - float(last_metrics['data'][iface][index])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -320,8 +320,8 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print ('value for %s is ' + d['format']) % (d['name'], v) ++ print(('value for %s is ' + d['format']) % (d['name'], v)) + time.sleep(5) +- except StandardError: +- print sys.exc_info()[0] ++ except Exception: ++ print(sys.exc_info()[0]) + os._exit(1) +diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py +index f9c6795..afa2165 100644 +--- a/gmond/python_modules/network/netstats.py ++++ b/gmond/python_modules/network/netstats.py +@@ -49,6 +49,10 @@ def get_metrics(): + new_metrics[metric_group] = dict() + for value in metrics: + # Skip first ++ try: ++ value = int(value) ++ except ValueError: ++ value = -1 + if count > 0 and value >= 0 and count in stats_pos[metric_group]: + metric_name = stats_pos[metric_group][count] + new_metrics[metric_group][metric_name] = value +@@ -94,7 +98,7 @@ def get_delta(name): + try: + delta = (float(curr_metrics['data'][group][metric]) - float(last_metrics['data'][group][metric])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -110,7 +114,7 @@ def get_tcploss_percentage(name): + try: + pct = 100 * (float(curr_metrics['data']['tcpext']["tcploss"]) - float(last_metrics["data"]['tcpext']["tcploss"])) / (float(curr_metrics['data']['tcp']['outsegs']) + float(curr_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['outsegs'])) + if pct < 0: +- print name + " is less 0" ++ print(name + " is less 0") + pct = 0 + except KeyError: + pct = 0.0 +@@ -128,7 +132,7 @@ def get_tcpattemptfail_percentage(name): + try: + pct = 100 * (float(curr_metrics['data']['tcp']["attemptfails"]) - float(last_metrics["data"]['tcp']["attemptfails"])) / (float(curr_metrics['data']['tcp']['outsegs']) + float(curr_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['outsegs'])) + if pct < 0: +- print name + " is less 0" ++ print(name + " is less 0") + pct = 0 + except Exception: + pct = 0.0 +@@ -144,7 +148,7 @@ def get_retrans_percentage(name): + try: + pct = 100 * (float(curr_metrics['data']['tcp']["retranssegs"]) - float(last_metrics['data']['tcp']["retranssegs"])) / (float(curr_metrics['data']['tcp']['outsegs']) + float(curr_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['outsegs'])) + if pct < 0: +- print name + " is less 0" ++ print(name + " is less 0") + pct = 0 + except KeyError: + pct = 0.0 +@@ -156,7 +160,7 @@ def get_retrans_percentage(name): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +diff --git a/gmond/python_modules/network/tcpconn.py b/gmond/python_modules/network/tcpconn.py +index 71bcc0f..b97d0ed 100644 +--- a/gmond/python_modules/network/tcpconn.py ++++ b/gmond/python_modules/network/tcpconn.py +@@ -68,7 +68,7 @@ def TCP_Connections(name): + global _WorkerThread + + if _WorkerThread is None: +- print 'Error: No netstat data gathering thread created for metric %s' % name ++ print('Error: No netstat data gathering thread created for metric %s' % name) + return 0 + + if not _WorkerThread.running and not _WorkerThread.shuttingdown: +@@ -233,7 +233,7 @@ class NetstatThread(threading.Thread): + if self.popenChild != None: + try: + self.popenChild.wait() +- except OSError, e: ++ except OSError as e: + if e.errno == 10: # No child processes + pass + +@@ -274,7 +274,7 @@ class NetstatThread(threading.Thread): + + try: + self.popenChild.wait() +- except OSError, e: ++ except OSError as e: + if e.errno == 10: # No child process + continue + +@@ -361,7 +361,7 @@ if __name__ == '__main__': + try: + for d in _descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %u' % (d['name'], v) ++ print('value for %s is %u' % (d['name'], v)) + time.sleep(5) + except KeyboardInterrupt: + os._exit(1) +diff --git a/gmond/python_modules/network/traffic1.py b/gmond/python_modules/network/traffic1.py +index 9e2b252..9f1078f 100644 +--- a/gmond/python_modules/network/traffic1.py ++++ b/gmond/python_modules/network/traffic1.py +@@ -16,7 +16,7 @@ Debug = False + + def dprint(f, *v): + if Debug: +- print >> sys.stderr, "DEBUG: " + f % v ++ print("DEBUG: " + f % v, file=sys.stderr) + + + class UpdateTrafficThread(threading.Thread): +@@ -76,7 +76,7 @@ class UpdateTrafficThread(threading.Thread): + dprint("%s", ">>update_metric") + self.stats = {} + _stats = a[1].split() +- for name, index in self.stats_tab.iteritems(): ++ for name, index in self.stats_tab.items(): + self.stats[name + '_' + self.target_device] = int(_stats[index]) + self.stats["time"] = time.time() + dprint("%s", self.stats) +@@ -84,7 +84,7 @@ class UpdateTrafficThread(threading.Thread): + if "time" in self.stats_prev: + dprint("%s: %d = %d - %d", "DO DIFF", self.stats["time"] - self.stats_prev["time"], self.stats["time"], self.stats_prev["time"]) + d = self.stats["time"] - self.stats_prev["time"] +- for name, cur in self.stats.iteritems(): ++ for name, cur in self.stats.items(): + self.metric[name] = float(cur - self.stats_prev[name]) / d + + self.stats_prev = self.stats.copy() +@@ -104,8 +104,8 @@ class UpdateTrafficThread(threading.Thread): + def metric_init(params): + global Desc_Skel, _Worker_Thread, Debug + +- print '[traffic1] Received the following parameters' +- print params ++ print('[traffic1] Received the following parameters') ++ print(params) + + Desc_Skel = { + 'name' : 'XXX', +@@ -172,7 +172,7 @@ def metric_init(params): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -195,11 +195,11 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print ('value for %s is ' + d['format']) % (d['name'], v) ++ print(('value for %s is ' + d['format']) % (d['name'], v)) + time.sleep(5) + except KeyboardInterrupt: + time.sleep(0.2) + os._exit(1) +- except StandardError: +- print sys.exc_info()[0] ++ except Exception: ++ print(sys.exc_info()[0]) + os._exit(1) +diff --git a/gmond/python_modules/nfs/nfsstats.py b/gmond/python_modules/nfs/nfsstats.py +index a383101..618b1be 100644 +--- a/gmond/python_modules/nfs/nfsstats.py ++++ b/gmond/python_modules/nfs/nfsstats.py +@@ -273,11 +273,11 @@ def metric_init(params): + + # Parse our defined params list in order to ensure list will not exceed max_plimit + n = 0 +- names_keys = configtable[i]['names'].keys() ++ names_keys = list(configtable[i]['names'].keys()) + keys_to_remove = [] + for _tmpkey in names_keys: + _tmplist = names_keys +- param_pos = re.split("{(\d+)\}", configtable[i]['names'][_tmpkey].values()[0])[1] ++ param_pos = re.split("{(\d+)\}", list(configtable[i]['names'][_tmpkey].values())[0])[1] + if int(param_pos) > int(max_plimit): + keys_to_remove.append(_tmpkey) + n += 1 +@@ -388,7 +388,7 @@ def debug(level, text): + if level > verboselevel: + return + if sys.stderr.isatty(): +- print text ++ print(text) + else: + syslog.syslog(text) + +diff --git a/gmond/python_modules/process/procstat.py b/gmond/python_modules/process/procstat.py +index b26849b..172cdce 100644 +--- a/gmond/python_modules/process/procstat.py ++++ b/gmond/python_modules/process/procstat.py +@@ -144,7 +144,7 @@ def get_pgid(proc): + logging.debug('getting pgid for process: ' + proc) + ERROR = 0 + +- if pgid_list.has_key(proc) and os.path.exists('/proc/' + pgid_list[proc][0]): ++ if proc in pgid_list and os.path.exists('/proc/' + pgid_list[proc][0]): + return pgid_list[proc] + + val = PROCESSES[proc] +@@ -245,14 +245,14 @@ def test(params): + + PROCESSES = params + +- for proc, val in PROCESSES.items(): ++ for proc, val in list(PROCESSES.items()): + print('') +- print(' Testing ' + proc + ': ' + val) ++ print((' Testing ' + proc + ': ' + val)) + + try: + (ppid, pgid) = get_pgid(proc) +- except Exception, e: +- print(' failed getting pgid: ' + str(e)) ++ except Exception as e: ++ print((' failed getting pgid: ' + str(e))) + continue + + pids = get_pgroup(ppid, pgid) +@@ -262,7 +262,7 @@ def test(params): + for pid in pids: + # Read from binary file containing command line arguments + args = file('/proc/' + pid + '/cmdline', 'rt').readline().replace('\0', ' ') +- print(' ' + pid + ' ' + args) ++ print((' ' + pid + ' ' + args)) + + logging.debug('success testing') + +@@ -279,7 +279,7 @@ def update_stats(): + else: + last_update = cur_time + +- for proc, val in PROCESSES.items(): ++ for proc, val in list(PROCESSES.items()): + logging.debug(' updating for ' + proc) + + # setup storage lists +@@ -292,7 +292,7 @@ def update_stats(): + # Update CPU utilization + try: + (ppid, pgid) = get_pgid(proc) +- except Exception, e: ++ except Exception as e: + logging.warning(' failed getting pgid: ' + str(e)) + stats[proc]['cpu'] = 0.0 + stats[proc]['mem'] = 0 +@@ -389,7 +389,7 @@ def metric_init(params): + time_max = 60 + for label in descriptions: + for proc in PROCESSES: +- if stats[proc].has_key(label): ++ if label in stats[proc]: + + d = { + 'name': 'procstat_' + proc + '_' + label, +@@ -433,12 +433,12 @@ def display_proc_stat(pid): + # Display them + i = 0 + for f in fields: +- print '%15s: %s' % (f, stat[i]) ++ print('%15s: %s' % (f, stat[i])) + i += 1 + + except: +- print('failed to get /proc/' + pid + '/stat') +- print(traceback.print_exc(file=sys.stdout)) ++ print(('failed to get /proc/' + pid + '/stat')) ++ print((traceback.print_exc(file=sys.stdout))) + + + def display_proc_statm(pid): +@@ -452,12 +452,12 @@ def display_proc_statm(pid): + # Display them + i = 0 + for f in fields: +- print '%15s: %s' % (f, statm[i]) ++ print('%15s: %s' % (f, statm[i])) + i += 1 + + except: +- print('failed to get /proc/' + pid + '/statm') +- print(traceback.print_exc(file=sys.stdout)) ++ print(('failed to get /proc/' + pid + '/statm')) ++ print((traceback.print_exc(file=sys.stdout))) + + + def metric_cleanup(): +@@ -502,7 +502,7 @@ if __name__ == '__main__': + update_stats() + + print('') +- print(' waiting ' + str(MAX_UPDATE_TIME) + ' seconds') ++ print((' waiting ' + str(MAX_UPDATE_TIME) + ' seconds')) + time.sleep(MAX_UPDATE_TIME) + + metric_init(params) +@@ -510,7 +510,7 @@ if __name__ == '__main__': + for d in descriptors: + v = d['call_back'](d['name']) + if not options.quiet: +- print ' %s: %s %s [%s]' % (d['name'], d['format'] % v, d['units'], d['description']) ++ print(' %s: %s %s [%s]' % (d['name'], d['format'] % v, d['units'], d['description'])) + + if options.gmetric: + if d['value_type'] == 'uint': +diff --git a/gmond/python_modules/ssl/entropy.py b/gmond/python_modules/ssl/entropy.py +index 8337981..71193c6 100644 +--- a/gmond/python_modules/ssl/entropy.py ++++ b/gmond/python_modules/ssl/entropy.py +@@ -53,4 +53,4 @@ if __name__ == '__main__': + metric_init({}) + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %u' % (d['name'], v) ++ print('value for %s is %u' % (d['name'], v)) +diff --git a/gmond/python_modules/varnish/varnish.py b/gmond/python_modules/varnish/varnish.py +index f8c0723..b1a8573 100755 +--- a/gmond/python_modules/varnish/varnish.py ++++ b/gmond/python_modules/varnish/varnish.py +@@ -51,7 +51,7 @@ METRICS_CACHE_MAX = 5 + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -92,7 +92,7 @@ def get_value(name): + name = name[len(NAME_PREFIX):] # remove prefix from name + try: + result = metrics['data'][name] +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -109,9 +109,9 @@ def get_delta(name): + try: + delta = float(curr_metrics['data'][name] - last_metrics['data'][name]) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print "Less than 0" ++ print("Less than 0") + delta = 0 +- except StandardError: ++ except Exception: + delta = 0 + + return delta +@@ -1038,6 +1038,6 @@ if __name__ == '__main__': + descriptors = metric_init(PARAMS) + while True: + for d in descriptors: +- print (('%s = %s') % (d['name'], d['format'])) % (d['call_back'](d['name'])) +- print 'Sleeping 15 seconds' ++ print((('%s = %s') % (d['name'], d['format'])) % (d['call_back'](d['name']))) ++ print('Sleeping 15 seconds') + time.sleep(15) +diff --git a/gmond/python_modules/vm_stats/vm_stats.py b/gmond/python_modules/vm_stats/vm_stats.py +index ed663de..2e1e8b8 100644 +--- a/gmond/python_modules/vm_stats/vm_stats.py ++++ b/gmond/python_modules/vm_stats/vm_stats.py +@@ -69,7 +69,7 @@ def get_value(name): + + try: + result = metrics['data'][name] +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -86,7 +86,7 @@ def get_delta(name): + try: + delta = (float(curr_metrics['data'][name]) - float(last_metrics['data'][name])) / (curr_metrics['time'] - last_metrics['time']) + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -112,7 +112,7 @@ def get_vmeff(name): + + delta = 100 * (float(curr_metrics['data']['pgsteal_normal']) - float(last_metrics['data']['pgsteal_normal'])) / pgscan_diff + if delta < 0: +- print name + " is less 0" ++ print(name + " is less 0") + delta = 0 + except KeyError: + delta = 0.0 +@@ -122,7 +122,7 @@ def get_vmeff(name): + + def create_desc(skel, prop): + d = skel.copy() +- for k, v in prop.iteritems(): ++ for k, v in prop.items(): + d[k] = v + return d + +@@ -734,6 +734,6 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print '%s = %s' % (d['name'], v) +- print 'Sleeping 15 seconds' ++ print('%s = %s' % (d['name'], v)) ++ print('Sleeping 15 seconds') + time.sleep(15) +diff --git a/gmond/python_modules/xen/xenstats.py b/gmond/python_modules/xen/xenstats.py +index 67a6c21..bdb3750 100755 +--- a/gmond/python_modules/xen/xenstats.py ++++ b/gmond/python_modules/xen/xenstats.py +@@ -128,4 +128,4 @@ if __name__ == '__main__': + metric_init('init') + for d in descriptors: + v = d['call_back'](d['name']) +- print 'value for %s is %u' % (d['name'], v) ++ print('value for %s is %u' % (d['name'], v)) diff --git a/ganglia-gmond-python2to3.patch b/ganglia-gmond-python2to3.patch new file mode 100644 index 0000000..fc1b9cc --- /dev/null +++ b/ganglia-gmond-python2to3.patch @@ -0,0 +1,176 @@ +diff --git a/gmond/modules/python/mod_python.c b/gmond/modules/python/mod_python.c +index ed5a401..484429e 100644 +--- a/gmond/modules/python/mod_python.c ++++ b/gmond/modules/python/mod_python.c +@@ -29,6 +29,10 @@ + * + * Author: Brad Nicholes (bnicholes novell.com) + * Jon Carey (jcarey novell.com) ++* ++* Modified for Python3 support, based on code at https://docs.python.org/3.5/howto/cporting.html ++* Tom Crane (T.Crane@rhul.ac.uk), June 2024. ++* + ******************************************************************************/ + + #include +@@ -51,12 +55,23 @@ + /* + * Backward compatibility for 2.1 to 2.4 + */ ++#if PY_MAJOR_VERSION < 3 + #if PY_MINOR_VERSION < 5 + #define Py_ssize_t int + #if PY_MINOR_VERSION < 3 + #define PyInt_AsUnsignedLongMask PyInt_AsLong + #endif + #endif ++#endif ++ ++#if PY_MAJOR_VERSION >= 3 ++# define PyInt_AsLong(x) (PyLong_AsLong((x))) ++# define PyInt_Check(x) (PyLong_Check((x))) ++# define PyString_Check(x) (PyUnicode_Check((x))) ++# define PyString_AsString(x) (PyUnicode_AsUTF8((x))) ++# define PyInt_AsUnsignedLongMask(x) (PyLong_AsUnsignedLongMask((x))) ++# define PyString_FromString(x) (PyUnicode_FromString((x))) ++#endif + + /* + * Declare ourselves so the configuration routines can find and know us. +@@ -540,7 +555,57 @@ static PyMethodDef GangliaMethods[] = { + {NULL, NULL, 0, NULL} + }; + ++struct module_state { ++ PyObject *error; ++}; ++ ++#if PY_MAJOR_VERSION >= 3 ++#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) ++#else ++#define GETSTATE(m) (&_state) ++static struct module_state _state; ++#endif ++ ++static PyObject * ++error_out(PyObject *m) { ++ struct module_state *st = GETSTATE(m); ++ PyErr_SetString(st->error, "something bad happened"); ++ return NULL; ++} ++ ++#if PY_MAJOR_VERSION >= 3 ++ ++static int ganglia_traverse(PyObject *m, visitproc visit, void *arg) { ++ Py_VISIT(GETSTATE(m)->error); ++ return 0; ++} ++ ++static int ganglia_clear(PyObject *m) { ++ Py_CLEAR(GETSTATE(m)->error); ++ return 0; ++} ++ ++ ++static struct PyModuleDef moduledef = { ++ PyModuleDef_HEAD_INIT, ++ "ganglia", ++ NULL, ++ sizeof(struct module_state), ++ GangliaMethods, ++ NULL, ++ ganglia_traverse, ++ ganglia_clear, ++ NULL ++}; ++ ++#define INITERROR return NULL ++ ++PyMODINIT_FUNC PyInit_metric_init(apr_pool_t *p) ++#else ++#define INITERROR return ++ + static int pyth_metric_init (apr_pool_t *p) ++#endif + { + DIR *dp; + struct dirent *entry; +@@ -563,29 +628,41 @@ static int pyth_metric_init (apr_pool_t *p) + + if (!path) { + err_msg("[PYTHON] Missing python module path.\n"); +- return -1; ++ INITERROR; + } + + if (access(path, F_OK)) + { + /* 'path' does not exist */ + err_msg("[PYTHON] Can't open the python module path %s.\n", path); +- return -1; ++ INITERROR; + } + + if (access(path, R_OK)) + { + /* Don't have read access to 'path' */ + err_msg("[PYTHON] Can't read from the python module path %s.\n", path); +- return -1; ++ INITERROR; + } + + /* Init Python environment */ + + /* Set up the python path to be able to load module from our module path */ + Py_Initialize(); +- Py_InitModule("ganglia", GangliaMethods); ++#if PY_MAJOR_VERSION >= 3 ++ PyObject *module = PyModule_Create(&moduledef); ++#else ++ PyObject *module = Py_InitModule("ganglia", GangliaMethods); ++#endif ++ if (module == NULL) ++ INITERROR; ++ struct module_state *st = GETSTATE(module); + ++ st->error = PyErr_NewException("ganglia.Error", NULL, NULL); ++ if (st->error == NULL) { ++ Py_DECREF(module); ++ INITERROR; ++ } + PyObject *sys_path = PySys_GetObject("path"); + PyObject *addpath = PyString_FromString(path); + PyList_Append(sys_path, addpath); +@@ -598,7 +675,7 @@ static int pyth_metric_init (apr_pool_t *p) + /* Error: Cannot open the directory - Shouldn't happen */ + /* Log? */ + err_msg("[PYTHON] Can't open the python module path %s.\n", path); +- return -1; ++ INITERROR; + } + + i = 0; +@@ -712,7 +789,11 @@ static int pyth_metric_init (apr_pool_t *p) + memset (mi, 0, sizeof(*mi)); + + python_module.metrics_info = (Ganglia_25metric *)metric_info->elts; ++#if PY_MAJOR_VERSION >= 3 ++ return module; ++#else + return 0; ++#endif + } + + static apr_status_t pyth_metric_cleanup ( void *data) +@@ -832,7 +913,11 @@ static g_val_t pyth_metric_handler( int metric_index ) + mmodule python_module = + { + STD_MMODULE_STUFF, ++#if PY_MAJOR_VERSION >= 3 ++ (int (*)(apr_pool_t *))PyInit_metric_init, ++#else + pyth_metric_init, ++#endif + NULL, + NULL, /* defined dynamically */ + pyth_metric_handler, diff --git a/ganglia.spec b/ganglia.spec index 199eb34..81fe900 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -4,14 +4,17 @@ %global systemd 1 %global _hardened_build 1 -%if 0%{?rhel} && 0%{?rhel} < 8 +%global with_python 1 +%if 0%{?rhel} == 7 %global py2 1 +%else +%global py3 1 %endif Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 48%{?dist} +Release: 50%{?dist} License: BSD URL: http://ganglia.sourceforge.net/ Source0: http://downloads.sourceforge.net/sourceforge/ganglia/ganglia-%{version}.tar.gz @@ -26,6 +29,9 @@ Patch1: ganglia-3.7.2-gcc14-cast.patch Patch10: ganglia-3.7.2-tirpc-hack.patch Patch20: ganglia-web-3.7.2-path.patch Patch21: ganglia-web-3.7.6-pr-379.patch +Patch30: ganglia-gmond-python2to3.patch +Patch31: ganglia-gmond-python2to3-modules.patch +Patch32: ganglia-3.7.2-autoconf-python-print.patch %if 0%{?systemd} BuildRequires: systemd %endif @@ -50,6 +56,7 @@ BuildRequires: make BuildRequires: pcre-devel %endif %{?py2:BuildRequires: python2-devel} +%{?py3:BuildRequires: python3-devel} BuildRequires: rrdtool-devel BuildRequires: rsync BuildRequires: /usr/bin/pod2man @@ -115,14 +122,30 @@ This gmond daemon provides the ganglia service within a single cluster or Multicast domain. %if 0%{?py2} -%package -n python2-ganglia-gmond +%package python2-gmond Summary: Ganglia Monitor daemon python DSO and metric modules Requires: ganglia-gmond Requires: python2 -%{?python_provide:%python_provide python2-ganglia-gmond} +%{?python_provide:%python_provide python2-gmond} # Remove before F30 -Provides: ganglia-gmond-python = %{version}-%{release} -%description -n python2-ganglia-gmond +Provides: ganglia-python = %{version}-%{release} +%description python2-gmond +Ganglia is a scalable, real-time monitoring and execution environment +with all execution requests and statistics expressed in an open +well-defined XML format. + +This package provides the gmond python DSO and python gmond modules, +which can be loaded via the DSO at gmond daemon start time. +%endif + +%if 0%{?py3} +%package python3-gmond +Summary: Ganglia Monitor daemon python3 DSO and metric modules +Requires: ganglia-gmond +Requires: python3 +%{?python_provide:%python_provide python3-gmond} +Provides: gmond-python = %{version}-%{release} +%description python3-gmond Ganglia is a scalable, real-time monitoring and execution environment with all execution requests and statistics expressed in an open well-defined XML format. @@ -142,10 +165,13 @@ programmers can use to build scalable cluster or grid applications %prep %setup -q -%patch -P0 -p1 -%patch -P1 -p1 +%patch -P 0 -p1 +%patch -P 1 -p1 +%patch -P 30 -p1 +%{?py3:%patch -P 31 -p1} +%patch -P 32 -p1 %if 0%{?fedora} || 0%{?rhel} > 7 -%patch -P10 -p1 +%patch -P 10 -p1 %endif # fix broken systemd support install -m 0644 %{SOURCE2} gmond/gmond.service.in @@ -154,12 +180,13 @@ install -m 0644 %{SOURCE3} gmetad/gmetad.service.in %setup -q -T -D -a 1 mv ganglia-web-%{webver} web pushd web -%patch -P20 -p1 -%patch -P21 -p1 +%patch -P 20 -p1 +%patch -P 21 -p1 popd %build touch Makefile.am + %if 0%{?fedora} || 0%{?rhel} > 7 aclocal -I m4 autoheader @@ -191,8 +218,14 @@ export CFLAGS="%{optflags} -fcommon" %if 0%{?fedora} > 37 --with-libpcre=no \ %endif +%if 0%{?with_python} + --enable-python \ %if 0%{?py2} --with-python=%{__python2} \ +%endif +%if 0%{?py3} + --with-python=%{__python3} \ +%endif %else --disable-python \ %endif @@ -218,7 +251,7 @@ make %{?_smp_mflags} make install DESTDIR=%{buildroot} ## Create directory structures -%{?py2:mkdir -p %{buildroot}%{_libdir}/ganglia/python_modules} +%{?with_python:mkdir -p %{buildroot}%{_libdir}/ganglia/python_modules} mkdir -p %{buildroot}%{_localstatedir}/lib/%{name}/rrds ## Install services @@ -234,9 +267,10 @@ install -Dp -m 0755 gmetad/gmetad.init %{buildroot}%{_sysconfdir}/init.d/gmetad LD_LIBRARY_PATH=lib/.libs gmond/gmond -t | %{__perl} -pe 's|nobody|ganglia|g' \ > %{buildroot}%{_sysconfdir}/ganglia/gmond.conf -%if 0%{?py2} +%if 0%{?with_python} ## Python bits # Copy the python metric modules and .conf files +mkdir -p %{buildroot}%{_sysconfdir}/ganglia/conf.d cp -p gmond/python_modules/conf.d/*.pyconf %{buildroot}%{_sysconfdir}/ganglia/conf.d/ cp -p gmond/modules/conf.d/*.conf %{buildroot}%{_sysconfdir}/ganglia/conf.d/ cp -p gmond/python_modules/*/*.py %{buildroot}%{_libdir}/ganglia/python_modules/ @@ -279,12 +313,12 @@ rm -f %{buildroot}%{_libdir}/*.la # Remove execute bit chmod 0644 %{buildroot}%{_datadir}/%{name}/header.php -%{?py2:chmod 0644 %{buildroot}%{_libdir}/%{name}/python_modules/*.py} +%{?with_python:chmod 0644 %{buildroot}%{_libdir}/%{name}/python_modules/*.py} chmod 0644 %{buildroot}%{_datadir}/%{name}/css/smoothness/jquery-ui-1.10.2.custom.css chmod 0644 %{buildroot}%{_datadir}/%{name}/css/smoothness/jquery-ui-1.10.2.custom.min.css # Remove shebang -%{?py2:sed -i '1{\@^#!@d}' %{buildroot}%{_libdir}/%{name}/python_modules/*.py} +%{?with_python:sed -i '1{\@^#!@d}' %{buildroot}%{_libdir}/%{name}/python_modules/*.py} %pre ## Add the "ganglia" user @@ -346,7 +380,7 @@ end %{_libdir}/libganglia*.so.* %dir %{_libdir}/ganglia %{_libdir}/ganglia/*.so -%{?py2:%exclude %{_libdir}/ganglia/modpython.so} +%{?with_python:%exclude %{_libdir}/ganglia/modpython.so} %files gmetad %dir %{_localstatedir}/lib/%{name} @@ -376,13 +410,22 @@ end %{_mandir}/man1/gstat.1* %{_mandir}/man1/gmetric.1* %dir %{_sysconfdir}/ganglia -%{?py2:%dir %{_sysconfdir}/ganglia/conf.d} +%{?with_python:%dir %{_sysconfdir}/ganglia/conf.d} %config(noreplace) %{_sysconfdir}/ganglia/gmond.conf -%{?py2:%config(noreplace) %{_sysconfdir}/ganglia/conf.d/*.conf} -%{?py2:%exclude %{_sysconfdir}/ganglia/conf.d/modpython.conf} +%{?with_python:%config(noreplace) %{_sysconfdir}/ganglia/conf.d/*.conf} +%{?with_python:%exclude %{_sysconfdir}/ganglia/conf.d/modpython.conf} %if 0%{?py2} -%files -n python2-ganglia-gmond +%files python2-gmond +%dir %{_libdir}/ganglia/python_modules/ +%{_libdir}/ganglia/python_modules/*.py* +%{_libdir}/ganglia/modpython.so* +%config(noreplace) %{_sysconfdir}/ganglia/conf.d/*.pyconf* +%config(noreplace) %{_sysconfdir}/ganglia/conf.d/modpython.conf +%endif + +%if 0%{?py3} +%files python3-gmond %dir %{_libdir}/ganglia/python_modules/ %{_libdir}/ganglia/python_modules/*.py* %{_libdir}/ganglia/modpython.so* @@ -408,6 +451,12 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Mon Jun 24 2024 Terje Rosten - 3.7.2-50 +- Various fixes to add Python 3 support for Fedora 40+ + +* Tue Jun 11 2024 Tom Crane - 3.7.2-49 +- Update gmond for Python3 modules support + * Sun Mar 10 2024 Terje Rosten - 3.7.2-48 - Update to commit 185ab6b From b9009b58fd388525304cc82441e39a6cc89b4881 Mon Sep 17 00:00:00 2001 From: Terje Rosten Date: Mon, 24 Jun 2024 20:09:24 +0200 Subject: [PATCH 03/15] Fix filename of patch --- ganglia.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ganglia.spec b/ganglia.spec index 81fe900..f79e7ba 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -31,7 +31,7 @@ Patch20: ganglia-web-3.7.2-path.patch Patch21: ganglia-web-3.7.6-pr-379.patch Patch30: ganglia-gmond-python2to3.patch Patch31: ganglia-gmond-python2to3-modules.patch -Patch32: ganglia-3.7.2-autoconf-python-print.patch +Patch32: ganglia-3.7.2-autoconf-python3.patch %if 0%{?systemd} BuildRequires: systemd %endif From f4cccbd59dc4e1c4a409b627507234eff2ee5019 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 17 Jul 2024 23:54:26 +0000 Subject: [PATCH 04/15] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- ganglia.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ganglia.spec b/ganglia.spec index f79e7ba..a355cbb 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,7 +14,7 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 50%{?dist} +Release: 51%{?dist} License: BSD URL: http://ganglia.sourceforge.net/ Source0: http://downloads.sourceforge.net/sourceforge/ganglia/ganglia-%{version}.tar.gz @@ -451,6 +451,9 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Wed Jul 17 2024 Fedora Release Engineering - 3.7.2-51 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Mon Jun 24 2024 Terje Rosten - 3.7.2-50 - Various fixes to add Python 3 support for Fedora 40+ From 29ae55186ff5a14df658fd1ae1ed6b986dd55918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Wed, 28 Aug 2024 09:52:33 +0200 Subject: [PATCH 05/15] convert license to SPDX This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4 --- ganglia.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ganglia.spec b/ganglia.spec index a355cbb..d5858ca 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,8 +14,9 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 51%{?dist} -License: BSD +Release: 52%{?dist} +# Automatically converted from old format: BSD - review is highly recommended. +License: LicenseRef-Callaway-BSD URL: http://ganglia.sourceforge.net/ Source0: http://downloads.sourceforge.net/sourceforge/ganglia/ganglia-%{version}.tar.gz Source1: https://github.com/ganglia/ganglia-web/archive/%{webver}/ganglia-web-%{webver}.tar.gz @@ -451,6 +452,9 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Wed Aug 28 2024 Miroslav Suchý - 3.7.6-52 +- convert license to SPDX + * Wed Jul 17 2024 Fedora Release Engineering - 3.7.2-51 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From 687891e8888199a494b7bd465bc5f6c58f30fba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20R=C3=B8sten?= Date: Sat, 28 Sep 2024 14:36:52 +0200 Subject: [PATCH 06/15] Add patch to improve compat with PHP 8 --- ganglia-web-3.7.6-php8.patch | 169 +++++++++++++++++++++++++++++++++++ ganglia.spec | 7 +- 2 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 ganglia-web-3.7.6-php8.patch diff --git a/ganglia-web-3.7.6-php8.patch b/ganglia-web-3.7.6-php8.patch new file mode 100644 index 0000000..9fcadb0 --- /dev/null +++ b/ganglia-web-3.7.6-php8.patch @@ -0,0 +1,169 @@ +From: + https://bugzilla.redhat.com/show_bug.cgi?id=2180500 + +diff --git a/api/host.php b/api/host.php +index 5eb026c..5cee9ec 100644 +--- a/api/host.php ++++ b/api/host.php +@@ -87,7 +87,7 @@ switch ( $_GET['action'] ) { + $reports["excluded_reports"] = array_unique($reports["excluded_reports"]); + $additional_cluster_img_html_args = array(); + $additional_cluster_img_html_args['h'] = $hostname; +- $additional_cluster_img_html_args['st'] = $cluster[LOCALTIME]; ++ $additional_cluster_img_html_args['st'] = $cluster['LOCALTIME']; + $additional_cluster_img_html_args['m'] = $metricname; + $additional_cluster_img_html_args['r'] = $range; + $additional_cluster_img_html_args['s'] = $sort; +@@ -152,7 +152,7 @@ switch ( $_GET['action'] ) { + $graph_arguments['z'] = $size; + $graph_arguments['jr'] = $jobrange; + $graph_arguments['js'] = $jobstart; +- $graph_arguments['st'] = $cluster[LOCALTIME]; ++ $graph_arguments['st'] = $cluster['LOCALTIME']; + # Adding units to graph 2003 by Jason Smith . + if ($v['UNITS']) { + $graph_arguments['vl'] = $metrics[$cluster_url]['UNITS']; +diff --git a/dwoo/Dwoo/Core.php b/dwoo/Dwoo/Core.php +index 8ec104b..fc62cde 100644 +--- a/dwoo/Dwoo/Core.php ++++ b/dwoo/Dwoo/Core.php +@@ -1250,7 +1250,7 @@ class Dwoo_Core + } + unset($varstr); + +- while (list($k, $sep) = each($m[1])) { ++ foreach($m[1] as $k => $sep){ + if ($sep === '.' || $sep === '[' || $sep === '') { + // strip enclosing quotes if present + $m[2][$k] = preg_replace('#^(["\']?)(.*?)\1$#', '$2', $m[2][$k]); +@@ -1425,7 +1425,7 @@ class Dwoo_Core + $cur = $this->scope; + } + +- while (list($k, $sep) = each($m[1])) { ++ foreach($m[1] as $k => $sep){ + if ($sep === '.' || $sep === '[' || $sep === '') { + if ((is_array($cur) || $cur instanceof ArrayAccess) && isset($cur[$m[2][$k]])) { + $cur = $cur[$m[2][$k]]; +@@ -1470,7 +1470,7 @@ class Dwoo_Core + $cur =& $this->scope; + $last = array(array_pop($m[1]), array_pop($m[2])); + +- while (list($k, $sep) = each($m[1])) { ++ foreach($m[1] as $k => $sep){ + if ($sep === '.' || $sep === '[' || $sep === '') { + if (is_array($cur) === false) { + $cur = array(); +diff --git a/dwoo/Dwoo/Data.php b/dwoo/Dwoo/Data.php +index c5f292e..d841546 100644 +--- a/dwoo/Dwoo/Data.php ++++ b/dwoo/Dwoo/Data.php +@@ -71,7 +71,7 @@ class Dwoo_Data implements Dwoo_IDataProvider + public function mergeData(array $data) + { + $args = func_get_args(); +- while (list(,$v) = each($args)) { ++ foreach($args as $v){ + if (is_array($v)) { + $this->data = array_merge($this->data, $v); + } +@@ -90,7 +90,7 @@ class Dwoo_Data implements Dwoo_IDataProvider + { + if (is_array($name)) { + reset($name); +- while (list($k,$v) = each($name)) ++ foreach($name as $k => $v) + $this->data[$k] = $v; + } else { + $this->data[$name] = $val; +diff --git a/dwoo/plugins/builtin/blocks/textformat.php b/dwoo/plugins/builtin/blocks/textformat.php +index fb0f422..61ec1d6 100644 +--- a/dwoo/plugins/builtin/blocks/textformat.php ++++ b/dwoo/plugins/builtin/blocks/textformat.php +@@ -67,7 +67,7 @@ class Dwoo_Plugin_textformat extends Dwoo_Block_Plugin + // gets paragraphs + $pgs = explode("\n", str_replace(array("\r\n", "\r"), "\n", $this->buffer)); + +- while (list($i,) = each($pgs)) { ++ foreach($pgs as $i){ + if (empty($pgs[$i])) { + continue; + } +diff --git a/dwoo/plugins/builtin/functions/capitalize.php b/dwoo/plugins/builtin/functions/capitalize.php +index d04f39b..de57c20 100644 +--- a/dwoo/plugins/builtin/functions/capitalize.php ++++ b/dwoo/plugins/builtin/functions/capitalize.php +@@ -25,7 +25,7 @@ function Dwoo_Plugin_capitalize(Dwoo_Core $dwoo, $value, $numwords=false) + } else { + $bits = explode(' ', (string) $value); + $out = ''; +- while (list(,$v) = each($bits)) { ++ foreach($bits as $v){ + if (preg_match('#^[^0-9]+$#', $v)) { + $out .= ' '.mb_convert_case($v, MB_CASE_TITLE, $dwoo->getCharset()); + } else { +diff --git a/host_view.php b/host_view.php +index ca05c8d..3b54b35 100644 +--- a/host_view.php ++++ b/host_view.php +@@ -329,7 +329,7 @@ $cluster_url = rawurlencode($clustername); + + $baseGraphArgs = "c=$cluster_url&h=" . $user['hostname'] + . "&r=" . $user['range'] . "&z=$size&jr=$jobrange" +- . "&js=$jobstart&st=$cluster[LOCALTIME]"; ++ . "&js=$jobstart&st=" . $cluster['LOCALTIME']; + if ($user['cs']) + $baseGraphArgs .= "&cs=" . rawurlencode($user['cs']); + if ($user['ce']) +diff --git a/lib/GangliaAuth.php b/lib/GangliaAuth.php +index 01ca10d..bda8f84 100644 +--- a/lib/GangliaAuth.php ++++ b/lib/GangliaAuth.php +@@ -94,7 +94,7 @@ class GangliaAuth { + } + + protected function getMagicQuotesGpc() { +- return get_magic_quotes_gpc(); ++ return false; + } + } + ?> +diff --git a/metric_group_view.php b/metric_group_view.php +index 13dc0a1..f526545 100644 +--- a/metric_group_view.php ++++ b/metric_group_view.php +@@ -105,7 +105,7 @@ $cluster_url = rawurlencode($clustername); + + $baseGraphArgs = "c=$cluster_url&h=$hostname" + . "&r=$range&z=$size&jr=$jobrange" +- . "&js=$jobstart&st=$cluster[LOCALTIME]"; ++ . "&js=$jobstart&st=$cluster['LOCALTIME']"; + if ($cs) + $baseGraphArgs .= "&cs=" . rawurlencode($cs); + if ($ce) +diff --git a/mobile_helper.php b/mobile_helper.php +index d9e20cb..2b384ad 100644 +--- a/mobile_helper.php ++++ b/mobile_helper.php +@@ -268,7 +268,7 @@ foreach ($metrics as $metric_name => $metric_attributes) { + else { + $metric_graphargs = "c=".rawurlencode($clustername)."&h=".rawurlencode($hostname)."&v=".rawurlencode($metric_attributes['VAL']) + ."&m=$metric_name&r=".rawurlencode($range)."&z=$size&jr=$jobrange" +- ."&js=$jobstart&st=$cluster[LOCALTIME]"; ++ ."&js=$jobstart&st=$cluster['LOCALTIME']"; + if ($cs) + $metric_graphargs .= "&cs=" . rawurlencode($cs); + if ($ce) +diff --git a/physical_view.php b/physical_view.php +index 8d5c3bc..a0d4111 100644 +--- a/physical_view.php ++++ b/physical_view.php +@@ -99,7 +99,7 @@ function physical_racks() { + else { + ksort($racks); + reset($racks); +- while (list($rack,) = each($racks)) { ++ foreach($racks as $rack){ + # In our convention, y=0 is close to the floor. (Easier to wire up) + krsort($racks[$rack]); + } diff --git a/ganglia.spec b/ganglia.spec index d5858ca..c5a55eb 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,7 +14,7 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 52%{?dist} +Release: 53%{?dist} # Automatically converted from old format: BSD - review is highly recommended. License: LicenseRef-Callaway-BSD URL: http://ganglia.sourceforge.net/ @@ -30,6 +30,7 @@ Patch1: ganglia-3.7.2-gcc14-cast.patch Patch10: ganglia-3.7.2-tirpc-hack.patch Patch20: ganglia-web-3.7.2-path.patch Patch21: ganglia-web-3.7.6-pr-379.patch +Patch22: ganglia-web-3.7.6-php8.patch Patch30: ganglia-gmond-python2to3.patch Patch31: ganglia-gmond-python2to3-modules.patch Patch32: ganglia-3.7.2-autoconf-python3.patch @@ -183,6 +184,7 @@ mv ganglia-web-%{webver} web pushd web %patch -P 20 -p1 %patch -P 21 -p1 +%patch -P 22 -p1 popd %build @@ -452,6 +454,9 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Sat Sep 28 2024 Terje Rosten - 3.7.6-53 +- Add patch to improve compat with PHP 8 + * Wed Aug 28 2024 Miroslav Suchý - 3.7.6-52 - convert license to SPDX From 12811467120ddf2f1c375504b25f29b55d75103f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20R=C3=B8sten?= Date: Wed, 16 Oct 2024 17:37:12 +0200 Subject: [PATCH 07/15] Various fixes to improve Python 3 support Add back regex support on Fedora (patch from Debian, thanks!) --- ...ix-return-value-from-mod_python-init.patch | 60 ++ ...2to3-modules.patch => 0002-2to3-pass.patch | 128 +++-- 0003-Ruff-pass.patch | 534 ++++++++++++++++++ 0004-Use-raw-strings.patch | 62 ++ ganglia-3.7.2-pcre2.patch | 126 +++++ ganglia.spec | 30 +- 6 files changed, 884 insertions(+), 56 deletions(-) create mode 100644 0001-Fix-return-value-from-mod_python-init.patch rename ganglia-gmond-python2to3-modules.patch => 0002-2to3-pass.patch (91%) create mode 100644 0003-Ruff-pass.patch create mode 100644 0004-Use-raw-strings.patch create mode 100644 ganglia-3.7.2-pcre2.patch diff --git a/0001-Fix-return-value-from-mod_python-init.patch b/0001-Fix-return-value-from-mod_python-init.patch new file mode 100644 index 0000000..db32809 --- /dev/null +++ b/0001-Fix-return-value-from-mod_python-init.patch @@ -0,0 +1,60 @@ +From 4ca52a1be8ef9b2ce1c62fdb4e5ba4db44132ad0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Tue, 15 Oct 2024 20:24:40 +0200 +Subject: [PATCH] Fix return value from mod_python init + +--- + gmond/modules/python/mod_python.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/gmond/modules/python/mod_python.c b/gmond/modules/python/mod_python.c +index 484429e..cdfeb7e 100644 +--- a/gmond/modules/python/mod_python.c ++++ b/gmond/modules/python/mod_python.c +@@ -601,11 +601,14 @@ static struct PyModuleDef moduledef = { + #define INITERROR return NULL + + PyMODINIT_FUNC PyInit_metric_init(apr_pool_t *p) ++ + #else ++ + #define INITERROR return + + static int pyth_metric_init (apr_pool_t *p) + #endif ++ + { + DIR *dp; + struct dirent *entry; +@@ -796,6 +799,16 @@ static int pyth_metric_init (apr_pool_t *p) + #endif + } + ++#if PY_MAJOR_VERSION >= 3 ++static int pyth_metric_init (apr_pool_t *p) { ++ if (PyInit_metric_init(p) == NULL) { ++ return 1; ++ } else { ++ return 0; ++ } ++} ++#endif ++ + static apr_status_t pyth_metric_cleanup ( void *data) + { + PyObject *pcleanup, *pobj; +@@ -913,11 +926,7 @@ static g_val_t pyth_metric_handler( int metric_index ) + mmodule python_module = + { + STD_MMODULE_STUFF, +-#if PY_MAJOR_VERSION >= 3 +- (int (*)(apr_pool_t *))PyInit_metric_init, +-#else + pyth_metric_init, +-#endif + NULL, + NULL, /* defined dynamically */ + pyth_metric_handler, +-- +2.47.0 + diff --git a/ganglia-gmond-python2to3-modules.patch b/0002-2to3-pass.patch similarity index 91% rename from ganglia-gmond-python2to3-modules.patch rename to 0002-2to3-pass.patch index 9d8ffeb..d4525ca 100644 --- a/ganglia-gmond-python2to3-modules.patch +++ b/0002-2to3-pass.patch @@ -1,5 +1,36 @@ +From ca162aba2b52e50b29ef107eb60f54ecb9f0442d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Mon, 14 Oct 2024 20:25:28 +0200 +Subject: [PATCH 2/3] 2to3 pass + +--- + .../apache_status/apache_status.py | 38 +++++++++---------- + gmond/python_modules/cpu/cpu_stats.py | 12 +++--- + gmond/python_modules/db/DBUtil.py | 13 ++++--- + gmond/python_modules/db/mysql.py | 11 +++--- + gmond/python_modules/db/redis.py | 6 +-- + gmond/python_modules/db/riak.py | 18 ++++----- + gmond/python_modules/disk/diskfree.py | 2 +- + gmond/python_modules/disk/diskstat.py | 4 +- + gmond/python_modules/disk/multidisk.py | 4 +- + gmond/python_modules/example/example.py | 6 +-- + gmond/python_modules/example/spfexample.py | 4 +- + gmond/python_modules/memcached/memcached.py | 20 +++++----- + gmond/python_modules/memory/mem_stats.py | 4 +- + .../python_modules/network/multi_interface.py | 12 +++--- + gmond/python_modules/network/netstats.py | 16 ++++---- + gmond/python_modules/network/tcpconn.py | 8 ++-- + gmond/python_modules/network/traffic1.py | 18 ++++----- + gmond/python_modules/nfs/nfsstats.py | 6 +-- + gmond/python_modules/process/procstat.py | 34 ++++++++--------- + gmond/python_modules/ssl/entropy.py | 2 +- + gmond/python_modules/varnish/varnish.py | 12 +++--- + gmond/python_modules/vm_stats/vm_stats.py | 12 +++--- + gmond/python_modules/xen/xenstats.py | 2 +- + 23 files changed, 133 insertions(+), 131 deletions(-) + diff --git a/gmond/python_modules/apache_status/apache_status.py b/gmond/python_modules/apache_status/apache_status.py -index e33e5ea..bfc2bae 100755 +index 580e893..fba14ee 100755 --- a/gmond/python_modules/apache_status/apache_status.py +++ b/gmond/python_modules/apache_status/apache_status.py @@ -4,7 +4,7 @@ @@ -42,7 +73,7 @@ index e33e5ea..bfc2bae 100755 for line in res: split_line = line.rstrip().split(": ") -@@ -92,20 +92,20 @@ def get_metrics(): +@@ -96,20 +96,20 @@ def get_metrics(): metric_name = long_metric_name metrics[metric_name] = split_line[1] @@ -67,7 +98,7 @@ index e33e5ea..bfc2bae 100755 for line in res: regMatch = SSL_REGEX.match(line) -@@ -115,7 +115,7 @@ def get_metrics(): +@@ -119,7 +119,7 @@ def get_metrics(): #print SSL_NAME_PREFIX + key + "=" + linebits[key] metrics[SSL_NAME_PREFIX + key] = linebits[key] @@ -76,7 +107,7 @@ index e33e5ea..bfc2bae 100755 traceback.print_exc() LAST_METRICS = copy.deepcopy(METRICS) -@@ -134,7 +134,7 @@ def get_value(name): +@@ -138,7 +138,7 @@ def get_value(name): try: result = metrics['data'][name] @@ -85,7 +116,7 @@ index e33e5ea..bfc2bae 100755 result = 0 return result -@@ -155,7 +155,7 @@ def get_delta(name): +@@ -159,7 +159,7 @@ def get_delta(name): try: delta = multiplier * (float(curr_metrics['data'][name]) - float(last_metrics['data'][name])) / (curr_metrics['time'] - last_metrics['time']) if delta < 0: @@ -94,7 +125,7 @@ index e33e5ea..bfc2bae 100755 delta = 0 except KeyError: delta = 0.0 -@@ -165,7 +165,7 @@ def get_delta(name): +@@ -169,7 +169,7 @@ def get_delta(name): def create_desc(prop): d = Desc_Skel.copy() @@ -103,7 +134,7 @@ index e33e5ea..bfc2bae 100755 d[k] = v return d -@@ -173,8 +173,8 @@ def create_desc(prop): +@@ -177,8 +177,8 @@ def create_desc(prop): def metric_init(params): global descriptors, Desc_Skel, SERVER_STATUS_URL, COLLECT_SSL @@ -114,7 +145,7 @@ index e33e5ea..bfc2bae 100755 if "metric_group" not in params: params["metric_group"] = "apache" -@@ -261,7 +261,7 @@ def metric_init(params): +@@ -265,7 +265,7 @@ def metric_init(params): "description": "Uptime", })) @@ -123,7 +154,7 @@ index e33e5ea..bfc2bae 100755 descriptors.append(create_desc({ "name" : k, "call_back" : get_value, -@@ -400,9 +400,9 @@ if __name__ == '__main__': +@@ -404,9 +404,9 @@ if __name__ == '__main__': for d in descriptors: v = d['call_back'](d['name']) if d['name'] == NAME_PREFIX + "rps": @@ -419,18 +450,9 @@ index 4cde607..79962ca 100644 + print('Sleeping 15 seconds') time.sleep(15) diff --git a/gmond/python_modules/disk/multidisk.py b/gmond/python_modules/disk/multidisk.py -index 5dff161..86bf456 100644 +index 5dff161..b26bf59 100644 --- a/gmond/python_modules/disk/multidisk.py +++ b/gmond/python_modules/disk/multidisk.py -@@ -30,7 +30,7 @@ - #* Author: Brad Nicholes (bnicholes novell.com) - #******************************************************************************/ - --import statvfs -+#import statvfs - import os - import ganglia - @@ -118,7 +118,7 @@ def metric_init(params): continue @@ -581,7 +603,7 @@ index 932a85b..b0cdc16 100644 - print 'value for %s is %f' % (d['name'], v) + print('value for %s is %f' % (d['name'], v)) diff --git a/gmond/python_modules/network/multi_interface.py b/gmond/python_modules/network/multi_interface.py -index 3f9b45d..f1da60a 100644 +index 456704b..e4b1b04 100644 --- a/gmond/python_modules/network/multi_interface.py +++ b/gmond/python_modules/network/multi_interface.py @@ -74,7 +74,7 @@ net_stats_file = "/proc/net/dev" @@ -624,65 +646,72 @@ index 3f9b45d..f1da60a 100644 + print(sys.exc_info()[0]) os._exit(1) diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py -index f9c6795..afa2165 100644 +index 66c378d..ba0c56f 100644 --- a/gmond/python_modules/network/netstats.py +++ b/gmond/python_modules/network/netstats.py -@@ -49,6 +49,10 @@ def get_metrics(): - new_metrics[metric_group] = dict() - for value in metrics: - # Skip first -+ try: -+ value = int(value) -+ except ValueError: -+ value = -1 - if count > 0 and value >= 0 and count in stats_pos[metric_group]: - metric_name = stats_pos[metric_group][count] - new_metrics[metric_group][metric_name] = value -@@ -94,7 +98,7 @@ def get_delta(name): +@@ -82,7 +82,7 @@ def get_value(name): + + try: + result = float(curr_metrics['data'][group][metric]) +- except StandardError: ++ except Exception: + result = 0 + + return result +@@ -101,7 +101,7 @@ def get_delta(name): try: delta = (float(curr_metrics['data'][group][metric]) - float(last_metrics['data'][group][metric])) / (curr_metrics['time'] - last_metrics['time']) if delta < 0: - print name + " is less 0" -+ print(name + " is less 0") ++ print((name + " is less 0")) delta = 0 except KeyError: delta = 0.0 -@@ -110,7 +114,7 @@ def get_tcploss_percentage(name): +@@ -117,7 +117,7 @@ def get_tcploss_percentage(name): try: pct = 100 * (float(curr_metrics['data']['tcpext']["tcploss"]) - float(last_metrics["data"]['tcpext']["tcploss"])) / (float(curr_metrics['data']['tcp']['outsegs']) + float(curr_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['outsegs'])) if pct < 0: - print name + " is less 0" -+ print(name + " is less 0") ++ print((name + " is less 0")) pct = 0 except KeyError: pct = 0.0 -@@ -128,7 +132,7 @@ def get_tcpattemptfail_percentage(name): +@@ -135,7 +135,7 @@ def get_tcpattemptfail_percentage(name): try: pct = 100 * (float(curr_metrics['data']['tcp']["attemptfails"]) - float(last_metrics["data"]['tcp']["attemptfails"])) / (float(curr_metrics['data']['tcp']['outsegs']) + float(curr_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['outsegs'])) if pct < 0: - print name + " is less 0" -+ print(name + " is less 0") ++ print((name + " is less 0")) pct = 0 except Exception: pct = 0.0 -@@ -144,7 +148,7 @@ def get_retrans_percentage(name): +@@ -151,7 +151,7 @@ def get_retrans_percentage(name): try: pct = 100 * (float(curr_metrics['data']['tcp']["retranssegs"]) - float(last_metrics['data']['tcp']["retranssegs"])) / (float(curr_metrics['data']['tcp']['outsegs']) + float(curr_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['insegs']) - float(last_metrics['data']['tcp']['outsegs'])) if pct < 0: - print name + " is less 0" -+ print(name + " is less 0") ++ print((name + " is less 0")) pct = 0 except KeyError: pct = 0.0 -@@ -156,7 +160,7 @@ def get_retrans_percentage(name): +@@ -163,7 +163,7 @@ def get_retrans_percentage(name): def create_desc(skel, prop): d = skel.copy() - for k, v in prop.iteritems(): -+ for k, v in prop.items(): ++ for k, v in list(prop.items()): d[k] = v return d +@@ -266,6 +266,6 @@ if __name__ == '__main__': + while True: + for d in descriptors: + v = d['call_back'](d['name']) +- print '%s = %s' % (d['name'], v) +- print 'Sleeping 15 seconds' ++ print('%s = %s' % (d['name'], v)) ++ print('Sleeping 15 seconds') + time.sleep(15) diff --git a/gmond/python_modules/network/tcpconn.py b/gmond/python_modules/network/tcpconn.py index 71bcc0f..b97d0ed 100644 --- a/gmond/python_modules/network/tcpconn.py @@ -817,7 +846,7 @@ index a383101..618b1be 100644 syslog.syslog(text) diff --git a/gmond/python_modules/process/procstat.py b/gmond/python_modules/process/procstat.py -index b26849b..172cdce 100644 +index 93ff9a9..aad5229 100644 --- a/gmond/python_modules/process/procstat.py +++ b/gmond/python_modules/process/procstat.py @@ -144,7 +144,7 @@ def get_pgid(proc): @@ -875,7 +904,7 @@ index b26849b..172cdce 100644 logging.warning(' failed getting pgid: ' + str(e)) stats[proc]['cpu'] = 0.0 stats[proc]['mem'] = 0 -@@ -389,7 +389,7 @@ def metric_init(params): +@@ -391,7 +391,7 @@ def metric_init(params): time_max = 60 for label in descriptions: for proc in PROCESSES: @@ -884,7 +913,7 @@ index b26849b..172cdce 100644 d = { 'name': 'procstat_' + proc + '_' + label, -@@ -433,12 +433,12 @@ def display_proc_stat(pid): +@@ -435,12 +435,12 @@ def display_proc_stat(pid): # Display them i = 0 for f in fields: @@ -900,7 +929,7 @@ index b26849b..172cdce 100644 def display_proc_statm(pid): -@@ -452,12 +452,12 @@ def display_proc_statm(pid): +@@ -454,12 +454,12 @@ def display_proc_statm(pid): # Display them i = 0 for f in fields: @@ -916,7 +945,7 @@ index b26849b..172cdce 100644 def metric_cleanup(): -@@ -502,7 +502,7 @@ if __name__ == '__main__': +@@ -504,7 +504,7 @@ if __name__ == '__main__': update_stats() print('') @@ -925,7 +954,7 @@ index b26849b..172cdce 100644 time.sleep(MAX_UPDATE_TIME) metric_init(params) -@@ -510,7 +510,7 @@ if __name__ == '__main__': +@@ -512,7 +512,7 @@ if __name__ == '__main__': for d in descriptors: v = d['call_back'](d['name']) if not options.quiet: @@ -1046,3 +1075,6 @@ index 67a6c21..bdb3750 100755 v = d['call_back'](d['name']) - print 'value for %s is %u' % (d['name'], v) + print('value for %s is %u' % (d['name'], v)) +-- +2.47.0 + diff --git a/0003-Ruff-pass.patch b/0003-Ruff-pass.patch new file mode 100644 index 0000000..409375c --- /dev/null +++ b/0003-Ruff-pass.patch @@ -0,0 +1,534 @@ +From 0be29755dcea7e19bc347b273fa38787ecb57252 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Mon, 14 Oct 2024 20:27:57 +0200 +Subject: [PATCH 3/3] Ruff pass + +--- + .../apache_status/apache_status.py | 5 +-- + gmond/python_modules/cpu/cpu_stats.py | 3 -- + gmond/python_modules/db/DBUtil.py | 6 ++-- + gmond/python_modules/db/mysql.py | 2 +- + gmond/python_modules/db/redis.py | 4 +-- + gmond/python_modules/db/riak.py | 9 +++--- + gmond/python_modules/disk/diskstat.py | 4 +-- + gmond/python_modules/disk/multidisk.py | 4 +-- + gmond/python_modules/memcached/memcached.py | 6 ++-- + gmond/python_modules/memory/mem_stats.py | 3 -- + .../python_modules/network/multi_interface.py | 2 +- + gmond/python_modules/network/netstats.py | 4 +-- + gmond/python_modules/network/tcpconn.py | 6 ++-- + gmond/python_modules/network/traffic1.py | 4 +-- + gmond/python_modules/nfs/nfsstats.py | 6 ++-- + gmond/python_modules/process/procstat.py | 32 +++++++++---------- + gmond/python_modules/ssl/entropy.py | 5 ++- + gmond/python_modules/varnish/varnish.py | 2 +- + gmond/python_modules/vm_stats/vm_stats.py | 1 - + gmond/python_modules/xen/xenstats.py | 2 -- + 20 files changed, 50 insertions(+), 60 deletions(-) + +diff --git a/gmond/python_modules/apache_status/apache_status.py b/gmond/python_modules/apache_status/apache_status.py +index fba14ee..d375d74 100755 +--- a/gmond/python_modules/apache_status/apache_status.py ++++ b/gmond/python_modules/apache_status/apache_status.py +@@ -2,9 +2,10 @@ + # -*- coding: utf-8 -*- + + import os +-import threading + import time +-import urllib.request, urllib.error, urllib.parse ++import urllib.request ++import urllib.error ++import urllib.parse + import traceback + import re + import copy +diff --git a/gmond/python_modules/cpu/cpu_stats.py b/gmond/python_modules/cpu/cpu_stats.py +index 16d6165..ab518cc 100644 +--- a/gmond/python_modules/cpu/cpu_stats.py ++++ b/gmond/python_modules/cpu/cpu_stats.py +@@ -1,6 +1,3 @@ +-import sys +-import traceback +-import os + import re + import time + import copy +diff --git a/gmond/python_modules/db/DBUtil.py b/gmond/python_modules/db/DBUtil.py +index 66f8a78..c7e7473 100644 +--- a/gmond/python_modules/db/DBUtil.py ++++ b/gmond/python_modules/db/DBUtil.py +@@ -28,7 +28,7 @@ pure python collections.defaultdict substitute + #from collections import defaultdict + try: + from collections import defaultdict +-except: ++except ImportError: + class defaultdict(dict): + def __init__(self, default_factory=None, *a, **kw): + if (default_factory is not None and +@@ -79,9 +79,9 @@ def longish(x): + try: + return int(x) + except ValueError: +- if(x.endswith(',')): ++ if x.endswith(','): + return longish(x[:-1]) +- if(is_hex(x.lower()) == True): ++ if is_hex(x.lower()): + return hexlongish(x) + #print "X==(%s)(%s)(%s)" %(x, x[:-1],hexlongish(x)), sys.exc_info()[0] + return longish(x[:-1]) +diff --git a/gmond/python_modules/db/mysql.py b/gmond/python_modules/db/mysql.py +index 065a6cd..5aae1cf 100644 +--- a/gmond/python_modules/db/mysql.py ++++ b/gmond/python_modules/db/mysql.py +@@ -354,7 +354,7 @@ def get_stat(name): + logging.debug("fetching %s" % name) + try: + return mysql_stats[label] +- except: ++ except KeyError: + logging.error("failed to fetch %s" % name) + return 0 + else: +diff --git a/gmond/python_modules/db/redis.py b/gmond/python_modules/db/redis.py +index 9101b49..285a625 100755 +--- a/gmond/python_modules/db/redis.py ++++ b/gmond/python_modules/db/redis.py +@@ -34,7 +34,7 @@ def metric_handler(name): + if metric_handler.auth is not None: + s.send("*2\r\n$4\r\nAUTH\r\n$%d\r\n%s\r\n" % (len(metric_handler.auth), metric_handler.auth)) + result = s.recv(100) +- if not 'OK' in result: ++ if 'OK' not in result: + return 0 + s.send("*1\r\n$4\r\nINFO\r\n") + #logging.debug("sent INFO") +@@ -83,7 +83,7 @@ def metric_handler(name): + v = cps + #logging.debug("submittincg metric %s is %s" % (n, int(v))) + metric_handler.info[n] = int(v) # TODO Use value_type. +- except Exception as e: ++ except Exception: + #logging.debug("caught exception %s" % e) + pass + s.close() +diff --git a/gmond/python_modules/db/riak.py b/gmond/python_modules/db/riak.py +index 499a04f..a399931 100755 +--- a/gmond/python_modules/db/riak.py ++++ b/gmond/python_modules/db/riak.py +@@ -24,7 +24,9 @@ import os + import sys + import threading + import time +-import urllib.request, urllib.error, urllib.parse ++import urllib.request ++import urllib.error ++import urllib.parse + import traceback + import json + +@@ -44,7 +46,7 @@ def floatable(str): + try: + float(str) + return True +- except: ++ except ValueError: + return False + + +@@ -102,7 +104,6 @@ class UpdateMetricThread(threading.Thread): + + def metric_of(self, name): + val = 0 +- mp = name.split("_")[0] + if name in self.metric: + _Lock.acquire() + val = self.metric[name] +@@ -1062,6 +1063,6 @@ if __name__ == '__main__': + except KeyboardInterrupt: + time.sleep(0.2) + os._exit(1) +- except: ++ except Exception: + traceback.print_exc() + os._exit(1) +diff --git a/gmond/python_modules/disk/diskstat.py b/gmond/python_modules/disk/diskstat.py +index 79962ca..aea335f 100644 +--- a/gmond/python_modules/disk/diskstat.py ++++ b/gmond/python_modules/disk/diskstat.py +@@ -386,7 +386,7 @@ def get_stat(name): + + try: + return stats[dev][label] +- except: ++ except Exception: + logging.warning('failed to fetch [' + dev + '] ' + name) + return 0 + else: +@@ -394,7 +394,7 @@ def get_stat(name): + + try: + return stats[label] +- except: ++ except Exception: + logging.warning('failed to fetch ' + name) + return 0 + +diff --git a/gmond/python_modules/disk/multidisk.py b/gmond/python_modules/disk/multidisk.py +index b26bf59..5ad59b5 100644 +--- a/gmond/python_modules/disk/multidisk.py ++++ b/gmond/python_modules/disk/multidisk.py +@@ -108,8 +108,8 @@ def metric_init(params): + global descriptors + f = open('/proc/mounts', 'r') + +- for l in f: +- line = l.split() ++ for buff in f: ++ line = buff.split() + if line[3].startswith('ro'): + continue + elif Remote_Mount(line[0], line[2]): +diff --git a/gmond/python_modules/memcached/memcached.py b/gmond/python_modules/memcached/memcached.py +index 8bdb57c..b5c3df4 100644 +--- a/gmond/python_modules/memcached/memcached.py ++++ b/gmond/python_modules/memcached/memcached.py +@@ -26,7 +26,7 @@ def floatable(str): + try: + float(str) + return True +- except: ++ except ValueError: + return False + + +@@ -58,7 +58,7 @@ class UpdateMetricThread(threading.Thread): + return + try: + self.join() +- except: ++ except Exception: + pass + + def run(self): +@@ -396,6 +396,6 @@ if __name__ == '__main__': + except KeyboardInterrupt: + time.sleep(0.2) + os._exit(1) +- except: ++ except Exception: + traceback.print_exc() + os._exit(1) +diff --git a/gmond/python_modules/memory/mem_stats.py b/gmond/python_modules/memory/mem_stats.py +index b0cdc16..0a6dd6a 100644 +--- a/gmond/python_modules/memory/mem_stats.py ++++ b/gmond/python_modules/memory/mem_stats.py +@@ -1,6 +1,3 @@ +-import sys +-import traceback +-import os + import re + + +diff --git a/gmond/python_modules/network/multi_interface.py b/gmond/python_modules/network/multi_interface.py +index e4b1b04..c9f898f 100644 +--- a/gmond/python_modules/network/multi_interface.py ++++ b/gmond/python_modules/network/multi_interface.py +@@ -94,7 +94,7 @@ def metric_init(params): + Desc_Skel = { + 'name' : 'XXX', + 'call_back' : get_delta, +- 'time_max' : 60, ++ 'time_max' : time_max, + 'value_type' : 'float', + 'format' : '%.0f', + 'units' : '/s', +diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py +index ba0c56f..ec65d1e 100644 +--- a/gmond/python_modules/network/netstats.py ++++ b/gmond/python_modules/network/netstats.py +@@ -2,11 +2,11 @@ + # + # /proc/net/netstat + +-import sys + import re + import time + import copy +-import string ++ ++NAME_PREFIX = 'netstat_' + + PARAMS = {} + +diff --git a/gmond/python_modules/network/tcpconn.py b/gmond/python_modules/network/tcpconn.py +index b97d0ed..cf55a6d 100644 +--- a/gmond/python_modules/network/tcpconn.py ++++ b/gmond/python_modules/network/tcpconn.py +@@ -31,6 +31,8 @@ + #******************************************************************************/ + + import os ++import threading ++import time + + OBSOLETE_POPEN = False + try: +@@ -39,8 +41,6 @@ except ImportError: + import popen2 + OBSOLETE_POPEN = True + +-import threading +-import time + + _WorkerThread = None # Worker thread object + _glock = threading.Lock() # Synchronization lock +@@ -230,7 +230,7 @@ class NetstatThread(threading.Thread): + + def shutdown(self): + self.shuttingdown = True +- if self.popenChild != None: ++ if self.popenChild is not None: + try: + self.popenChild.wait() + except OSError as e: +diff --git a/gmond/python_modules/network/traffic1.py b/gmond/python_modules/network/traffic1.py +index 9f1078f..c5fdcba 100644 +--- a/gmond/python_modules/network/traffic1.py ++++ b/gmond/python_modules/network/traffic1.py +@@ -67,8 +67,8 @@ class UpdateTrafficThread(threading.Thread): + + def update_metric(self): + f = open(self.proc_file, "r") +- for l in f: +- a = l.split(":") ++ for buff in f: ++ a = buff.split(":") + dev = a[0].lstrip() + if dev != self.target_device: + continue +diff --git a/gmond/python_modules/nfs/nfsstats.py b/gmond/python_modules/nfs/nfsstats.py +index 618b1be..2d3d279 100644 +--- a/gmond/python_modules/nfs/nfsstats.py ++++ b/gmond/python_modules/nfs/nfsstats.py +@@ -10,8 +10,6 @@ + # 2) the code is structured in a way intended to make it easy to repurpose + # the code for extracting other information out of /proc + +-import os +-import stat + import re + import time + import syslog +@@ -262,7 +260,7 @@ def metric_init(params): + else: + tests_passed = False + break +- except: ++ except Exception: + tests_passed = False + break + if not tests_passed: +@@ -362,7 +360,7 @@ def get_value(name): + for i in range(0, len(descriptors)): + if descriptors[i]['name'] == name: + break +- contents = file(descriptors[i]['file']).read() ++ contents = open(descriptors[i]['file']).read() + m = re.search(descriptors[i]['re'], contents, flags=re.MULTILINE) + + m_value = m.group(1) +diff --git a/gmond/python_modules/process/procstat.py b/gmond/python_modules/process/procstat.py +index aad5229..e5c3f9a 100644 +--- a/gmond/python_modules/process/procstat.py ++++ b/gmond/python_modules/process/procstat.py +@@ -128,14 +128,14 @@ PROCESSES = {} + + def readCpu(pid): + try: +- stat = file('/proc/' + pid + '/stat', 'rt').readline().split() ++ stat = open('/proc/' + pid + '/stat', 'rt').readline().split() + #logging.debug(' stat (' + pid + '): ' + str(stat)) + utime = int(stat[13]) + stime = int(stat[14]) + cutime = int(stat[15]) + cstime = int(stat[16]) + return (utime + stime + cutime + cstime) +- except: ++ except Exception: + logging.warning('failed to get (' + str(pid) + ') stats') + return 0 + +@@ -152,8 +152,8 @@ def get_pgid(proc): + if '.pid' in val[-4:]: + if os.path.exists(val): + logging.debug(' pidfile found') +- ppid = file(val, 'rt').readline().strip() +- pgid = file('/proc/' + ppid + '/stat', 'rt').readline().split()[4] ++ ppid = open(val, 'rt').readline().strip() ++ pgid = open('/proc/' + ppid + '/stat', 'rt').readline().split()[4] + else: + raise Exception('pidfile (' + val + ') does not exist') + +@@ -195,10 +195,10 @@ def get_pgroup(ppid, pgid): + p_list = [] + for stat_file in glob.glob('/proc/[1-9]*/stat'): + try: +- stat = file(stat_file, 'rt').readline().split() ++ stat = open(stat_file, 'rt').readline().split() + if stat[4] == pgid: + p_list.append(stat[0]) +- except: ++ except Exception: + # likely the pid has exited. this is normal. + pass + +@@ -225,7 +225,7 @@ def get_rss(pids): + try: + statm = open('/proc/' + p + '/statm', 'rt').readline().split() + #logging.debug(' statm (' + p + '): ' + str(statm)) +- except: ++ except Exception: + # Process finished, ignore this mem usage + logging.warning(' failed getting statm for pid: ' + p) + continue +@@ -261,7 +261,7 @@ def test(params): + print(' PID, ARGS') + for pid in pids: + # Read from binary file containing command line arguments +- args = file('/proc/' + pid + '/cmdline', 'rt').readline().replace('\0', ' ') ++ args = open('/proc/' + pid + '/cmdline', 'rt').readline().replace('\0', ' ') + print((' ' + pid + ' ' + args)) + + logging.debug('success testing') +@@ -283,9 +283,9 @@ def update_stats(): + logging.debug(' updating for ' + proc) + + # setup storage lists +- if not proc in stats: ++ if proc not in stats: + stats[proc] = {} +- if not proc in last_val: ++ if proc not in last_val: + last_val[proc] = {} + + ##### +@@ -347,7 +347,7 @@ def get_stat(name): + + try: + return stats[proc][label] +- except: ++ except Exception: + logging.warning('failed to fetch [' + proc + '] ' + name) + return 0 + else: +@@ -355,7 +355,7 @@ def get_stat(name): + + try: + return stats[label] +- except: ++ except Exception: + logging.warning('failed to fetch ' + name) + return 0 + else: +@@ -420,7 +420,7 @@ def metric_init(params): + + def display_proc_stat(pid): + try: +- stat = file('/proc/' + pid + '/stat', 'rt').readline().split() ++ stat = open('/proc/' + pid + '/stat', 'rt').readline().split() + + fields = [ + 'pid', 'comm', 'state', 'ppid', 'pgrp', 'session', +@@ -438,14 +438,14 @@ def display_proc_stat(pid): + print('%15s: %s' % (f, stat[i])) + i += 1 + +- except: ++ except Exception: + print(('failed to get /proc/' + pid + '/stat')) + print((traceback.print_exc(file=sys.stdout))) + + + def display_proc_statm(pid): + try: +- statm = file('/proc/' + pid + '/statm', 'rt').readline().split() ++ statm = open('/proc/' + pid + '/statm', 'rt').readline().split() + + fields = [ + 'size', 'rss', 'share', 'trs', 'drs', 'lrs', 'dt' +@@ -457,7 +457,7 @@ def display_proc_statm(pid): + print('%15s: %s' % (f, statm[i])) + i += 1 + +- except: ++ except Exception: + print(('failed to get /proc/' + pid + '/statm')) + print((traceback.print_exc(file=sys.stdout))) + +diff --git a/gmond/python_modules/ssl/entropy.py b/gmond/python_modules/ssl/entropy.py +index 71193c6..bb9f67c 100644 +--- a/gmond/python_modules/ssl/entropy.py ++++ b/gmond/python_modules/ssl/entropy.py +@@ -7,7 +7,6 @@ + # (it can reuse the pool of bits). + # Therefore if you are running SSL on the box you want to know this. + +-import sys + + + entropy_file = "/proc/sys/kernel/random/entropy_avail" +@@ -20,8 +19,8 @@ def metrics_handler(name): + except IOError: + return 0 + +- for l in f: +- line = l ++ for buff in f: ++ line = buff + + return int(line) + +diff --git a/gmond/python_modules/varnish/varnish.py b/gmond/python_modules/varnish/varnish.py +index b1a8573..e5c1b75 100755 +--- a/gmond/python_modules/varnish/varnish.py ++++ b/gmond/python_modules/varnish/varnish.py +@@ -143,7 +143,7 @@ def metric_init(lparams): + Desc_Skel = { + 'name' : 'XXX', + 'call_back' : 'XXX', +- 'time_max' : 60, ++ 'time_max' : time_max, + 'value_type' : 'float', + 'format' : '%f', + 'units' : 'XXX', +diff --git a/gmond/python_modules/vm_stats/vm_stats.py b/gmond/python_modules/vm_stats/vm_stats.py +index 2e1e8b8..8eb9c11 100644 +--- a/gmond/python_modules/vm_stats/vm_stats.py ++++ b/gmond/python_modules/vm_stats/vm_stats.py +@@ -3,7 +3,6 @@ + # + # /proc/vmstat + +-import sys + import re + import time + import copy +diff --git a/gmond/python_modules/xen/xenstats.py b/gmond/python_modules/xen/xenstats.py +index bdb3750..1c328e4 100755 +--- a/gmond/python_modules/xen/xenstats.py ++++ b/gmond/python_modules/xen/xenstats.py +@@ -18,8 +18,6 @@ + # MA 02110-1301, USA. + + import libvirt +-import os +-import time + + descriptors = list() + conn = libvirt.openReadOnly("xen:///") +-- +2.47.0 + diff --git a/0004-Use-raw-strings.patch b/0004-Use-raw-strings.patch new file mode 100644 index 0000000..722e6aa --- /dev/null +++ b/0004-Use-raw-strings.patch @@ -0,0 +1,62 @@ +From 21656da69738482cca947cb70ad9ef25ac95cbfa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Mon, 14 Oct 2024 20:36:13 +0200 +Subject: [PATCH 4/4] Use raw strings + +--- + gmond/python_modules/memory/mem_stats.py | 2 +- + gmond/python_modules/network/netstats.py | 4 ++-- + gmond/python_modules/vm_stats/vm_stats.py | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/gmond/python_modules/memory/mem_stats.py b/gmond/python_modules/memory/mem_stats.py +index 0a6dd6a..522268e 100644 +--- a/gmond/python_modules/memory/mem_stats.py ++++ b/gmond/python_modules/memory/mem_stats.py +@@ -26,7 +26,7 @@ def metrics_handler(name): + if name == 'mem_swap_used': + return metrics_handler('mem_swap_total') - metrics_handler('mem_swap_free') + for line in file: +- parts = re.split("\s+", line) ++ parts = re.split(r"\s+", line) + if parts[0] == metric_map[name]['name'] + ":": + # All of the measurements are in kBytes. We want to change them over + # to Bytes +diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py +index ec65d1e..3805f4b 100644 +--- a/gmond/python_modules/network/netstats.py ++++ b/gmond/python_modules/network/netstats.py +@@ -46,7 +46,7 @@ def get_metrics(): + for line in file: + if re.match("(.*): [0-9]", line): + count = 0 +- metrics = re.split("\s+", line) ++ metrics = re.split(r"\s+", line) + metric_group = metrics[0].replace(":", "").lower() + if metric_group not in stats_pos: + continue +@@ -202,7 +202,7 @@ def metric_init(params): + # Lines with + if not re.match("(.*): [0-9]", line): + count = 0 +- mapping = re.split("\s+", line) ++ mapping = re.split(r"\s+", line) + metric_group = mapping[0].replace(":", "").lower() + stats_pos[metric_group] = dict() + for metric in mapping: +diff --git a/gmond/python_modules/vm_stats/vm_stats.py b/gmond/python_modules/vm_stats/vm_stats.py +index 8eb9c11..fc5a241 100644 +--- a/gmond/python_modules/vm_stats/vm_stats.py ++++ b/gmond/python_modules/vm_stats/vm_stats.py +@@ -46,7 +46,7 @@ def get_metrics(): + # convert to dict + metrics = {} + for line in file: +- parts = re.split("\s+", line) ++ parts = re.split(r"\s+", line) + metrics[parts[0]] = parts[1] + + # update cache +-- +2.47.0 + diff --git a/ganglia-3.7.2-pcre2.patch b/ganglia-3.7.2-pcre2.patch new file mode 100644 index 0000000..64260fc --- /dev/null +++ b/ganglia-3.7.2-pcre2.patch @@ -0,0 +1,126 @@ +From https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1000041 + +--- ganglia.orig/configure.ac ++++ ganglia/configure.ac +@@ -520,14 +520,20 @@ + echo "Added -L$libpcrepath/${LIB_SUFFIX} to LDFLAGS" + fi + if test x"$libpcre" == xyes ; then +- AC_CHECK_HEADERS([pcre/pcre.h pcre.h]) +- AC_CHECK_LIB(pcre, pcre_compile) +- if test x"$ac_cv_lib_pcre_pcre_compile" = xyes; then +- echo "Found a suitable pcre library" +- else +- echo "libpcre not found, specify --with-libpcre=no to build without PCRE support" +- exit 1; +- fi ++ AC_CHECK_HEADERS([pcre2.h], [], [], [[#define PCRE2_CODE_UNIT_WIDTH 8]]) ++ LIBS="$LIBS -lpcre2-8" ++ AC_MSG_CHECKING([for pcre2_match_data_create in -lpcre2-8]) ++ AC_LINK_IFELSE( ++ [AC_LANG_PROGRAM([[#define PCRE2_CODE_UNIT_WIDTH 8 ++ #include ++ ]], ++ [[pcre2_match_data *md; ++ md = pcre2_match_data_create (16, NULL);]])], ++ [AC_DEFINE([HAVE_LIBPCRE], [1], [Define if the PCRE2 library is available]) ++ AC_MSG_RESULT([yes]) ++ AC_MSG_RESULT([Found a suitable pcre library])], ++ [AC_MSG_RESULT([no]) ++ AC_MSG_FAILURE([libpcre not found, specify --with-libpcre=no to build without PCRE support], [1])]) + else + echo "building without PCRE support" + fi +--- ganglia.orig/gmond/gmond.c ++++ ganglia/gmond/gmond.c +@@ -38,11 +38,8 @@ + #include + + #ifdef HAVE_LIBPCRE +-#if defined (HAVE_PCRE_PCRE_H) +-#include +-#else +-#include +-#endif ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + #endif + + #include "cmdline.h" /* generated by cmdline.sh which runs gengetopt */ +@@ -2650,10 +2647,11 @@ + + if(name_match != NULL) + { +- pcre *pcre_re; +- const char *pcre_err_ptr; +- int pcre_err_offset; +- int pcre_ovector[PCRE_OVECCOUNT]; ++ pcre2_code *pcre_re; ++ pcre2_match_data *pcre_md; ++ int pcre_err_ptr; ++ size_t pcre_err_offset; ++ size_t *pcre_ovector; + int pcre_rc; + + apr_hash_index_t *hi; +@@ -2662,9 +2660,9 @@ + const char *key; + int found = 0; + +- if((pcre_re = pcre_compile(name_match, 0, &pcre_err_ptr, &pcre_err_offset, NULL)) == NULL) ++ if((pcre_re = pcre2_compile((PCRE2_SPTR)name_match, PCRE2_ZERO_TERMINATED, 0, &pcre_err_ptr, &pcre_err_offset, NULL)) == NULL) + { +- err_msg ("pcre_compile failed on %s\n", name_match); ++ err_msg ("pcre2_compile failed on %s\n", name_match); + exit (1); + } + +@@ -2676,6 +2674,8 @@ + exit(EXIT_FAILURE); + } + ++ pcre_md = pcre2_match_data_create(PCRE_OVECCOUNT, NULL); ++ + for(hi = apr_hash_first(p, metric_callbacks); + hi; + hi = apr_hash_next(hi)) +@@ -2683,17 +2683,17 @@ + Ganglia_metric_callback *cb; + + apr_hash_this(hi, (const void**)&key, NULL, &val); +- if((pcre_rc = pcre_exec(pcre_re, NULL, key, strlen(key), 0, 0, pcre_ovector, PCRE_OVECCOUNT)) < 1) ++ if((pcre_rc = pcre2_match(pcre_re, (PCRE2_SPTR)key, strlen(key), 0, 0, pcre_md, NULL)) < 1) + { + switch(pcre_rc) + { +- case PCRE_ERROR_NOMATCH: ++ case PCRE2_ERROR_NOMATCH: + break; + case 0: + /* output vector not big enough */ + default: + /* unexpected error */ +- err_msg ("unexpected pcre_exec error\n"); ++ err_msg ("unexpected pcre2_match error\n"); + exit (1); + } + } +@@ -2703,6 +2703,8 @@ + char *title_tmpl = cfg_getstr ( metric, "title"); + float value_threshold = cfg_getfloat( metric, "value_threshold"); + ++ pcre_ovector = pcre2_get_ovector_pointer(pcre_md); ++ + if(title_tmpl != NULL) + { + struct iovec *ptrs; +@@ -2772,6 +2774,8 @@ + if (!found) + err_msg("Unable to find any metric information for '%s'. Possible that a module has not been loaded.\n", name_match); + ++ pcre2_match_data_free(pcre_md); ++ pcre2_code_free(pcre_re); + } + else + #endif + diff --git a/ganglia.spec b/ganglia.spec index c5a55eb..7088480 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,7 +14,7 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 53%{?dist} +Release: 54%{?dist} # Automatically converted from old format: BSD - review is highly recommended. License: LicenseRef-Callaway-BSD URL: http://ganglia.sourceforge.net/ @@ -32,8 +32,12 @@ Patch20: ganglia-web-3.7.2-path.patch Patch21: ganglia-web-3.7.6-pr-379.patch Patch22: ganglia-web-3.7.6-php8.patch Patch30: ganglia-gmond-python2to3.patch -Patch31: ganglia-gmond-python2to3-modules.patch -Patch32: ganglia-3.7.2-autoconf-python3.patch +Patch31: 0002-2to3-pass.patch +Patch32: 0003-Ruff-pass.patch +Patch33: 0004-Use-raw-strings.patch +Patch34: 0001-Fix-return-value-from-mod_python-init.patch +Patch40: ganglia-3.7.2-autoconf-python3.patch +Patch50: ganglia-3.7.2-pcre2.patch %if 0%{?systemd} BuildRequires: systemd %endif @@ -54,8 +58,10 @@ BuildRequires: libconfuse-devel BuildRequires: libmemcached-devel BuildRequires: libpng-devel BuildRequires: make -%if 0%{?fedora} < 38 || 0%{?rhel} +%if 0%{?rhel} BuildRequires: pcre-devel +%else +BuildRequires: pcre2-devel %endif %{?py2:BuildRequires: python2-devel} %{?py3:BuildRequires: python3-devel} @@ -171,10 +177,16 @@ programmers can use to build scalable cluster or grid applications %patch -P 1 -p1 %patch -P 30 -p1 %{?py3:%patch -P 31 -p1} -%patch -P 32 -p1 +%{?py3:%patch -P 32 -p1} +%{?py3:%patch -P 33 -p1} +%{?py3:%patch -P 34 -p1} +%patch -P 40 -p1 %if 0%{?fedora} || 0%{?rhel} > 7 %patch -P 10 -p1 %endif +%if 0%{?fedora} +%patch -P 50 -p1 +%endif # fix broken systemd support install -m 0644 %{SOURCE2} gmond/gmond.service.in install -m 0644 %{SOURCE3} gmetad/gmetad.service.in @@ -218,9 +230,7 @@ export CFLAGS="%{optflags} -fcommon" --with-memcached \ --disable-static \ --enable-shared \ -%if 0%{?fedora} > 37 - --with-libpcre=no \ -%endif + --with-libpcre=yes \ %if 0%{?with_python} --enable-python \ %if 0%{?py2} @@ -454,6 +464,10 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Tue Oct 15 2024 Terje Rosten - 3.7.6-54 +- Various fixes to improve Python 3 support +- Add back regex support on Fedora (patch from Debian, thanks!) + * Sat Sep 28 2024 Terje Rosten - 3.7.6-53 - Add patch to improve compat with PHP 8 From 83e544951ee47d43f96eabd48668a81724683218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20R=C3=B8sten?= Date: Mon, 4 Nov 2024 20:19:13 +0100 Subject: [PATCH 08/15] Add forgotten int() conversion patch Add forgotten int() conversion patch Add forgotten int() conversion patch Add forgotten int() conversion patch Add forgotten int() conversion patch Add forgotten int() conversion patch --- ...loop-might-contain-non-integer-input.patch | 27 +++++++++++++++++++ ganglia.spec | 9 +++++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 0005-First-loop-might-contain-non-integer-input.patch diff --git a/0005-First-loop-might-contain-non-integer-input.patch b/0005-First-loop-might-contain-non-integer-input.patch new file mode 100644 index 0000000..4077272 --- /dev/null +++ b/0005-First-loop-might-contain-non-integer-input.patch @@ -0,0 +1,27 @@ +From 1d9688e7059d0a93c27bf4e74f26ad3cf1120837 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Terje=20R=C3=B8sten?= +Date: Mon, 4 Nov 2024 20:06:47 +0100 +Subject: [PATCH 5/5] First loop might contain non integer input + +--- + gmond/python_modules/network/netstats.py | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py +index 3805f4b..76f6b68 100644 +--- a/gmond/python_modules/network/netstats.py ++++ b/gmond/python_modules/network/netstats.py +@@ -52,6 +52,10 @@ def get_metrics(): + continue + new_metrics[metric_group] = dict() + for value in metrics: ++ try: ++ value = int(value) ++ except ValueError: ++ value = -1 + # Skip first + if count > 0 and value >= 0 and count in stats_pos[metric_group]: + metric_name = stats_pos[metric_group][count] +-- +2.47.0 + diff --git a/ganglia.spec b/ganglia.spec index 7088480..40b2588 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,7 +14,7 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 54%{?dist} +Release: 55%{?dist} # Automatically converted from old format: BSD - review is highly recommended. License: LicenseRef-Callaway-BSD URL: http://ganglia.sourceforge.net/ @@ -35,7 +35,8 @@ Patch30: ganglia-gmond-python2to3.patch Patch31: 0002-2to3-pass.patch Patch32: 0003-Ruff-pass.patch Patch33: 0004-Use-raw-strings.patch -Patch34: 0001-Fix-return-value-from-mod_python-init.patch +Patch34: 0005-First-loop-might-contain-non-integer-input.patch +Patch35: 0001-Fix-return-value-from-mod_python-init.patch Patch40: ganglia-3.7.2-autoconf-python3.patch Patch50: ganglia-3.7.2-pcre2.patch %if 0%{?systemd} @@ -180,6 +181,7 @@ programmers can use to build scalable cluster or grid applications %{?py3:%patch -P 32 -p1} %{?py3:%patch -P 33 -p1} %{?py3:%patch -P 34 -p1} +%{?py3:%patch -P 35 -p1} %patch -P 40 -p1 %if 0%{?fedora} || 0%{?rhel} > 7 %patch -P 10 -p1 @@ -464,6 +466,9 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Mon Nov 04 2024 Terje Rosten - 3.7.6-55 +- Add forgotten int() conversion patch + * Tue Oct 15 2024 Terje Rosten - 3.7.6-54 - Various fixes to improve Python 3 support - Add back regex support on Fedora (patch from Debian, thanks!) From 70b3e9078b7a9008a4e33a3983a73f767f49110e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 19:08:37 +0000 Subject: [PATCH 09/15] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- ganglia.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ganglia.spec b/ganglia.spec index 40b2588..7fa091a 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,7 +14,7 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 55%{?dist} +Release: 56%{?dist} # Automatically converted from old format: BSD - review is highly recommended. License: LicenseRef-Callaway-BSD URL: http://ganglia.sourceforge.net/ @@ -466,6 +466,9 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Thu Jan 16 2025 Fedora Release Engineering - 3.7.2-56 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Mon Nov 04 2024 Terje Rosten - 3.7.6-55 - Add forgotten int() conversion patch From c0f6480f78ccd493d2f417631f2ef3398706b659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20R=C3=B8sten?= Date: Sat, 29 Mar 2025 14:42:56 +0100 Subject: [PATCH 10/15] Use sysusers on FC43+ Fix changelog --- ganglia.spec | 25 ++++++++++++++++++++----- ganglia.sysusers.conf | 1 + 2 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 ganglia.sysusers.conf diff --git a/ganglia.spec b/ganglia.spec index 7fa091a..da795f6 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,7 +14,7 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 56%{?dist} +Release: 57%{?dist} # Automatically converted from old format: BSD - review is highly recommended. License: LicenseRef-Callaway-BSD URL: http://ganglia.sourceforge.net/ @@ -25,6 +25,7 @@ Source3: gmetad.service Source4: ganglia-httpd24.conf.d Source5: ganglia-httpd.conf.d Source6: conf.php +Source7: ganglia.sysusers.conf Patch0: ganglia-3.7.2-185ab6.patch Patch1: ganglia-3.7.2-gcc14-cast.patch Patch10: ganglia-3.7.2-tirpc-hack.patch @@ -335,10 +336,17 @@ chmod 0644 %{buildroot}%{_datadir}/%{name}/css/smoothness/jquery-ui-1.10.2.custo # Remove shebang %{?with_python:sed -i '1{\@^#!@d}' %{buildroot}%{_libdir}/%{name}/python_modules/*.py} +# Sysusers +%if 0%{?fedora} > 42 +install -m0644 -D %{SOURCE7} %{buildroot}%{_sysusersdir}/ganglia.conf +%endif + +%if 0%{?rhel} || 0%{?fedora} < 43 %pre ## Add the "ganglia" user /usr/sbin/useradd -c "Ganglia Monitoring System" \ -s /sbin/nologin -r -d %{_localstatedir}/lib/%{name} ganglia 2> /dev/null || : +%endif %if 0%{?systemd} %post gmond @@ -396,6 +404,9 @@ end %dir %{_libdir}/ganglia %{_libdir}/ganglia/*.so %{?with_python:%exclude %{_libdir}/ganglia/modpython.so} +%if 0%{?fedora} > 42 +%{_sysusersdir}/ganglia.conf +%endif %files gmetad %dir %{_localstatedir}/lib/%{name} @@ -466,20 +477,24 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Sat Mar 29 2025 Terje Rosten - 3.7.2-57 +- Use sysusers on FC43+ +- Fix changelog + * Thu Jan 16 2025 Fedora Release Engineering - 3.7.2-56 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild -* Mon Nov 04 2024 Terje Rosten - 3.7.6-55 +* Mon Nov 04 2024 Terje Rosten - 3.7.2-55 - Add forgotten int() conversion patch -* Tue Oct 15 2024 Terje Rosten - 3.7.6-54 +* Tue Oct 15 2024 Terje Rosten - 3.7.2-54 - Various fixes to improve Python 3 support - Add back regex support on Fedora (patch from Debian, thanks!) -* Sat Sep 28 2024 Terje Rosten - 3.7.6-53 +* Sat Sep 28 2024 Terje Rosten - 3.7.2-53 - Add patch to improve compat with PHP 8 -* Wed Aug 28 2024 Miroslav Suchý - 3.7.6-52 +* Wed Aug 28 2024 Miroslav Suchý - 3.7.2-52 - convert license to SPDX * Wed Jul 17 2024 Fedora Release Engineering - 3.7.2-51 diff --git a/ganglia.sysusers.conf b/ganglia.sysusers.conf new file mode 100644 index 0000000..fcc615e --- /dev/null +++ b/ganglia.sysusers.conf @@ -0,0 +1 @@ +u ganglia - 'Ganglia Monitoring System' /var/lib/ganglia - From e2eca71c61e526de7efd7917d7cf2ed93fe3a777 Mon Sep 17 00:00:00 2001 From: Terje Rosten Date: Sat, 5 Apr 2025 21:05:46 +0200 Subject: [PATCH 11/15] Follow PHP quote rules --- ganglia-web-3.7.6-php8.patch | 4 ++-- ganglia.spec | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ganglia-web-3.7.6-php8.patch b/ganglia-web-3.7.6-php8.patch index 9fcadb0..6a946c7 100644 --- a/ganglia-web-3.7.6-php8.patch +++ b/ganglia-web-3.7.6-php8.patch @@ -129,7 +129,7 @@ index 01ca10d..bda8f84 100644 } ?> diff --git a/metric_group_view.php b/metric_group_view.php -index 13dc0a1..f526545 100644 +index 13dc0a1..617a3aa 100644 --- a/metric_group_view.php +++ b/metric_group_view.php @@ -105,7 +105,7 @@ $cluster_url = rawurlencode($clustername); @@ -137,7 +137,7 @@ index 13dc0a1..f526545 100644 $baseGraphArgs = "c=$cluster_url&h=$hostname" . "&r=$range&z=$size&jr=$jobrange" - . "&js=$jobstart&st=$cluster[LOCALTIME]"; -+ . "&js=$jobstart&st=$cluster['LOCALTIME']"; ++ . "&js=$jobstart&st={$cluster['LOCALTIME']}"; if ($cs) $baseGraphArgs .= "&cs=" . rawurlencode($cs); if ($ce) diff --git a/ganglia.spec b/ganglia.spec index da795f6..a771357 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,7 +14,7 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 57%{?dist} +Release: 58%{?dist} # Automatically converted from old format: BSD - review is highly recommended. License: LicenseRef-Callaway-BSD URL: http://ganglia.sourceforge.net/ @@ -477,6 +477,9 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Sat Apr 05 2025 Terje Rosten - 3.7.2-58 +- Follow PHP quote rules + * Sat Mar 29 2025 Terje Rosten - 3.7.2-57 - Use sysusers on FC43+ - Fix changelog From a157a44a4ed88641af1d57607d840a33d3fcd823 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Mon, 2 Jun 2025 19:55:46 +0200 Subject: [PATCH 12/15] Rebuilt for Python 3.14 --- ganglia.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ganglia.spec b/ganglia.spec index a771357..17007ab 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,7 +14,7 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 58%{?dist} +Release: 59%{?dist} # Automatically converted from old format: BSD - review is highly recommended. License: LicenseRef-Callaway-BSD URL: http://ganglia.sourceforge.net/ @@ -477,6 +477,9 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Mon Jun 02 2025 Python Maint - 3.7.2-59 +- Rebuilt for Python 3.14 + * Sat Apr 05 2025 Terje Rosten - 3.7.2-58 - Follow PHP quote rules From 66edd50471832c81619f55163988bd68f73451d6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 20:56:47 +0000 Subject: [PATCH 13/15] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- ganglia.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ganglia.spec b/ganglia.spec index 17007ab..57d9942 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -14,7 +14,7 @@ Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 59%{?dist} +Release: 60%{?dist} # Automatically converted from old format: BSD - review is highly recommended. License: LicenseRef-Callaway-BSD URL: http://ganglia.sourceforge.net/ @@ -477,6 +477,9 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Wed Jul 23 2025 Fedora Release Engineering - 3.7.2-60 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Mon Jun 02 2025 Python Maint - 3.7.2-59 - Rebuilt for Python 3.14 From 266569fcb8c48ea4a3fd55028ad9ecf4c7fc22ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20R=C3=B8sten?= Date: Sun, 28 Sep 2025 21:48:55 +0200 Subject: [PATCH 14/15] Port to epel10 Add TZ patches Remove legacy libart_lgpl-devel buildreq Fix URL --- 0001-Sanitize-input-for-timezone.patch | 34 +++++++++++++++++++ ...e-supplied-timezone-is-a-valid-timez.patch | 25 ++++++++++++++ ganglia.spec | 25 +++++++++----- 3 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 0001-Sanitize-input-for-timezone.patch create mode 100644 0002-Validate-that-the-supplied-timezone-is-a-valid-timez.patch diff --git a/0001-Sanitize-input-for-timezone.patch b/0001-Sanitize-input-for-timezone.patch new file mode 100644 index 0000000..3093b39 --- /dev/null +++ b/0001-Sanitize-input-for-timezone.patch @@ -0,0 +1,34 @@ +From 092f16cafa0a1ef5f001a35b54dd896f601f1428 Mon Sep 17 00:00:00 2001 +From: Vladimir Vuksan <44271-vvuksan-fastly@users.noreply.drupalcode.org> +Date: Mon, 5 May 2025 10:16:00 -0400 +Subject: [PATCH 1/2] Sanitize input for timezone + +--- + graph.php | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/graph.php b/graph.php +index e8a7a9c..fdf9c86 100644 +--- a/graph.php ++++ b/graph.php +@@ -946,7 +946,7 @@ function rrdgraph_cmd_build($rrdtool_graph, + + $command = ''; + if (isset($_SESSION['tz']) && ($_SESSION['tz'] != '')) +- $command .= "TZ='" . $_SESSION['tz'] . "' "; ++ $command .= "TZ='" . escapeshellcmd($_SESSION['tz']) . "' "; + + $command .= + $conf['rrdtool'] . +@@ -1123,7 +1123,7 @@ function output_data_to_external_format($rrdtool_graph_series, + + $command = ''; + if (isset($_SESSION['tz']) && ($_SESSION['tz'] != '')) +- $command .= "TZ='" . $_SESSION['tz'] . "' "; ++ $command .= "TZ='" . escapeshellcmd($_SESSION['tz']) . "' "; + + $command .= $rrdtool . + " xport --start '" . $rrdtool_graph_start . +-- +2.51.0 + diff --git a/0002-Validate-that-the-supplied-timezone-is-a-valid-timez.patch b/0002-Validate-that-the-supplied-timezone-is-a-valid-timez.patch new file mode 100644 index 0000000..0fc5319 --- /dev/null +++ b/0002-Validate-that-the-supplied-timezone-is-a-valid-timez.patch @@ -0,0 +1,25 @@ +From bd2a339a510f0da021d3adededdfa98006f03001 Mon Sep 17 00:00:00 2001 +From: Vladimir Vuksan <44271-vvuksan-fastly@users.noreply.drupalcode.org> +Date: Mon, 5 May 2025 10:30:48 -0400 +Subject: [PATCH 2/2] Validate that the supplied timezone is a valid timezone + +--- + header.php | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/header.php b/header.php +index 729fe27..a50c41b 100644 +--- a/header.php ++++ b/header.php +@@ -1,7 +1,7 @@ + 9 BuildRequires: pcre2-devel +%else +BuildRequires: pcre-devel %endif %{?py2:BuildRequires: python2-devel} %{?py3:BuildRequires: python3-devel} @@ -187,7 +188,7 @@ programmers can use to build scalable cluster or grid applications %if 0%{?fedora} || 0%{?rhel} > 7 %patch -P 10 -p1 %endif -%if 0%{?fedora} +%if 0%{?fedora} || 0%{?rhel} > 9 %patch -P 50 -p1 %endif # fix broken systemd support @@ -200,6 +201,8 @@ pushd web %patch -P 20 -p1 %patch -P 21 -p1 %patch -P 22 -p1 +%patch -P 23 -p1 +%patch -P 24 -p1 popd %build @@ -214,7 +217,7 @@ automake --add-missing --copy --foreign autoconf -f || exit 1 %endif -%if 0%{?fedora} > 36 +%if 0%{?fedora} > 36 || 0%{?rhel} > 9 pushd libmetrics aclocal -I m4 autoheader @@ -477,6 +480,12 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Sun Sep 28 2025 Terje Rosten - 3.7.2-61 +- Port to epel10 +- Add TZ patches +- Remove legacy libart_lgpl-devel buildreq +- Fix URL + * Wed Jul 23 2025 Fedora Release Engineering - 3.7.2-60 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild From c3c5e6fa74f7207128bd549369f542f54b00e9d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Terje=20R=C3=B8sten?= Date: Mon, 29 Sep 2025 18:23:03 +0200 Subject: [PATCH 15/15] Some refactoring --- ganglia.spec | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/ganglia.spec b/ganglia.spec index 8053720..b45259d 100644 --- a/ganglia.spec +++ b/ganglia.spec @@ -11,10 +11,30 @@ %global py3 1 %endif +%if 0%{?fedora} || 0%{?rhel} > 9 +%global pcre2 1 +%global autoconf_fix 1 +%endif + +%if 0%{?fedora} || 0%{?rhel} > 7 +%global tirpc 1 +%global php_xml 1 +%endif + +%if 0%{?fedora} > 42 +%global sysusers 1 +%else +%global legacy_users 1 +%endif + +%if 0%{?fedora} || 0%{?rhel} > 6 +%global httpd24 1 +%endif + Summary: Distributed Monitoring System Name: ganglia Version: %{gangver} -Release: 61%{?dist} +Release: 62%{?dist} # Automatically converted from old format: BSD - review is highly recommended. License: LicenseRef-Callaway-BSD URL: https://github.com/ganglia @@ -45,7 +65,7 @@ Patch50: ganglia-3.7.2-pcre2.patch %if 0%{?systemd} BuildRequires: systemd %endif -%if 0%{?fedora} || 0%{?rhel} > 7 +%if 0%{?tirpc} BuildRequires: rpcgen BuildRequires: libtirpc-devel BuildRequires: autoconf @@ -61,7 +81,7 @@ BuildRequires: libconfuse-devel BuildRequires: libmemcached-devel BuildRequires: libpng-devel BuildRequires: make -%if 0%{?fedora} || 0%{?rhel} > 9 +%if 0%{?pcre2} BuildRequires: pcre2-devel %else BuildRequires: pcre-devel @@ -84,7 +104,7 @@ Requires: rrdtool Requires: php Requires: php-gd Requires: %{name}-gmetad = %{gangver}-%{release} -%if 0%{?fedora} || 0%{?rhel} > 7 +%if 0%{?php_xml} Requires: php-xml %endif %description web @@ -185,10 +205,10 @@ programmers can use to build scalable cluster or grid applications %{?py3:%patch -P 34 -p1} %{?py3:%patch -P 35 -p1} %patch -P 40 -p1 -%if 0%{?fedora} || 0%{?rhel} > 7 +%if 0%{?tirpc} %patch -P 10 -p1 %endif -%if 0%{?fedora} || 0%{?rhel} > 9 +%if 0%{?pcre2} %patch -P 50 -p1 %endif # fix broken systemd support @@ -208,7 +228,7 @@ popd %build touch Makefile.am -%if 0%{?fedora} || 0%{?rhel} > 7 +%if 0%{?tirpc} aclocal -I m4 autoheader automake --add-missing --copy --foreign 2>/dev/null @@ -217,7 +237,7 @@ automake --add-missing --copy --foreign autoconf -f || exit 1 %endif -%if 0%{?fedora} > 36 || 0%{?rhel} > 9 +%if 0%{?autoconf_fix} pushd libmetrics aclocal -I m4 autoheader @@ -304,7 +324,7 @@ ln -s ../../..%{_sysconfdir}/%{name}/conf.php \ popd ## httpd config -%if 0%{?fedora} || 0%{?rhel} > 6 +%if 0%{?httpd24} install -Dp -m 0644 %{SOURCE4} %{buildroot}%{_sysconfdir}/httpd/conf.d/%{name}.conf %else install -Dp -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/httpd/conf.d/%{name}.conf @@ -340,11 +360,12 @@ chmod 0644 %{buildroot}%{_datadir}/%{name}/css/smoothness/jquery-ui-1.10.2.custo %{?with_python:sed -i '1{\@^#!@d}' %{buildroot}%{_libdir}/%{name}/python_modules/*.py} # Sysusers -%if 0%{?fedora} > 42 +%if 0%{?sysusers} install -m0644 -D %{SOURCE7} %{buildroot}%{_sysusersdir}/ganglia.conf %endif -%if 0%{?rhel} || 0%{?fedora} < 43 + +%if 0%{?legacy_users} %pre ## Add the "ganglia" user /usr/sbin/useradd -c "Ganglia Monitoring System" \ @@ -407,7 +428,7 @@ end %dir %{_libdir}/ganglia %{_libdir}/ganglia/*.so %{?with_python:%exclude %{_libdir}/ganglia/modpython.so} -%if 0%{?fedora} > 42 +%if 0%{?sysusers} %{_sysusersdir}/ganglia.conf %endif @@ -480,6 +501,9 @@ end %dir %attr(0755,apache,apache) %{_localstatedir}/lib/%{name}-web/dwoo/compiled %changelog +* Mon Sep 29 2025 Terje Rosten - 3.7.2-62 +- Some refactoring + * Sun Sep 28 2025 Terje Rosten - 3.7.2-61 - Port to epel10 - Add TZ patches