from concurrent.futures import CancelledError
from functools import partial
+import yaml
from theblues import charmstore
from .client import client
handler = BundleHandler(self)
await handler.fetch_plan(entity_id)
await handler.execute_plan()
+ extant_apps = {app for app in self.applications}
+ pending_apps = set(handler.applications) - extant_apps
+ if pending_apps:
+ # new apps will usually be in the model by now, but if some
+ # haven't made it yet we'll need to wait on them to be added
+ await asyncio.gather(*[
+ asyncio.ensure_future(
+ self.model._wait_for_new('application', app_name))
+ for app_name in pending_apps
+ ])
+ return [app for name, app in self.applications.items()
+ if name in handler.applications]
else:
log.debug(
'Deploying %s', entity_id)
"""
pass
+ async def destroy_unit(self, *unit_names):
+ """Destroy units by name.
+
+ """
+ app_facade = client.ApplicationFacade()
+ app_facade.connect(self.connection)
+
+ log.debug(
+ 'Destroying unit%s %s',
+ 's' if len(unit_names) == 1 else '',
+ ' '.join(unit_names))
+
+ return await app_facade.Destroy(self.name)
+ destroy_units = destroy_unit
+
def get_backup(self, archive_id):
"""Download a backup archive file.
self.ann_facade.connect(model.connection)
async def fetch_plan(self, entity_id):
- yaml = await self.charmstore.files(entity_id,
- filename='bundle.yaml',
- read_file=True)
- self.plan = await self.client_facade.GetBundleChanges(yaml)
+ bundle_yaml = await self.charmstore.files(entity_id,
+ filename='bundle.yaml',
+ read_file=True)
+ self.bundle = yaml.safe_load(bundle_yaml)
+ self.plan = await self.client_facade.GetBundleChanges(bundle_yaml)
async def execute_plan(self):
for step in self.plan.changes:
result = await method(*step.args)
self.references[step.id_] = result
+ @property
+ def applications(self):
+ return list(self.bundle['services'].keys())
+
def resolve(self, reference):
if reference and reference.startswith('$'):
reference = self.references[reference[1:]]
parts[0] = self.resolve(parts[0])
endpoints[i] = ':'.join(parts)
+ log.info('Relating %s <-> %s', *endpoints)
return await self.model.add_relation(*endpoints)
async def deploy(self, charm, series, application, options, constraints,
resources=resources,
)
# do the do
- log.debug('Deploying %s', charm)
+ log.info('Deploying %s', charm)
await self.app_facade.Deploy([app])
return application
log.debug('Reusing unit %s for %s', unit_name, application)
return self.model.units[unit_name]
+ log.debug('Adding new unit for %s%s', application,
+ ' to %s' % placement if placement else '')
return await self.model.applications[application].add_unit(
count=1,
to=placement,
be exposed.
"""
application = self.resolve(application)
+ log.info('Exposing %s', application)
return await self.model.applications[application].expose()
async def setAnnotations(self, id_, entity_type, annotations):
try:
entity = self.model.state.get_entity(entity_type, entity_id)
except KeyError:
- entity = await self._wait_for_new(entity_type, entity_id)
+ entity = await self.model._wait_for_new(entity_type, entity_id)
return await entity.set_annotations(annotations)