Store version information in component registry

This stores the zuul version of each component in the component
registry and updates the API endpoint.

Change-Id:  I1855b2a6db2bd330343cad69d9d6cf21ea35a1f5
This commit is contained in:
Felix Edel 2021-10-19 16:25:41 +02:00
parent 1df09a82ef
commit 220534c0f7
8 changed files with 31 additions and 17 deletions

View File

@ -239,7 +239,7 @@ class TestWeb(BaseTestWeb):
self.assertEqual(len(data["web"]), 1)
# Each component should contain hostname and state information
for key in ["hostname", "state"]:
for key in ["hostname", "state", "version"]:
self.assertIn(key, data["executor"][0])
self.assertIn(key, data["scheduler"][0])
self.assertIn(key, data["web"][0])

View File

@ -66,6 +66,7 @@ from zuul.model import (
)
import zuul.model
from zuul.nodepool import Nodepool
from zuul.version import get_version_string
from zuul.zk.event_queues import PipelineResultEventQueue
from zuul.zk.components import ExecutorComponent
from zuul.zk.exceptions import JobRequestNotFound
@ -3059,7 +3060,8 @@ class ExecutorServer(BaseMergeServer):
# perhaps hostname+pid.
self.hostname = get_default(self.config, 'executor', 'hostname',
socket.getfqdn())
self.component_info = ExecutorComponent(self.zk_client, self.hostname)
self.component_info = ExecutorComponent(
self.zk_client, self.hostname, version=get_version_string())
self.component_info.register()
self.log_streaming_port = log_streaming_port
self.governor_lock = threading.Lock()

View File

@ -24,6 +24,7 @@ from zuul.exceptions import StreamingError
from zuul.lib import streamer_utils
from zuul.lib.commandsocket import CommandSocket
from zuul.lib.config import get_default
from zuul.version import get_version_string
from zuul.zk import ZooKeeperClient
from zuul.zk.components import ComponentRegistry, FingerGatewayComponent
from zuul.zk.executor import ExecutorApi
@ -177,7 +178,7 @@ class FingerGateway(object):
self.zk_client = ZooKeeperClient.fromConfig(config)
self.zk_client.connect()
self.component_info = FingerGatewayComponent(
self.zk_client, self.hostname
self.zk_client, self.hostname, version=get_version_string()
)
if self.zone is not None:
self.component_info.zone = self.zone

View File

@ -32,6 +32,7 @@ from zuul.merger.merger import nullcontext
from zuul.model import (
FilesChangesCompletedEvent, MergeCompletedEvent, MergeRequest
)
from zuul.version import get_version_string
from zuul.zk import ZooKeeperClient
from zuul.zk.components import MergerComponent
from zuul.zk.event_queues import PipelineResultEventQueue
@ -465,7 +466,8 @@ class MergeServer(BaseMergeServer):
):
super().__init__(config, 'merger', connections)
self.hostname = socket.getfqdn()
self.component_info = MergerComponent(self.zk_client, self.hostname)
self.component_info = MergerComponent(
self.zk_client, self.hostname, version=get_version_string())
self.component_info.register()
self.command_map = dict(

View File

@ -31,7 +31,6 @@ from apscheduler.triggers.interval import IntervalTrigger
from kazoo.exceptions import NotEmptyError
from zuul import configloader, exceptions
from zuul import version as zuul_version
from zuul import rpclistener
from zuul.lib import commandsocket
from zuul.lib.ansible import AnsibleManager
@ -70,6 +69,7 @@ from zuul.model import (
SystemAttributes,
STATE_FAILED,
)
from zuul.version import get_version_string
from zuul.zk import ZooKeeperClient
from zuul.zk.cleanup import (
SemaphoreCleanupLock,
@ -177,7 +177,11 @@ class Scheduler(threading.Thread):
self.zk_client = ZooKeeperClient.fromConfig(self.config)
self.zk_client.connect()
self.system = ZuulSystem(self.zk_client)
self.component_info = SchedulerComponent(self.zk_client, self.hostname)
self.zuul_version = get_version_string()
self.component_info = SchedulerComponent(
self.zk_client, self.hostname, version=self.zuul_version)
self.component_info.register()
self.component_registry = ComponentRegistry(self.zk_client)
self.system_config_cache = SystemConfigCache(self.zk_client,
@ -229,11 +233,6 @@ class Scheduler(threading.Thread):
'/var/lib/zuul/scheduler.socket')
self.command_socket = commandsocket.CommandSocket(command_socket)
if zuul_version.is_release is False:
self.zuul_version = "%s %s" % (zuul_version.release_string,
zuul_version.git_version)
else:
self.zuul_version = zuul_version.release_string
self.last_reconfigured = None
self.globals = SystemAttributes.fromConfig(self.config)

View File

@ -33,3 +33,9 @@ try:
git_version = _metadata['git_version']
except Exception:
pass
def get_version_string():
if is_release:
return release_string
return "{} {}".format(release_string, git_version)

View File

@ -36,6 +36,7 @@ from zuul.lib import streamer_utils
from zuul.lib.re2util import filter_allowed_disallowed
import zuul.model
import zuul.rpcclient
from zuul.version import get_version_string
from zuul.zk import ZooKeeperClient
from zuul.zk.components import ComponentRegistry, WebComponent
from zuul.zk.executor import ExecutorApi
@ -760,6 +761,7 @@ class ZuulWebAPI(object):
comp_json = {
"hostname": comp.hostname,
"state": comp.state,
"version": comp.version,
}
ret.setdefault(kind, []).append(comp_json)
resp = cherrypy.response
@ -1319,7 +1321,8 @@ class ZuulWeb(object):
self.executor_api = ExecutorApi(self.zk_client, use_cache=False)
self.component_info = WebComponent(self.zk_client, self.hostname)
self.component_info = WebComponent(
self.zk_client, self.hostname, version=get_version_string())
self.component_info.register()
self.component_registry = ComponentRegistry(self.zk_client)

View File

@ -51,13 +51,14 @@ class BaseComponent(ZooKeeperBase):
log = logging.getLogger("zuul.Component")
kind = "base"
def __init__(self, client, hostname):
def __init__(self, client, hostname, version=None):
# Ensure that the content is available before setting any other
# attribute, because our __setattr__ implementation is relying on it.
self.__dict__["content"] = {
"hostname": hostname,
"state": self.STOPPED,
"kind": self.kind,
"version": version,
}
super().__init__(client)
@ -136,8 +137,8 @@ class SchedulerComponent(BaseComponent):
class ExecutorComponent(BaseComponent):
kind = "executor"
def __init__(self, client, hostname):
super().__init__(client, hostname)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.initial_state = {
"accepting_work": False,
"zone": None,
@ -154,8 +155,8 @@ class MergerComponent(BaseComponent):
class FingerGatewayComponent(BaseComponent):
kind = "fingergw"
def __init__(self, client, hostname):
super().__init__(client, hostname)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.initial_state = {
"zone": None,
"public_port": None,