)
app.placement = placement
- result = await app_facade.Deploy([app])
- errors = [r.error.message for r in result.results if r.error]
- if errors:
- raise JujuError('\n'.join(errors))
+ await app_facade.Deploy([app])
return await self._wait_for_new('application', application_name)
def destroy(self):
self.plan = await self.client_facade.GetBundleChanges(
yaml.dump(self.bundle))
- if self.plan.errors:
- raise JujuError('\n'.join(self.plan.errors))
-
async def execute_plan(self):
for step in self.plan.changes:
method = getattr(self, step.method)
"""
# resolve indirect references
charm = self.resolve(charm)
- # stringify all config values for API
+ # stringify all config values for API, and convert to YAML
options = {k: str(v) for k, v in options.items()}
+ options = yaml.dump({application: options}, default_flow_style=False)
# build param object
app = client.ApplicationDeploy(
charm_url=charm,
series=series,
application=application,
- config=options,
+ # Pass options to config-yaml rather than config, as
+ # config-yaml invokes a newer codepath that better handles
+ # empty strings in the options values.
+ config_yaml=options,
constraints=parse_constraints(constraints),
storage=storage,
endpoint_bindings=endpoint_bindings,