diff --git a/certbot/certbot/_internal/snap_config.py b/certbot/certbot/_internal/snap_config.py index e07ee6c08..0b662d459 100644 --- a/certbot/certbot/_internal/snap_config.py +++ b/certbot/certbot/_internal/snap_config.py @@ -33,6 +33,7 @@ _ARCH_TRIPLET_MAP = { 'amd64': 'x86_64-linux-gnu', 's390x': 's390x-linux-gnu', } +CURRENT_PYTHON_VERSION_STRING = 'python3.12' LOGGER = logging.getLogger(__name__) @@ -71,10 +72,35 @@ def prepare_env(cli_args: List[str]) -> List[str]: raise e data = response.json() - connections = ['/snap/{0}/current/lib/python3.12/site-packages/'.format(item['slot']['snap']) - for item in data.get('result', {}).get('established', []) - if item.get('plug', {}).get('plug') == 'plugin' - and item.get('plug-attrs', {}).get('content') == 'certbot-1'] + connections = [] + outdated_plugins = [] + for plugin in data.get('result', {}).get('established', []): + plug: str = plugin.get('plug', {}).get('plug') + plug_content: str = plugin.get('plug-attrs', {}).get('content') + if plug == 'plugin' and plug_content == 'certbot-1': + plugin_name: str = plugin['slot']['snap'] + # First, check that the plugin is using our expected python version, + # i.e. its "read" slot is something like + # "$SNAP/lib/python3.12/site-packages". If not, skip it and print an + # error. + slot_read: str = plugin.get('slot-attrs', {}).get('read', []) + if len(slot_read) != 0 and CURRENT_PYTHON_VERSION_STRING not in slot_read[0]: + outdated_plugins.append(plugin_name) + continue + + connections.append('/snap/{0}/current/lib/{1}/site-packages/'.format( + plugin_name, + CURRENT_PYTHON_VERSION_STRING + )) + + if outdated_plugins: + LOGGER.warning('The following plugins are using an outdated python version and must be ' + 'updated to be compatible with Certbot 3.0. Please see ' + 'https://community.letsencrypt.org/t/' + 'certbot-3-0-could-have-potential-third-party-snap-breakages/226940 ' + 'for more information:') + plugin_list = '\n'.join(' * {}'.format(plugin) for plugin in outdated_plugins) + LOGGER.warning(plugin_list) os.environ['CERTBOT_PLUGIN_PATH'] = ':'.join(connections)