X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=juju%2Fapplication.py;h=8719a629d2153b63374a3959b70f29c89d825793;hb=c50c361a8b9a3bbf1a33f5659e492b481f065cd2;hp=9863d882b067c9eeb27f0d7bc730fe09d695f5d0;hpb=1624359bfce926d60327fd15c4a087402f63c18e;p=osm%2FN2VC.git diff --git a/juju/application.py b/juju/application.py index 9863d88..8719a62 100644 --- a/juju/application.py +++ b/juju/application.py @@ -3,6 +3,7 @@ import logging from . import model from .client import client +from .errors import JujuError from .placement import parse as parse_placement log = logging.getLogger(__name__) @@ -79,8 +80,7 @@ class Application(model.ModelEntity): If None, a new machine is provisioned. """ - app_facade = client.ApplicationFacade() - app_facade.connect(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) log.debug( 'Adding %s unit%s to %s', @@ -134,8 +134,7 @@ class Application(model.ModelEntity): if ':' not in local_relation: local_relation = '{}:{}'.format(self.name, local_relation) - app_facade = client.ApplicationFacade() - app_facade.connect(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) log.debug( 'Destroying relation %s <-> %s', local_relation, remote_relation) @@ -155,8 +154,7 @@ class Application(model.ModelEntity): """Remove this application from the model. """ - app_facade = client.ApplicationFacade() - app_facade.connect(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) log.debug( 'Destroying %s', self.name) @@ -168,8 +166,7 @@ class Application(model.ModelEntity): """Make this application publicly available over the network. """ - app_facade = client.ApplicationFacade() - app_facade.connect(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) log.debug( 'Exposing %s', self.name) @@ -180,8 +177,7 @@ class Application(model.ModelEntity): """Return the configuration settings dict for this application. """ - app_facade = client.ApplicationFacade() - app_facade.connect(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) log.debug( 'Getting config for %s', self.name) @@ -192,8 +188,7 @@ class Application(model.ModelEntity): """Return the machine constraints dict for this application. """ - app_facade = client.ApplicationFacade() - app_facade.connect(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) log.debug( 'Getting constraints for %s', self.name) @@ -225,8 +220,7 @@ class Application(model.ModelEntity): :param int timeout: Time to wait before command is considered failed """ - action = client.ActionFacade() - action.connect(self.connection) + action = client.ActionFacade.from_connection(self.connection) log.debug( 'Running `%s` on all units of %s', command, self.name) @@ -249,11 +243,11 @@ class Application(model.ModelEntity): """ log.debug('Updating annotations on application %s', self.name) - self.ann_facade = client.AnnotationsFacade() - self.ann_facade.connect(self.connection) + self.ann_facade = client.AnnotationsFacade.from_connection( + self.connection) ann = client.EntityAnnotations( - entity=self.name, + entity=self.tag, annotations=annotations, ) return await self.ann_facade.Set([ann]) @@ -265,8 +259,7 @@ class Application(model.ModelEntity): :param bool to_default: Set application options to default values """ - app_facade = client.ApplicationFacade() - app_facade.connect(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) log.debug( 'Setting config for %s: %s', self.name, config) @@ -279,8 +272,7 @@ class Application(model.ModelEntity): :param dict constraints: Dict of machine constraints """ - app_facade = client.ApplicationFacade() - app_facade.connect(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) log.debug( 'Setting constraints for %s: %s', self.name, constraints) @@ -308,8 +300,7 @@ class Application(model.ModelEntity): """Remove public availability over the network for this application. """ - app_facade = client.ApplicationFacade() - app_facade.connect(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) log.debug( 'Unexposing %s', self.name) @@ -324,9 +315,9 @@ class Application(model.ModelEntity): """ raise NotImplementedError() - def upgrade_charm( + async def upgrade_charm( self, channel=None, force_series=False, force_units=False, - path=None, resources=None, revision=-1, switch=None): + path=None, resources=None, revision=None, switch=None): """Upgrade the charm for this application. :param str channel: Channel to use when getting the charm from the @@ -341,7 +332,55 @@ class Application(model.ModelEntity): :param str switch: Crossgrade charm url """ - raise NotImplementedError() + # TODO: Support local upgrades + if path is not None: + raise NotImplementedError("path option is not implemented") + if resources is not None: + raise NotImplementedError("resources option is not implemented") + + if switch is not None and revision is not None: + raise ValueError("switch and revision are mutually exclusive") + + client_facade = client.ClientFacade.from_connection(self.connection) + app_facade = client.ApplicationFacade.from_connection(self.connection) + + if switch is not None: + charm_url = switch + if not charm_url.startswith('cs:'): + charm_url = 'cs:' + charm_url + else: + charm_url = self.data['charm-url'] + charm_url = charm_url.rpartition('-')[0] + if revision is not None: + charm_url = "%s-%d" % (charm_url, revision) + else: + charmstore = self.model.charmstore + entity = await charmstore.entity(charm_url, channel=channel) + charm_url = entity['Id'] + + if charm_url == self.data['charm-url']: + raise JujuError('already running charm "%s"' % charm_url) + + await client_facade.AddCharm( + url=charm_url, + channel=channel + ) + + await app_facade.SetCharm( + application=self.entity_id, + channel=channel, + charm_url=charm_url, + config_settings=None, + config_settings_yaml=None, + force_series=force_series, + force_units=force_units, + resource_ids=None, + storage_constraints=None + ) + + await self.model.block_until( + lambda: self.data['charm-url'] == charm_url + ) async def get_metrics(self): """Get metrics for this application's units.