From: Tim Van Steenburgh Date: Mon, 28 Nov 2016 23:47:26 +0000 (-0500) Subject: Merge pull request #21 from petevg/bug/add-machines-params-passing X-Git-Tag: 0.1.0~30 X-Git-Url: https://osm.etsi.org/gitweb/?a=commitdiff_plain;h=132f5ea91d63a915b2d892fc5a54429a8dc92bba;hp=-c;p=osm%2FN2VC.git Merge pull request #21 from petevg/bug/add-machines-params-passing Fixed addMachines. --- 132f5ea91d63a915b2d892fc5a54429a8dc92bba diff --combined juju/model.py index 56924cf,8d6c666..b218fba --- a/juju/model.py +++ b/juju/model.py @@@ -12,6 -12,7 +12,7 @@@ from theblues import charmstor from .client import client from .client import watcher from .client import connection + from .constraints import parse as parse_constraints from .delta import get_entity_delta from .delta import get_entity_class from .exceptions import DeadEntityException @@@ -576,24 -577,15 +577,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.""" @@@ -1206,36 -1198,6 +1207,36 @@@ def charmstore(self): return self._charmstore + async def get_metrics(self, *tags): + """Retrieve metrics. + + :param str \*tags: Tags of entities from which to retrieve metrics. + No tags retrieves the metrics of all units in the model. + """ + log.debug("Retrieving metrics for %s", + ', '.join(tags) if tags else "all units") + + metrics_facade = client.MetricsDebugFacade() + metrics_facade.connect(self.connection) + + entities = [client.Entity(tag) for tag in tags] + metrics_result = await metrics_facade.GetMetrics(entities) + + metrics = collections.defaultdict(list) + + for entity_metrics in metrics_result.results: + error = entity_metrics.error + if error: + if "is not a valid tag" in error: + raise ValueError(error.message) + else: + raise Exception(error.message) + + for metric in entity_metrics.metrics: + metrics[metric.unit].append(metric.to_json()) + + return metrics + class BundleHandler(object): """ @@@ -1294,35 -1256,41 +1295,41 @@@ await self.client_facade.AddCharm(None, entity_id) return entity_id - async def addMachines(self, series, constraints, container_type, - parent_id): - """ - :param series string: - Series holds the optional machine OS series. - - :param constraints string: - Constraints holds the optional machine constraints. - - :param Container_type string: - ContainerType optionally holds the type of the container (for - instance ""lxc" or kvm"). It is not specified for top level - machines. - - :param parent_id string: - ParentId optionally holds a placeholder pointing to another machine - change or to a unit change. This value is only specified in the - case this machine is a container, in which case also ContainerType - is set. - """ - params = client.AddMachineParams( - series=series, - constraints=constraints, - container_type=container_type, - parent_id=self.resolve(parent_id), - ) - results = await self.client_facade.AddMachines(params) - log.debug('Added new machine %s', results[0].machine) - return results[0].machine + async def addMachines(self, params=None): + """ + :param params dict: + Dictionary specifying the machine to add. All keys are optional. + Keys include: + + series: string specifying the machine OS series. + constraints: string holding machine constraints, if any. We'll + parse this into the json friendly dict that the juju api + expects. + container_type: string holding the type of the container (for + instance ""lxc" or kvm"). It is not specified for top level + machines. + parent_id: string holding a placeholder pointing to another + machine change or to a unit change. This value is only + specified in the case this machine is a container, in + which case also ContainerType is set. + """ + params = params or {} + + if 'parent_id' in params: + params['parent_id'] = self.resolve(params['parent_id']) + + params['constraints'] = parse_constraints( + params.get('constraints')) + params['jobs'] = params.get('jobs', ['JobHostUnits']) + + params = client.AddMachineParams(**params) + results = await self.client_facade.AddMachines([params]) + error = results.machines[0].error + if error: + raise ValueError("Error adding machine: %s", error.message) + machine = results.machines[0].machine + log.debug('Added new machine %s', machine) + return machine async def addRelation(self, endpoint1, endpoint2): """ @@@ -1391,8 -1359,6 +1398,8 @@@ # 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):