Skip to content

Commit

Permalink
Fix for unit.run_actions to support both old and new clients
Browse files Browse the repository at this point in the history
Fixes #705
  • Loading branch information
cderici committed Aug 10, 2022
1 parent 1dd9cbf commit fb837cc
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
8 changes: 7 additions & 1 deletion juju/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@


class Action(model.ModelEntity):

def __init__(self, entity_id, model, history_index=-1, connected=True):
super().__init__(entity_id, model, history_index, connected)
self.results = {}

@property
def status(self):
return self.data['status']

async def wait(self):
return await self.model.get_action_output(self.id)
self.results = await self.model.get_action_output(self.id)
return self
23 changes: 15 additions & 8 deletions juju/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2262,7 +2262,19 @@ async def set_constraints(self, constraints):
constraints=constraints)

async def get_action_output(self, action_uuid, wait=None):
"""Get the results of an action by ID.
""" Get the results of an action by ID.
:param str action_uuid: Id of the action
:param int wait: Time in seconds to wait for action to complete.
:return dict: Output from action
:raises: :class:`JujuError` if invalid action_uuid
"""
action = await self._get_completed_action(action_uuid, wait=wait)
# ActionResult.output is None if the action produced no output
return {} if action.output is None else action.output

async def _get_completed_action(self, action_uuid, wait=None):
"""Get the completed internal _definitions.Action object.
:param str action_uuid: Id of the action
:param int wait: Time in seconds to wait for action to complete.
Expand All @@ -2288,13 +2300,8 @@ async def _wait_for_action_status():
await jasyncio.wait_for(
_wait_for_action_status(),
timeout=wait)
action_output = await action_facade.Actions(entities=entity)
# ActionResult.output is None if the action produced no output
if action_output.results[0].output is None:
output = {}
else:
output = action_output.results[0].output
return output
action_results = await action_facade.Actions(entities=entity)
return action_results.results[0]

async def get_action_status(self, uuid_or_prefix=None, name=None):
"""Get the status of all actions, filtered by ID, ID prefix, or name.
Expand Down
15 changes: 10 additions & 5 deletions juju/unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,22 +227,27 @@ async def run_action(self, action_name, **params):
"""
action_facade = client.ActionFacade.from_connection(self.connection)

log.debug('Starting action `%s` on %s', action_name, self.name)

res = await action_facade.EnqueueOperation(actions=[client.Action(
old_client = self.connection.is_using_old_client

op = action_facade.Enqueue if old_client else action_facade.EnqueueOperation
res = await op(actions=[client.Action(
name=action_name,
parameters=params,
receiver=self.tag,
)])
action = res.actions[0].result
error = res.actions[0].error

_action = res.results[0] if old_client else res.actions[0]
action = _action.action
error = _action.error

if error and error.code == 'not found':
raise ValueError('Action `%s` not found on %s' % (action_name,
self.name))
elif error:
raise Exception('Unknown action error: %s' % error.serialize())
action_id = action[len('action-'):]
action_id = action.tag[len('action-'):]
log.debug('Action started as %s', action_id)
# we mustn't use wait_for_action because that blocks until the
# action is complete, rather than just being in the model
Expand Down

0 comments on commit fb837cc

Please sign in to comment.