mirror of
https://pagure.io/fm-orchestrator.git
synced 2026-04-02 18:28:52 +08:00
Handle lost message from Koji informing MBS about Component being tagged into Koji tag.
Adds new meethod checking the "tagged" and "tagged_in_final" attributes of "complete" ComponentBuilds in the current batch of module builds in "building" state against the Koji. In case the Koji shows the build as tagged/tagged_in_final, the fake "tagged" message is added to work queue.
This commit is contained in:
@@ -52,6 +52,7 @@ class MBSProducer(PollingProducer):
|
||||
self.trigger_new_repo_when_stalled(conf, session)
|
||||
self.delete_old_koji_targets(conf, session)
|
||||
self.cleanup_stale_failed_builds(conf, session)
|
||||
self.sync_koji_build_tags(conf, session)
|
||||
except Exception:
|
||||
msg = 'Error in poller execution:'
|
||||
log.exception(msg)
|
||||
@@ -371,3 +372,54 @@ class MBSProducer(PollingProducer):
|
||||
)
|
||||
build.transition(config, state=models.BUILD_STATES["failed"], state_reason=state_reason)
|
||||
session.commit()
|
||||
|
||||
def sync_koji_build_tags(self, config, session):
|
||||
"""
|
||||
Method checking the "tagged" and "tagged_in_final" attributes of
|
||||
"complete" ComponentBuilds in the current batch of module builds
|
||||
in "building" state against the Koji.
|
||||
|
||||
In case the Koji shows the build as tagged/tagged_in_final,
|
||||
fake "tagged" message is added to work queue.
|
||||
"""
|
||||
if conf.system != 'koji':
|
||||
return
|
||||
|
||||
koji_session = KojiModuleBuilder.get_session(conf, login=False)
|
||||
|
||||
module_builds = models.ModuleBuild.by_state(session, "build")
|
||||
for module_build in module_builds:
|
||||
complete_components = module_build.current_batch(
|
||||
koji.BUILD_STATES['COMPLETE'])
|
||||
for c in complete_components:
|
||||
# In case the component is tagged in the build tag and
|
||||
# also tagged in the final tag (or it is build_time_only
|
||||
# and therefore should not be tagged in final tag), skip it.
|
||||
if c.tagged and (c.tagged_in_final or c.build_time_only):
|
||||
continue
|
||||
|
||||
log.info("%r: Component %r is complete, but not tagged in the "
|
||||
"final and/or build tags.", module_build, c)
|
||||
|
||||
# Check in which tags the component is tagged.
|
||||
tag_dicts = koji_session.listTags(c.nvr)
|
||||
tags = [tag_dict["name"] for tag_dict in tag_dicts]
|
||||
|
||||
# If it is tagged in final tag, but MBS does not think so,
|
||||
# schedule fake message.
|
||||
if not c.tagged_in_final and module_build.koji_tag in tags:
|
||||
msg = module_build_service.messaging.KojiTagChange(
|
||||
'sync_koji_build_tags_fake_message',
|
||||
module_build.koji_tag, c.package, c.nvr)
|
||||
log.info(" Scheduling faked event %r" % msg)
|
||||
module_build_service.scheduler.consumer.work_queue_put(msg)
|
||||
|
||||
# If it is tagged in the build tag, but MBS does not think so,
|
||||
# schedule fake message.
|
||||
build_tag = module_build.koji_tag + "-build"
|
||||
if not c.tagged and build_tag in tags:
|
||||
msg = module_build_service.messaging.KojiTagChange(
|
||||
'sync_koji_build_tags_fake_message',
|
||||
build_tag, c.package, c.nvr)
|
||||
log.info(" Scheduling faked event %r" % msg)
|
||||
module_build_service.scheduler.consumer.work_queue_put(msg)
|
||||
|
||||
@@ -25,6 +25,7 @@ from tests import reuse_component_init_data, db, clean_database
|
||||
import mock
|
||||
import koji
|
||||
from module_build_service.scheduler.producer import MBSProducer
|
||||
from module_build_service.messaging import KojiTagChange
|
||||
import six.moves.queue as queue
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
@@ -567,3 +568,65 @@ class TestPoller:
|
||||
module = models.ModuleBuild.query.filter_by(state=4).all()
|
||||
assert len(module) == 1
|
||||
assert module[0].id == 2
|
||||
|
||||
@pytest.mark.parametrize('tagged, tagged_in_final', ([True, False], [True, False]))
|
||||
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
|
||||
def test_sync_koji_build_tags(
|
||||
self, ClientSession, create_builder, global_consumer, dbg,
|
||||
tagged, tagged_in_final):
|
||||
module_build_2 = models.ModuleBuild.query.filter_by(id=2).one()
|
||||
|
||||
# Only module build 1's build target should be deleted.
|
||||
module_build_2.koji_tag = 'module-tag1'
|
||||
module_build_2.state = models.BUILD_STATES['build']
|
||||
c = module_build_2.current_batch()[0]
|
||||
c.state = koji.BUILD_STATES["COMPLETE"]
|
||||
c.tagged_in_final = False
|
||||
c.tagged = False
|
||||
db.session.commit()
|
||||
db.session.refresh(module_build_2)
|
||||
|
||||
koji_session = ClientSession.return_value
|
||||
# No created module build has any of these tags.
|
||||
ret = []
|
||||
|
||||
if tagged:
|
||||
ret.append(
|
||||
{
|
||||
'id': 1,
|
||||
'name': module_build_2.koji_tag + "-build"
|
||||
},
|
||||
)
|
||||
if tagged_in_final:
|
||||
ret.append(
|
||||
{
|
||||
'id': 2,
|
||||
'name': module_build_2.koji_tag
|
||||
},
|
||||
)
|
||||
koji_session.listTags.return_value = ret
|
||||
|
||||
consumer = mock.MagicMock()
|
||||
consumer.incoming = queue.Queue()
|
||||
global_consumer.return_value = consumer
|
||||
hub = mock.MagicMock()
|
||||
poller = MBSProducer(hub)
|
||||
|
||||
assert consumer.incoming.qsize() == 0
|
||||
poller.sync_koji_build_tags(conf, db.session)
|
||||
assert consumer.incoming.qsize() == 2 - len(ret)
|
||||
|
||||
expected_msg_tags = []
|
||||
if tagged:
|
||||
expected_msg_tags.append(module_build_2.koji_tag + "-build")
|
||||
if tagged_in_final:
|
||||
expected_msg_tags.append(module_build_2.koji_tag)
|
||||
|
||||
assert len(expected_msg_tags) == consumer.incoming.qsize()
|
||||
|
||||
for i in range(consumer.incoming.qsize()):
|
||||
msg = consumer.incoming.get()
|
||||
assert isinstance(msg, KojiTagChange)
|
||||
assert msg.artifact == c.package
|
||||
assert msg.nvr == c.nvr
|
||||
assert msg.tag in expected_msg_tags
|
||||
|
||||
Reference in New Issue
Block a user