From f54d1f5d76a4ae27992fcae385c07c7d8e0cd987 Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Sep 30 2020 07:57:46 +0000 Subject: [PATCH 1/5] report versions of components Fixes: https://pagure.io/koji/issue/2430 --- diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index 0125933..ff51f70 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -2843,6 +2843,7 @@ def anon_handle_list_hosts(goptions, session, args): parser.add_option("--quiet", action="store_true", default=goptions.quiet, help=_("Do not print header information")) parser.add_option("--show-channels", action="store_true", help=_("Show host's channels")) + parser.add_option("--show-version", action="store_true", help=_("Show host's' version")) (options, args) = parser.parse_args(args) opts = {} ensure_connection(session) @@ -2896,14 +2897,24 @@ def anon_handle_list_hosts(goptions, session, args): if not options.quiet: hdr = "{hostname:<{longest_host}} Enb Rdy Load/Cap Arches Last Update".format( longest_host=longest_host, hostname='Hostname') + if options.show_version: + hdr += " Version" if options.show_channels: - hdr += " Channels" + hdr += " Channels" print(hdr) mask = "%%(name)-%ss %%(enabled)-3s %%(ready)-3s %%(task_load)4.1f/%%(capacity)-4.1f " \ "%%(arches)-16s %%(update)-19s" % longest_host + if options.show_version: + mask += " %(version)-10s" if options.show_channels: mask += " %(channels)s" for host in hosts: + if host.get('version') is None: + # hub doesn't support it, so we don't know the version + host['version'] = 'not supported' + elif not host.get('version'): + # hub supports it, but builder doesn't report + host['version'] = '-' print(mask % host) @@ -3330,6 +3341,7 @@ def anon_handle_hostinfo(goptions, session, args): print("%s%s" % (" " * 9, line)) else: print("Comment:") + print('Version: %s' % info['version']) print("Enabled: %s" % (info['enabled'] and 'yes' or 'no')) print("Ready: %s" % (info['ready'] and 'yes' or 'no')) update = session.getLastHostUpdate(info['id']) @@ -7654,3 +7666,10 @@ def handle_unblock_notification(goptions, session, args): session.deleteNotificationBlock(n_id) if not goptions.quiet: print(_("Notification block %d successfully removed.") % n_id) + + +def handle_version(goptions, session, args): + """Report client and hub versions""" + ensure_connection(session) + print('Client: %s' % koji.__version__) + print('Hub: %s' % session.getKojiVersion()) diff --git a/docs/schema.sql b/docs/schema.sql index ac3b374..73f291d 100644 --- a/docs/schema.sql +++ b/docs/schema.sql @@ -156,7 +156,8 @@ CREATE TABLE host ( user_id INTEGER NOT NULL REFERENCES users (id), name VARCHAR(128) UNIQUE NOT NULL, task_load FLOAT CHECK (NOT task_load < 0) NOT NULL DEFAULT 0.0, - ready BOOLEAN NOT NULL DEFAULT 'false' + ready BOOLEAN NOT NULL DEFAULT 'false', + version VARCHAR(10) NOT NULL DEFAULT '' ) WITHOUT OIDS; CREATE TABLE host_config ( diff --git a/docs/source/conf.py b/docs/source/conf.py index 96ffa15..4955c4c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -13,7 +13,7 @@ # serve to show the default. #import sys -#import os +import os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -53,10 +53,11 @@ copyright = u'2017, Mike McLean, Mike B, Dennis Gilmore, Mathieu Bridon, Ian McL # |version| and |release|, also used in various other places throughout the # built documents. # +exec(open(os.path.join(os.path.dirname(__file__), '../../koji/_version.py'), 'rt').read()) # The short X.Y version. -version = '1.22' +version = '%d.%d' % locals()['__version_info__'][:2] # The full version, including alpha/beta/rc tags. -release = '1.22.1' +release = locals()['__version__'] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/hub/kojihub.py b/hub/kojihub.py index 47934fb..7121627 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -5190,6 +5190,7 @@ def get_host(hostInfo, strict=False, event=None): - comment - ready - enabled + - version """ tables = ['host_config'] joins = ['host ON host.id = host_config.host_id'] @@ -5199,6 +5200,7 @@ def get_host(hostInfo, strict=False, event=None): 'host.name': 'name', 'host.ready': 'ready', 'host.task_load': 'task_load', + 'host.version': 'version', 'host_config.arches': 'arches', 'host_config.capacity': 'capacity', 'host_config.description': 'description', @@ -10278,6 +10280,9 @@ class RootExports(object): def echo(self, *args): return args + def getKojiVersion(self): + return koji.__version__ + def getAPIVersion(self): return koji.API_VERSION @@ -12482,6 +12487,7 @@ class RootExports(object): 'host.name': 'name', 'host.ready': 'ready', 'host.task_load': 'task_load', + 'host.version': 'version', 'host_config.arches': 'arches', 'host_config.capacity': 'capacity', 'host_config.description': 'description', @@ -13444,14 +13450,17 @@ class Host(object): task['alert'] = True return tasks - def updateHost(self, task_load, ready): + def updateHost(self, task_load, ready, resources=None): host_data = get_host(self.id) - if task_load != host_data['task_load'] or ready != host_data['ready']: - c = context.cnx.cursor() + if task_load != host_data['task_load'] or \ + ready != host_data['ready'] or \ + resources and resources.get('version') and host_data['version'] != resources['version']: id = self.id - q = """UPDATE host SET task_load=%(task_load)s,ready=%(ready)s WHERE id=%(id)s""" - c.execute(q, locals()) - context.commit_pending = True + update = UpdateProcessor('host', clauses=['id=%(id)s'], values=locals()) + update.set(task_load=task_load, ready=ready) + if resources and 'version' in resources: + update.set(version=resources['version']) + update.execute() def getLoadData(self): """Get load balancing data @@ -13529,10 +13538,10 @@ class HostExports(object): host.verify() return host.id - def updateHost(self, task_load, ready): + def updateHost(self, task_load, ready, resources=None): host = Host() host.verify() - host.updateHost(task_load, ready) + host.updateHost(task_load, ready, resources=resources) def getLoadData(self): host = Host() diff --git a/koji/__init__.py b/koji/__init__.py index 43a557c..58c0da5 100644 --- a/koji/__init__.py +++ b/koji/__init__.py @@ -62,6 +62,9 @@ from six.moves import range, zip from koji.xmlrpcplus import Fault, dumps, getparser, loads, xmlrpc_client from . import util +from . import _version +__version__ = _version.__version__ +__version_info__ = _version.__version_info__ SSL_Error = None try: diff --git a/koji/_version.py b/koji/_version.py new file mode 100644 index 0000000..e8871b9 --- /dev/null +++ b/koji/_version.py @@ -0,0 +1,2 @@ +__version_info__ = (1, 22, 0) +__version__ = '.'.join([str(x) for x in __version_info__]) diff --git a/koji/daemon.py b/koji/daemon.py index fea5970..39ccc88 100644 --- a/koji/daemon.py +++ b/koji/daemon.py @@ -633,7 +633,8 @@ class TaskManager(object): for task_id in self.pids: self.cleanupTask(task_id) self.session.host.freeTasks(to_list(self.tasks.keys())) - self.session.host.updateHost(task_load=0.0, ready=False) + self.session.host.updateHost(task_load=0.0, ready=False, + resources={'version': koji.__version__}) def updateBuildroots(self, nolocal=False): """Handle buildroot cleanup/maintenance @@ -891,7 +892,8 @@ class TaskManager(object): def getNextTask(self): self.ready = self.readyForTask() - self.session.host.updateHost(self.task_load, self.ready) + self.session.host.updateHost(self.task_load, self.ready, + resources={'version': koji.__version__}) if not self.ready: self.logger.info("Not ready for task") return False diff --git a/setup.py b/setup.py index 5e7ff6b..94f31b3 100644 --- a/setup.py +++ b/setup.py @@ -30,9 +30,14 @@ def get_install_requires(): return requires +def get_version(): + exec(open('koji/_version.py', 'rt').read()) + return(locals()['__version__']) + + setup( name="koji", - version="1.22.1", + version=get_version(), description=("Koji is a system for building and tracking RPMS. The base" " package contains shared libraries and the command-line" " interface."), diff --git a/tests/test_cli/data/list-commands.txt b/tests/test_cli/data/list-commands.txt index a718f58..592ae85 100644 --- a/tests/test_cli/data/list-commands.txt +++ b/tests/test_cli/data/list-commands.txt @@ -122,6 +122,7 @@ miscellaneous commands: dist-repo Create a yum repo with distribution options import-comps Import group/package information from a comps file moshimoshi Introduce yourself + version Report client and hub versions monitor commands: add-notification Add user's notification diff --git a/tests/test_hub/test_get_host.py b/tests/test_hub/test_get_host.py index 7bf38d0..e514940 100644 --- a/tests/test_hub/test_get_host.py +++ b/tests/test_hub/test_get_host.py @@ -33,11 +33,11 @@ class TestSetHostEnabled(unittest.TestCase): self.assertEqual(len(self.queries), 1) query = self.queries[0] columns = ['host.id', 'host.user_id', 'host.name', 'host.ready', - 'host.task_load', 'host_config.arches', + 'host.task_load', 'host.version', 'host_config.arches', 'host_config.capacity', 'host_config.description', 'host_config.comment', 'host_config.enabled'] joins = ['host ON host.id = host_config.host_id'] - aliases = ['id', 'user_id', 'name', 'ready', 'task_load', + aliases = ['id', 'user_id', 'name', 'ready', 'task_load', 'version', 'arches', 'capacity', 'description', 'comment', 'enabled'] clauses = ['(host_config.active = TRUE)', 'host.name = %(hostInfo)s'] values = {'hostInfo': 'hostname'} @@ -54,11 +54,11 @@ class TestSetHostEnabled(unittest.TestCase): self.assertEqual(len(self.queries), 1) query = self.queries[0] columns = ['host.id', 'host.user_id', 'host.name', 'host.ready', - 'host.task_load', 'host_config.arches', + 'host.task_load', 'host.version', 'host_config.arches', 'host_config.capacity', 'host_config.description', 'host_config.comment', 'host_config.enabled'] joins = ['host ON host.id = host_config.host_id'] - aliases = ['id', 'user_id', 'name', 'ready', 'task_load', + aliases = ['id', 'user_id', 'name', 'ready', 'task_load', 'version', 'arches', 'capacity', 'description', 'comment', 'enabled'] clauses = ['(host_config.create_event <= 345 AND ( host_config.revoke_event IS NULL OR 345 < host_config.revoke_event ))', 'host.id = %(hostInfo)i'] diff --git a/www/kojiweb/api.chtml b/www/kojiweb/api.chtml index 291d584..729d488 100644 --- a/www/kojiweb/api.chtml +++ b/www/kojiweb/api.chtml @@ -1,6 +1,7 @@ #include "includes/header.chtml" +#import koji -

API reference

+

API reference (API version: $api_version, hub version: $koji_version, web version: $koji.__version__)