Wait for apps during bundle deploy
authorCory Johns <johnsca@gmail.com>
Tue, 22 Nov 2016 19:24:52 +0000 (14:24 -0500)
committerCory Johns <johnsca@gmail.com>
Tue, 22 Nov 2016 21:10:57 +0000 (16:10 -0500)
This ensures subsequent operations, such as expose, have the ModelEntity
to work with.

Fixes #17

juju/model.py
juju/unit.py

index 9d14f82..b731899 100644 (file)
@@ -576,15 +576,24 @@ class Model(object):
         entity_id = await q.get()
         return self.state._live_entity_map(entity_type)[entity_id]
 
-    async def _wait_for_new(self, entity_type, entity_id, predicate=None):
+    async def _wait_for_new(self, entity_type, entity_id=None, predicate=None):
         """Wait for a new object to appear in the Model and return it.
 
         Waits for an object of type ``entity_type`` with id ``entity_id``.
+        If ``entity_id`` is ``None``, it will wait for the first new entity
+        of the correct type.
 
         This coroutine blocks until the new object appears in the model.
 
         """
-        return await self._wait(entity_type, entity_id, 'add', predicate)
+        # if the entity is already in the model, just return it
+        if entity_id in self.state._live_entity_map(entity_type):
+            return self.state._live_entity_map(entity_type)[entity_id]
+        # if we know the entity_id, we can trigger on any action that puts
+        # the enitty into the model; otherwise, we have to watch for the
+        # next "add" action on that entity_type
+        action = 'add' if entity_id is None else None
+        return await self._wait(entity_type, entity_id, action, predicate)
 
     async def wait_for_action(self, action_id):
         """Given an action, wait for it to complete."""
@@ -1352,6 +1361,8 @@ class BundleHandler(object):
         # do the do
         log.info('Deploying %s', charm)
         await self.app_facade.Deploy([app])
+        # ensure the app is in the model for future operations
+        await self.model._wait_for_new('application', application)
         return application
 
     async def addUnit(self, application, to):
index d0a70bd..1f8254f 100644 (file)
@@ -161,9 +161,9 @@ class Unit(model.ModelEntity):
             raise Exception('Unknown action error: %s' % error.serialize())
         action_id = action.tag[len('action-'):]
         log.debug('Action started as %s', action_id)
-        # we can't use wait_for_new here because we don't
-        # consistently (ever?) get an "add" delta for the action
-        return await self.model._wait('action', action_id, None)
+        # we mustn't use wait_for_action because that blocks until the
+        # action is complete, rather than just being in the model
+        return await self.model._wait_for_new('action', action_id)
 
     def scp(
             self, source_path, user=None, destination_path=None, proxy=False,