diff --git a/homeassistant/config.py b/homeassistant/config.py index 9465025cfd2..7e8bcec08a5 100644 --- a/homeassistant/config.py +++ b/homeassistant/config.py @@ -1,7 +1,7 @@ """Module to help with parsing and generating configuration files.""" from collections import OrderedDict # pylint: disable=no-name-in-module -from distutils.version import LooseVersion # pylint: disable=import-error +from distutils.version import StrictVersion # pylint: disable=import-error import logging import os import re @@ -31,6 +31,7 @@ from homeassistant.loader import ( Integration, async_get_integration, IntegrationNotFound ) from homeassistant.util.yaml import load_yaml, SECRET_YAML +from homeassistant.util.package import is_docker_env import homeassistant.helpers.config_validation as cv from homeassistant.util.unit_system import IMPERIAL_SYSTEM, METRIC_SYSTEM from homeassistant.helpers.entity_values import EntityValues @@ -333,13 +334,15 @@ def process_ha_config_upgrade(hass: HomeAssistant) -> None: _LOGGER.info("Upgrading configuration directory from %s to %s", conf_version, __version__) - if LooseVersion(conf_version) < LooseVersion('0.50'): + version_obj = StrictVersion(conf_version) + + if version_obj < StrictVersion('0.50'): # 0.50 introduced persistent deps dir. lib_path = hass.config.path('deps') if os.path.isdir(lib_path): shutil.rmtree(lib_path) - if LooseVersion(conf_version) < LooseVersion('0.92'): + if version_obj < StrictVersion('0.92'): # 0.92 moved google/tts.py to google_translate/tts.py config_path = find_config_file(hass.config.config_dir) assert config_path is not None @@ -357,6 +360,13 @@ def process_ha_config_upgrade(hass: HomeAssistant) -> None: _LOGGER.exception("Migrating to google_translate tts failed") pass + if version_obj < StrictVersion('0.94.0b6') and is_docker_env(): + # In 0.94 we no longer install packages inside the deps folder when + # running inside a Docker container. + lib_path = hass.config.path('deps') + if os.path.isdir(lib_path): + shutil.rmtree(lib_path) + with open(version_path, 'wt') as outp: outp.write(__version__) diff --git a/tests/test_config.py b/tests/test_config.py index a42fc3b809c..8e983c673c5 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -256,7 +256,8 @@ async def test_entity_customization(hass): @mock.patch('homeassistant.config.shutil') @mock.patch('homeassistant.config.os') -def test_remove_lib_on_upgrade(mock_os, mock_shutil, hass): +@mock.patch('homeassistant.config.is_docker_env', return_value=False) +def test_remove_lib_on_upgrade(mock_docker, mock_os, mock_shutil, hass): """Test removal of library on upgrade from before 0.50.""" ha_version = '0.49.0' mock_os.path.isdir = mock.Mock(return_value=True) @@ -275,6 +276,28 @@ def test_remove_lib_on_upgrade(mock_os, mock_shutil, hass): assert mock_shutil.rmtree.call_args == mock.call(hass_path) +@mock.patch('homeassistant.config.shutil') +@mock.patch('homeassistant.config.os') +@mock.patch('homeassistant.config.is_docker_env', return_value=True) +def test_remove_lib_on_upgrade_94(mock_docker, mock_os, mock_shutil, hass): + """Test removal of library on upgrade from before 0.94 and in Docker.""" + ha_version = '0.94.0b5' + mock_os.path.isdir = mock.Mock(return_value=True) + mock_open = mock.mock_open() + with mock.patch('homeassistant.config.open', mock_open, create=True): + opened_file = mock_open.return_value + # pylint: disable=no-member + opened_file.readline.return_value = ha_version + hass.config.path = mock.Mock() + config_util.process_ha_config_upgrade(hass) + hass_path = hass.config.path.return_value + + assert mock_os.path.isdir.call_count == 1 + assert mock_os.path.isdir.call_args == mock.call(hass_path) + assert mock_shutil.rmtree.call_count == 1 + assert mock_shutil.rmtree.call_args == mock.call(hass_path) + + def test_process_config_upgrade(hass): """Test update of version on upgrade.""" ha_version = '0.92.0'