diff --git a/juju/client/facade_versions.py b/juju/client/facade_versions.py index f5c273c2..d595a34b 100644 --- a/juju/client/facade_versions.py +++ b/juju/client/facade_versions.py @@ -17,7 +17,7 @@ 'Backups': (3, ), 'Block': (2, ), 'Bundle': (6, ), - 'Charms': (6, ), + 'Charms': (6, 7), 'Client': (6, 7, 8), 'Cloud': (7, ), 'Controller': (11, 12), diff --git a/juju/model.py b/juju/model.py index 2be474d5..b3ea07bb 100644 --- a/juju/model.py +++ b/juju/model.py @@ -1,5 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +from __future__ import annotations import base64 import collections @@ -452,7 +453,7 @@ class LocalDeployType: """ async def resolve(self, charm_path, architecture, - app_name=None, channel=None, series=None, + app_name=None, channel=None, series: str|None = None, revision=None, entity_url=None, force=False, model_conf=None): """resolve attempts to resolve a local charm or bundle using the url @@ -1876,7 +1877,7 @@ async def _add_charm(self, charm_url, origin): client_facade = client.ClientFacade.from_connection(self.connection()) return await client_facade.AddCharm(channel=str(origin.risk), url=charm_url, force=False) - async def _resolve_charm(self, url, origin, force=False, series=None, model_config=None): + async def _resolve_charm(self, url, origin, force=False, series: str|None = None, model_config=None): """Calls Charms.ResolveCharms to resolve all the fields of the charm_origin and also the url and the supported_series @@ -1917,15 +1918,24 @@ async def _resolve_charm(self, url, origin, force=False, series=None, model_conf if result.error: raise JujuError(f'resolving {url} : {result.error.message}') - # TODO (cderici) : supported_bases - supported_series = result.get('supported_series', result.unknown_fields['supported-series']) + charmhub_bases = result.supported_bases resolved_origin = result.charm_origin charm_url = URL.parse(result.url) + if "supported-series" in result.unknown_fields: + # Legacy code path for Charms v6, that is Juju < 3.3.0 + supported_series: list[str] = result.unknown_fields['supported-series'] + # run the series selector to get a series for the base + selected_series = utils.series_selector(series, charm_url, model_config, supported_series, force) + result.charm_origin.base = utils.get_base_from_origin_or_channel(resolved_origin, selected_series) + charm_url.series = selected_series - # run the series selector to get a series for the base - selected_series = utils.series_selector(series, charm_url, model_config, supported_series, force) - result.charm_origin.base = utils.get_base_from_origin_or_channel(resolved_origin, selected_series) - charm_url.series = selected_series + if series: + # Ugh this ugly, + # series is valid against Juju 3.0~3.2.x + # base is valid against Juju 3.3~4.x + # we should convert back and forth really... + warnings.warn("series= argument is deprecated, use base= instead", DeprecationWarning, stacklevel=3) + # FIXME actually use the argument return charm_url, resolved_origin diff --git a/juju/utils.py b/juju/utils.py index c4f4780a..614a9da8 100644 --- a/juju/utils.py +++ b/juju/utils.py @@ -1,5 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +from __future__ import annotations import os import textwrap @@ -488,7 +489,7 @@ def user_requested(series_arg, supported_series, force): return series -def series_selector(series_arg='', charm_url=None, model_config=None, supported_series=[], force=False): +def series_selector(series_arg: str|None = "", charm_url=None, model_config=None, supported_series=[], force=False): """ series_selector corresponds to the CharmSeries() in https://github.com/juju/juju/blob/develop/core/charm/series_selector.go