X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FN2VC.git;a=blobdiff_plain;f=n2vc%2Flibjuju.py;h=28474a082bd4767f5a897f8d44bc8dbe9f4b6508;hp=a00fa58aaa0bc1b2535bc5aa16707fb59e594f67;hb=59f520da90fb12b9d9871889dfbc5d57aa14c591;hpb=7077e2601a209a87f7fe397b35586e7701ca759a;ds=sidebyside diff --git a/n2vc/libjuju.py b/n2vc/libjuju.py index a00fa58..28474a0 100644 --- a/n2vc/libjuju.py +++ b/n2vc/libjuju.py @@ -22,6 +22,7 @@ from juju.errors import JujuAPIError from juju.model import Model from juju.machine import Machine from juju.application import Application +from juju.unit import Unit from juju.client._definitions import ( FullStatus, QueryApplicationOffersResults, @@ -629,11 +630,21 @@ class Libjuju: if application is None: raise JujuApplicationNotFound("Cannot execute action") - # Get unit + # Get leader unit + # Racing condition: + # Ocassionally, self._get_leader_unit() will return None + # because the leader elected hook has not been triggered yet. + # Therefore, we are doing some retries. If it happens again, + # re-open bug 1236 + attempts = 3 + time_between_retries = 10 unit = None - for u in application.units: - if await u.is_leader_from_status(): - unit = u + for _ in range(attempts): + unit = await self._get_leader_unit(application) + if unit is None: + await asyncio.sleep(time_between_retries) + else: + break if unit is None: raise JujuLeaderUnitNotFound( "Cannot execute action: leader unit not found" @@ -1166,3 +1177,11 @@ class Libjuju: await controller.remove_cloud(name) finally: await self.disconnect_controller(controller) + + async def _get_leader_unit(self, application: Application) -> Unit: + unit = None + for u in application.units: + if await u.is_leader_from_status(): + unit = u + break + return unit