From d4e41dbf80f4f42958d93012f640d478dbd54f6a Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 24 Sep 2019 15:25:28 +0200 Subject: [PATCH 01/21] Bump version 190 --- hassio/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hassio/const.py b/hassio/const.py index 681eff5dd..223534629 100644 --- a/hassio/const.py +++ b/hassio/const.py @@ -2,7 +2,7 @@ from pathlib import Path from ipaddress import ip_network -HASSIO_VERSION = "189" +HASSIO_VERSION = "190" URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons" From 5e4e9740c753a599bff767e67a98797857925d72 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2019 09:41:16 +0200 Subject: [PATCH 02/21] Bump pylint from 2.3.1 to 2.4.0 (#1307) * Bump pylint from 2.3.1 to 2.4.0 Bumps [pylint](https://github.com/PyCQA/pylint) from 2.3.1 to 2.4.0. - [Release notes](https://github.com/PyCQA/pylint/releases) - [Changelog](https://github.com/PyCQA/pylint/blob/master/ChangeLog) - [Commits](https://github.com/PyCQA/pylint/compare/pylint-2.3.1...pylint-2.4.0) Signed-off-by: dependabot-preview[bot] * Update __main__.py * Update bootstrap.py * Update homeassistant.py * Update __init__.py --- hassio/__main__.py | 1 + hassio/addons/__init__.py | 2 +- hassio/bootstrap.py | 1 + hassio/homeassistant.py | 4 ++-- requirements_tests.txt | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hassio/__main__.py b/hassio/__main__.py index 426845fa4..dd8a15aa0 100644 --- a/hassio/__main__.py +++ b/hassio/__main__.py @@ -12,6 +12,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__) def initialize_event_loop(): """Attempt to use uvloop.""" try: + # pylint: disable=import-outside-toplevel import uvloop uvloop.install() diff --git a/hassio/addons/__init__.py b/hassio/addons/__init__.py index dba02f21f..7b3114279 100644 --- a/hassio/addons/__init__.py +++ b/hassio/addons/__init__.py @@ -293,7 +293,7 @@ class AddonManager(CoreSysAttributes): continue # Need local lookup - elif addon.need_build and not addon.is_detached: + if addon.need_build and not addon.is_detached: store = self.store[addon.slug] # If this add-on is available for rebuild if addon.version == store.version: diff --git a/hassio/bootstrap.py b/hassio/bootstrap.py index a5587f5d0..35b35eee4 100644 --- a/hassio/bootstrap.py +++ b/hassio/bootstrap.py @@ -236,6 +236,7 @@ def supervisor_debugger(coresys: CoreSys) -> None: """Setup debugger if needed.""" if not coresys.config.debug: return + # pylint: disable=import-outside-toplevel import ptvsd _LOGGER.info("Initialize Hass.io debugger") diff --git a/hassio/homeassistant.py b/hassio/homeassistant.py index d9fd3c7ff..9fe656659 100644 --- a/hassio/homeassistant.py +++ b/hassio/homeassistant.py @@ -575,7 +575,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): migration_progress = True _LOGGER.info("Home Assistant record migration in progress") continue - elif migration_progress: + if migration_progress: migration_progress = False # Reset start time start_time = time.monotonic() _LOGGER.info("Home Assistant record migration done") @@ -586,7 +586,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): pip_progress = True _LOGGER.info("Home Assistant pip installation in progress") continue - elif pip_progress: + if pip_progress: pip_progress = False # Reset start time start_time = time.monotonic() _LOGGER.info("Home Assistant pip installation done") diff --git a/requirements_tests.txt b/requirements_tests.txt index 3e0d445ac..ea828505b 100644 --- a/requirements_tests.txt +++ b/requirements_tests.txt @@ -1,5 +1,5 @@ flake8==3.7.8 -pylint==2.3.1 +pylint==2.4.0 pytest==5.1.3 pytest-timeout==1.3.3 pytest-aiohttp==0.3.0 From 4818ad74657fa5914a616a7a5b329ab5c9e8bce2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2019 18:08:33 +0200 Subject: [PATCH 03/21] Bump pylint from 2.4.0 to 2.4.1 (#1308) Bumps [pylint](https://github.com/PyCQA/pylint) from 2.4.0 to 2.4.1. - [Release notes](https://github.com/PyCQA/pylint/releases) - [Changelog](https://github.com/PyCQA/pylint/blob/master/ChangeLog) - [Commits](https://github.com/PyCQA/pylint/compare/pylint-2.4.0...pylint-2.4.1) Signed-off-by: dependabot-preview[bot] --- requirements_tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_tests.txt b/requirements_tests.txt index ea828505b..c48c2fa0e 100644 --- a/requirements_tests.txt +++ b/requirements_tests.txt @@ -1,5 +1,5 @@ flake8==3.7.8 -pylint==2.4.0 +pylint==2.4.1 pytest==5.1.3 pytest-timeout==1.3.3 pytest-aiohttp==0.3.0 From e30f39e97e6679fe15564956af94be9c0db4049c Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 30 Sep 2019 11:01:35 +0200 Subject: [PATCH 04/21] Update devcontainer.json --- .devcontainer/devcontainer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 61551f188..e61f5c215 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,7 +10,8 @@ "--privileged" ], "extensions": [ - "ms-python.python" + "ms-python.python", + "visualstudioexptteam.vscodeintellicode" ], "settings": { "python.pythonPath": "/usr/local/bin/python", From a75fd2d07e143a23bd9b78aae838b2e03d3c6627 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 30 Sep 2019 11:01:59 +0200 Subject: [PATCH 05/21] Update devcontainer.json --- .devcontainer/devcontainer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e61f5c215..be0cb1775 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -11,7 +11,8 @@ ], "extensions": [ "ms-python.python", - "visualstudioexptteam.vscodeintellicode" + "visualstudioexptteam.vscodeintellicode", + "esbenp.prettier-vscode" ], "settings": { "python.pythonPath": "/usr/local/bin/python", From fb2537708733e66f3eed62a4d76b8ddab0308253 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2019 22:15:12 +0200 Subject: [PATCH 06/21] Bump pytest from 5.1.3 to 5.2.0 (#1315) Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.1.3 to 5.2.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/5.1.3...5.2.0) Signed-off-by: dependabot-preview[bot] --- requirements_tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_tests.txt b/requirements_tests.txt index c48c2fa0e..f89308514 100644 --- a/requirements_tests.txt +++ b/requirements_tests.txt @@ -1,5 +1,5 @@ flake8==3.7.8 pylint==2.4.1 -pytest==5.1.3 +pytest==5.2.0 pytest-timeout==1.3.3 pytest-aiohttp==0.3.0 From 8ef32b40c885bfea0eae6ceba71075c58d4385bc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2019 22:21:00 +0200 Subject: [PATCH 07/21] Bump pylint from 2.4.1 to 2.4.2 (#1314) Bumps [pylint](https://github.com/PyCQA/pylint) from 2.4.1 to 2.4.2. - [Release notes](https://github.com/PyCQA/pylint/releases) - [Changelog](https://github.com/PyCQA/pylint/blob/master/ChangeLog) - [Commits](https://github.com/PyCQA/pylint/compare/pylint-2.4.1...pylint-2.4.2) Signed-off-by: dependabot-preview[bot] --- requirements_tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_tests.txt b/requirements_tests.txt index f89308514..6ad105112 100644 --- a/requirements_tests.txt +++ b/requirements_tests.txt @@ -1,5 +1,5 @@ flake8==3.7.8 -pylint==2.4.1 +pylint==2.4.2 pytest==5.2.0 pytest-timeout==1.3.3 pytest-aiohttp==0.3.0 From 46548af1652cf49b3d76289b56dc80337a695ff3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2019 13:06:20 +0200 Subject: [PATCH 08/21] Bump gitpython from 3.0.2 to 3.0.3 (#1319) Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/master/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.0.2...3.0.3) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3279921c3..8f0795d11 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ colorlog==4.0.2 cpe==1.2.1 cryptography==2.7 docker==4.0.2 -gitpython==3.0.2 +gitpython==3.0.3 packaging==19.2 pytz==2019.2 pyudev==0.21.0 From 603334f4f3bcb4ac666031a2a3850f04d6c0778c Mon Sep 17 00:00:00 2001 From: Timmo Date: Mon, 14 Oct 2019 10:30:18 +0100 Subject: [PATCH 09/21] Add support for Home Panel discovery (#1327) --- hassio/discovery/services/home_panel.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 hassio/discovery/services/home_panel.py diff --git a/hassio/discovery/services/home_panel.py b/hassio/discovery/services/home_panel.py new file mode 100644 index 000000000..c924239cf --- /dev/null +++ b/hassio/discovery/services/home_panel.py @@ -0,0 +1,11 @@ +"""Discovery service for Home Panel.""" +import voluptuous as vol + +from hassio.validate import NETWORK_PORT + +from ..const import ATTR_HOST, ATTR_PORT + + +SCHEMA = vol.Schema( + {vol.Required(ATTR_HOST): vol.Coerce(str), vol.Required(ATTR_PORT): NETWORK_PORT} +) From bf4f40f99133f9eb29f7e4d59a059bb48cdaea4b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2019 11:31:03 +0200 Subject: [PATCH 10/21] Bump docker from 4.0.2 to 4.1.0 (#1321) Bumps [docker](https://github.com/docker/docker-py) from 4.0.2 to 4.1.0. - [Release notes](https://github.com/docker/docker-py/releases) - [Commits](https://github.com/docker/docker-py/compare/4.0.2...4.1.0) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8f0795d11..61fcff56f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ cchardet==2.1.4 colorlog==4.0.2 cpe==1.2.1 cryptography==2.7 -docker==4.0.2 +docker==4.1.0 gitpython==3.0.3 packaging==19.2 pytz==2019.2 From 4c72c3aafc9f75fb3807dc35a6320c9b53b7b0bc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2019 11:32:45 +0200 Subject: [PATCH 11/21] Bump aiohttp from 3.6.1 to 3.6.2 (#1325) Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.6.1 to 3.6.2. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.6.1...v3.6.2) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 61fcff56f..3eca1b47d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.6.1 +aiohttp==3.6.2 async_timeout==3.0.1 attrs==19.1.0 cchardet==2.1.4 From 5aa9b0245a9d2e281419a8f9872f44e1370e19d8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2019 11:33:59 +0200 Subject: [PATCH 12/21] Bump pytest from 5.2.0 to 5.2.1 (#1324) Bumps [pytest](https://github.com/pytest-dev/pytest) from 5.2.0 to 5.2.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/5.2.0...5.2.1) Signed-off-by: dependabot-preview[bot] --- requirements_tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_tests.txt b/requirements_tests.txt index 6ad105112..7f70cfcc0 100644 --- a/requirements_tests.txt +++ b/requirements_tests.txt @@ -1,5 +1,5 @@ flake8==3.7.8 pylint==2.4.2 -pytest==5.2.0 +pytest==5.2.1 pytest-timeout==1.3.3 pytest-aiohttp==0.3.0 From b4497d231b7d20f78d3db23da0bc419e2f4ef26d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2019 11:40:50 +0200 Subject: [PATCH 13/21] Bump pytz from 2019.2 to 2019.3 (#1323) Bumps [pytz](https://github.com/stub42/pytz) from 2019.2 to 2019.3. - [Release notes](https://github.com/stub42/pytz/releases) - [Commits](https://github.com/stub42/pytz/compare/release_2019.2...release_2019.3) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3eca1b47d..5bb5d17fa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,7 @@ cryptography==2.7 docker==4.1.0 gitpython==3.0.3 packaging==19.2 -pytz==2019.2 +pytz==2019.3 pyudev==0.21.0 ruamel.yaml==0.15.100 uvloop==0.13.0 From 3574df1385abeb246c760ced3e68291c32f132b7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2019 16:48:06 +0200 Subject: [PATCH 14/21] Bump attrs from 19.1.0 to 19.3.0 (#1329) * Bump attrs from 19.1.0 to 19.3.0 Bumps [attrs](https://github.com/python-attrs/attrs) from 19.1.0 to 19.3.0. - [Release notes](https://github.com/python-attrs/attrs/releases) - [Changelog](https://github.com/python-attrs/attrs/blob/master/CHANGELOG.rst) - [Commits](https://github.com/python-attrs/attrs/compare/19.1.0...19.3.0) Signed-off-by: dependabot-preview[bot] * Fix attr Deprecations --- .devcontainer/devcontainer.json | 4 ++-- hassio/discovery/__init__.py | 4 ++-- hassio/host/alsa.py | 9 +++++++-- hassio/host/services.py | 6 +++--- requirements.txt | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index be0cb1775..02d1af0a8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "appPort": "9123:8123", "runArgs": [ "-e", - "GIT_EDITOR=\"code --wait\"", + "GIT_EDITOR=code --wait", "--privileged" ], "extensions": [ @@ -28,4 +28,4 @@ "editor.formatOnType": true, "files.trimTrailingWhitespace": true } -} +} \ No newline at end of file diff --git a/hassio/discovery/__init__.py b/hassio/discovery/__init__.py index 7fc5bfb49..3af8961ec 100644 --- a/hassio/discovery/__init__.py +++ b/hassio/discovery/__init__.py @@ -31,8 +31,8 @@ class Message: addon: str = attr.ib() service: str = attr.ib() - config: Dict[str, Any] = attr.ib(cmp=False) - uuid: UUID = attr.ib(factory=lambda: uuid4().hex, cmp=False) + config: Dict[str, Any] = attr.ib(eq=False) + uuid: UUID = attr.ib(factory=lambda: uuid4().hex, eq=False) class Discovery(CoreSysAttributes, JsonConfig): diff --git a/hassio/host/alsa.py b/hassio/host/alsa.py index 180fde33c..e17082364 100644 --- a/hassio/host/alsa.py +++ b/hassio/host/alsa.py @@ -11,8 +11,13 @@ from ..coresys import CoreSysAttributes _LOGGER: logging.Logger = logging.getLogger(__name__) -# pylint: disable=invalid-name -DefaultConfig = attr.make_class("DefaultConfig", ["input", "output"]) + +@attr.s() +class DefaultConfig: + """Default config input/output ALSA channel.""" + + input: str = attr.ib() + output: str = attr.ib() AUDIODB_JSON: Path = Path(__file__).parents[1].joinpath("data/audiodb.json") diff --git a/hassio/host/services.py b/hassio/host/services.py index 5eb7c70ba..6dd6367f4 100644 --- a/hassio/host/services.py +++ b/hassio/host/services.py @@ -91,9 +91,9 @@ class ServiceManager(CoreSysAttributes): class ServiceInfo: """Represent a single Service.""" - name = attr.ib(type=str) - description = attr.ib(type=str) - state = attr.ib(type=str) + name: str = attr.ib() + description: str = attr.ib() + state: str = attr.ib() @staticmethod def read_from(unit): diff --git a/requirements.txt b/requirements.txt index 5bb5d17fa..0a0185fda 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ aiohttp==3.6.2 async_timeout==3.0.1 -attrs==19.1.0 +attrs==19.3.0 cchardet==2.1.4 colorlog==4.0.2 cpe==1.2.1 From ba8ca4d9eea910ad3bed1394ae9fb38d8855ab3a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2019 14:53:35 +0200 Subject: [PATCH 15/21] Bump pylint from 2.4.2 to 2.4.3 (#1334) Bumps [pylint](https://github.com/PyCQA/pylint) from 2.4.2 to 2.4.3. - [Release notes](https://github.com/PyCQA/pylint/releases) - [Changelog](https://github.com/PyCQA/pylint/blob/master/ChangeLog) - [Commits](https://github.com/PyCQA/pylint/compare/pylint-2.4.2...pylint-2.4.3) Signed-off-by: dependabot-preview[bot] --- requirements_tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_tests.txt b/requirements_tests.txt index 7f70cfcc0..beffc951d 100644 --- a/requirements_tests.txt +++ b/requirements_tests.txt @@ -1,5 +1,5 @@ flake8==3.7.8 -pylint==2.4.2 +pylint==2.4.3 pytest==5.2.1 pytest-timeout==1.3.3 pytest-aiohttp==0.3.0 From a9ebb147c5635fb1624ac936e29332a015412fa3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2019 14:54:28 +0200 Subject: [PATCH 16/21] Bump cryptography from 2.7 to 2.8 (#1332) Bumps [cryptography](https://github.com/pyca/cryptography) from 2.7 to 2.8. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/2.7...2.8) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0a0185fda..3f31bed6b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ attrs==19.3.0 cchardet==2.1.4 colorlog==4.0.2 cpe==1.2.1 -cryptography==2.7 +cryptography==2.8 docker==4.1.0 gitpython==3.0.3 packaging==19.2 From 05c8022db31bdd427055f0eb49c69744b2eb4f8d Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 21 Oct 2019 12:23:00 +0200 Subject: [PATCH 17/21] Check path on extractall (#1336) * Check path on extractall * code cleanup * Add logger * Fix issue * Add tests --- hassio/addons/addon.py | 3 ++- hassio/snapshots/snapshot.py | 6 +++--- hassio/utils/tar.py | 26 +++++++++++++++++++++++--- tests/utils/test_tarfile.py | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 tests/utils/test_tarfile.py diff --git a/hassio/addons/addon.py b/hassio/addons/addon.py index 5b633946e..e47c593d4 100644 --- a/hassio/addons/addon.py +++ b/hassio/addons/addon.py @@ -51,6 +51,7 @@ from ..exceptions import ( ) from ..utils.apparmor import adjust_profile from ..utils.json import read_json_file, write_json_file +from ..utils.tar import secure_path from .model import AddonModel, Data from .utils import remove_data from .validate import SCHEMA_ADDON_SNAPSHOT, validate_options @@ -579,7 +580,7 @@ class Addon(AddonModel): def _extract_tarfile(): """Extract tar snapshot.""" with tar_file as snapshot: - snapshot.extractall(path=Path(temp)) + snapshot.extractall(path=Path(temp), member=secure_path(snapshot)) try: await self.sys_run_in_executor(_extract_tarfile) diff --git a/hassio/snapshots/snapshot.py b/hassio/snapshots/snapshot.py index 9437d748b..5ea4d3d5b 100644 --- a/hassio/snapshots/snapshot.py +++ b/hassio/snapshots/snapshot.py @@ -41,7 +41,7 @@ from ..const import ( from ..coresys import CoreSys, CoreSysAttributes from ..exceptions import AddonsError from ..utils.json import write_json_file -from ..utils.tar import SecureTarFile +from ..utils.tar import SecureTarFile, secure_path from .utils import key_to_iv, password_for_validating, password_to_key, remove_folder from .validate import ALL_FOLDERS, SCHEMA_SNAPSHOT @@ -248,7 +248,7 @@ class Snapshot(CoreSysAttributes): def _extract_snapshot(): """Extract a snapshot.""" with tarfile.open(self.tarfile, "r:") as tar: - tar.extractall(path=self._tmp.name) + tar.extractall(path=self._tmp.name, members=secure_path(tar)) await self.sys_run_in_executor(_extract_snapshot) @@ -396,7 +396,7 @@ class Snapshot(CoreSysAttributes): try: _LOGGER.info("Restore folder %s", name) with SecureTarFile(tar_name, "r", key=self._key) as tar_file: - tar_file.extractall(path=origin_dir) + tar_file.extractall(path=origin_dir, members=tar_file) _LOGGER.info("Restore folder %s done", name) except (tarfile.TarError, OSError) as err: _LOGGER.warning("Can't restore folder %s: %s", name, err) diff --git a/hassio/utils/tar.py b/hassio/utils/tar.py index af3b0a181..9d5be5741 100644 --- a/hassio/utils/tar.py +++ b/hassio/utils/tar.py @@ -1,19 +1,22 @@ """Tarfile fileobject handler for encrypted files.""" import hashlib +import logging import os -from pathlib import Path import tarfile -from typing import IO, Optional +from pathlib import Path +from typing import IO, Generator, Optional from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding from cryptography.hazmat.primitives.ciphers import ( - CipherContext, Cipher, + CipherContext, algorithms, modes, ) +_LOGGER: logging.Logger = logging.getLogger(__name__) + BLOCK_SIZE = 16 BLOCK_SIZE_BITS = 128 @@ -111,3 +114,20 @@ def _generate_iv(key: bytes, salt: bytes) -> bytes: for _ in range(100): temp_iv = hashlib.sha256(temp_iv).digest() return temp_iv[:16] + + +def secure_path(tar: tarfile.TarFile) -> Generator[tarfile.TarInfo, None, None]: + """Security safe check of path. + + Prevent ../ or absolut paths + """ + for member in tar: + file_path = Path(member.name) + try: + assert not file_path.is_absolute() + Path("/fake", file_path).resolve().relative_to("/fake") + except (ValueError, RuntimeError, AssertionError): + _LOGGER.warning("Issue with file %s", file_path) + continue + else: + yield member diff --git a/tests/utils/test_tarfile.py b/tests/utils/test_tarfile.py new file mode 100644 index 000000000..ed61871ea --- /dev/null +++ b/tests/utils/test_tarfile.py @@ -0,0 +1,33 @@ +"""Test Tarfile functions.""" + +import attr + +from hassio.utils.tar import secure_path + + +@attr.s +class TarInfo: + """Fake TarInfo""" + + name: str = attr.ib() + + +def test_secure_path(): + """Test Secure Path.""" + test_list = [ + TarInfo("test.txt"), + TarInfo("data/xy.blob"), + TarInfo("bla/blu/ble"), + TarInfo("data/../xy.blob"), + ] + assert test_list == list(secure_path(test_list)) + + +def test_not_secure_path(): + """Test Not secure path.""" + test_list = [ + TarInfo("/test.txt"), + TarInfo("data/../../xy.blob"), + TarInfo("/bla/blu/ble"), + ] + assert [] == list(secure_path(test_list)) From 11811701d06775d4c871078459878588cc3b2529 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 21 Oct 2019 14:48:24 +0200 Subject: [PATCH 18/21] Add snapshot_exclude option (#1337) * Add snapshot tar filter * Add filter to add-on * Fix bug * Fix --- hassio/addons/addon.py | 19 +++++++++++++------ hassio/addons/model.py | 6 ++++++ hassio/addons/validate.py | 2 ++ hassio/const.py | 1 + hassio/snapshots/utils.py | 2 +- hassio/store/git.py | 2 +- hassio/utils/tar.py | 23 +++++++++++++++++++++-- tests/utils/test_tarfile.py | 30 +++++++++++++++++++++++++++++- 8 files changed, 74 insertions(+), 11 deletions(-) diff --git a/hassio/addons/addon.py b/hassio/addons/addon.py index e47c593d4..50e6f9eac 100644 --- a/hassio/addons/addon.py +++ b/hassio/addons/addon.py @@ -51,7 +51,7 @@ from ..exceptions import ( ) from ..utils.apparmor import adjust_profile from ..utils.json import read_json_file, write_json_file -from ..utils.tar import secure_path +from ..utils.tar import exclude_filter, secure_path from .model import AddonModel, Data from .utils import remove_data from .validate import SCHEMA_ADDON_SNAPSHOT, validate_options @@ -526,7 +526,7 @@ class Addon(AddonModel): async def snapshot(self, tar_file: tarfile.TarFile) -> None: """Snapshot state of an add-on.""" - with TemporaryDirectory(dir=str(self.sys_config.path_tmp)) as temp: + with TemporaryDirectory(dir=self.sys_config.path_tmp) as temp: # store local image if self.need_build: try: @@ -561,8 +561,15 @@ class Addon(AddonModel): def _write_tarfile(): """Write tar inside loop.""" with tar_file as snapshot: + # Snapshot system snapshot.add(temp, arcname=".") - snapshot.add(self.path_data, arcname="data") + + # Snapshot data + snapshot.add( + self.path_data, + arcname="data", + filter=exclude_filter(self.snapshot_exclude), + ) try: _LOGGER.info("Build snapshot for add-on %s", self.slug) @@ -575,12 +582,12 @@ class Addon(AddonModel): async def restore(self, tar_file: tarfile.TarFile) -> None: """Restore state of an add-on.""" - with TemporaryDirectory(dir=str(self.sys_config.path_tmp)) as temp: + with TemporaryDirectory(dir=self.sys_config.path_tmp) as temp: # extract snapshot def _extract_tarfile(): """Extract tar snapshot.""" with tar_file as snapshot: - snapshot.extractall(path=Path(temp), member=secure_path(snapshot)) + snapshot.extractall(path=Path(temp), members=secure_path(snapshot)) try: await self.sys_run_in_executor(_extract_tarfile) @@ -641,7 +648,7 @@ class Addon(AddonModel): # Restore data def _restore_data(): """Restore data.""" - shutil.copytree(str(Path(temp, "data")), str(self.path_data)) + shutil.copytree(Path(temp, "data"), self.path_data) _LOGGER.info("Restore data for addon %s", self.slug) if self.path_data.is_dir(): diff --git a/hassio/addons/model.py b/hassio/addons/model.py index ffdada1c9..6cc799b44 100644 --- a/hassio/addons/model.py +++ b/hassio/addons/model.py @@ -47,6 +47,7 @@ from ..const import ( ATTR_SCHEMA, ATTR_SERVICES, ATTR_SLUG, + ATTR_SNAPSHOT_EXCLUDE, ATTR_STARTUP, ATTR_STDIN, ATTR_TIMEOUT, @@ -324,6 +325,11 @@ class AddonModel(CoreSysAttributes): """Return Hass.io role for API.""" return self.data[ATTR_HASSIO_ROLE] + @property + def snapshot_exclude(self) -> List[str]: + """Return Exclude list for snapshot.""" + return self.data.get(ATTR_SNAPSHOT_EXCLUDE, []) + @property def with_stdin(self) -> bool: """Return True if the add-on access use stdin input.""" diff --git a/hassio/addons/validate.py b/hassio/addons/validate.py index 87b695887..d47c9e2d9 100644 --- a/hassio/addons/validate.py +++ b/hassio/addons/validate.py @@ -62,6 +62,7 @@ from ..const import ( ATTR_SCHEMA, ATTR_SERVICES, ATTR_SLUG, + ATTR_SNAPSHOT_EXCLUDE, ATTR_SQUASH, ATTR_STARTUP, ATTR_STATE, @@ -214,6 +215,7 @@ SCHEMA_ADDON_CONFIG = vol.Schema( vol.Optional(ATTR_AUTH_API, default=False): vol.Boolean(), vol.Optional(ATTR_SERVICES): [vol.Match(RE_SERVICE)], vol.Optional(ATTR_DISCOVERY): [valid_discovery_service], + vol.Optional(ATTR_SNAPSHOT_EXCLUDE): [vol.Coerce(str)], vol.Required(ATTR_OPTIONS): dict, vol.Required(ATTR_SCHEMA): vol.Any( vol.Schema( diff --git a/hassio/const.py b/hassio/const.py index 223534629..6194f771b 100644 --- a/hassio/const.py +++ b/hassio/const.py @@ -221,6 +221,7 @@ ATTR_SERVERS = "servers" ATTR_LOCALS = "locals" ATTR_UDEV = "udev" ATTR_VALUE = "value" +ATTR_SNAPSHOT_EXCLUDE = "snapshot_exclude" PROVIDE_SERVICE = "provide" NEED_SERVICE = "need" diff --git a/hassio/snapshots/utils.py b/hassio/snapshots/utils.py index 2f9d73bce..a2403a482 100644 --- a/hassio/snapshots/utils.py +++ b/hassio/snapshots/utils.py @@ -42,7 +42,7 @@ def remove_folder(folder): for obj in folder.iterdir(): try: if obj.is_dir(): - shutil.rmtree(str(obj), ignore_errors=True) + shutil.rmtree(obj, ignore_errors=True) else: obj.unlink() except (OSError, shutil.Error): diff --git a/hassio/store/git.py b/hassio/store/git.py index 7bff4f6ab..a60799230 100644 --- a/hassio/store/git.py +++ b/hassio/store/git.py @@ -137,7 +137,7 @@ class GitRepo(CoreSysAttributes): """Log error.""" _LOGGER.warning("Can't remove %s", path) - shutil.rmtree(str(self.path), onerror=log_err) + shutil.rmtree(self.path, onerror=log_err) class GitRepoHassIO(GitRepo): diff --git a/hassio/utils/tar.py b/hassio/utils/tar.py index 9d5be5741..27f12fa94 100644 --- a/hassio/utils/tar.py +++ b/hassio/utils/tar.py @@ -2,9 +2,9 @@ import hashlib import logging import os -import tarfile from pathlib import Path -from typing import IO, Generator, Optional +import tarfile +from typing import IO, Callable, Generator, List, Optional from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding @@ -131,3 +131,22 @@ def secure_path(tar: tarfile.TarFile) -> Generator[tarfile.TarInfo, None, None]: continue else: yield member + + +def exclude_filter( + exclude_list: List[str] +) -> Callable[[tarfile.TarInfo], Optional[tarfile.TarInfo]]: + """Create callable filter function to check TarInfo for add.""" + + def my_filter(tar: tarfile.TarInfo) -> Optional[tarfile.TarInfo]: + """Custom exclude filter.""" + file_path = Path(tar.name) + for exclude in exclude_list: + if not file_path.match(exclude): + continue + _LOGGER.debug("Ignore %s because of %s", file_path, exclude) + return None + + return tar + + return my_filter diff --git a/tests/utils/test_tarfile.py b/tests/utils/test_tarfile.py index ed61871ea..e0a5e31e7 100644 --- a/tests/utils/test_tarfile.py +++ b/tests/utils/test_tarfile.py @@ -1,8 +1,9 @@ """Test Tarfile functions.""" import attr +import pytest -from hassio.utils.tar import secure_path +from hassio.utils.tar import secure_path, exclude_filter @attr.s @@ -31,3 +32,30 @@ def test_not_secure_path(): TarInfo("/bla/blu/ble"), ] assert [] == list(secure_path(test_list)) + + +def test_exclude_filter_good(): + """Test exclude filter.""" + filter_funct = exclude_filter(["not/match", "/dev/xy"]) + test_list = [ + TarInfo("test.txt"), + TarInfo("data/xy.blob"), + TarInfo("bla/blu/ble"), + TarInfo("data/../xy.blob"), + ] + + assert test_list == [filter_funct(result) for result in test_list] + + +def test_exclude_filter_bad(): + """Test exclude filter.""" + filter_funct = exclude_filter(["*.txt", "data/*", "bla/blu/ble"]) + test_list = [ + TarInfo("test.txt"), + TarInfo("data/xy.blob"), + TarInfo("bla/blu/ble"), + TarInfo("data/test_files/kk.txt"), + ] + + for info in [filter_funct(result) for result in test_list]: + assert info is None From 927b4695c99260d0e8bd540c38bb864636b78a8d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2019 13:31:14 +0200 Subject: [PATCH 19/21] Bump gitpython from 3.0.3 to 3.0.4 (#1338) Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.0.3 to 3.0.4. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/master/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.0.3...3.0.4) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3f31bed6b..418f45365 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ colorlog==4.0.2 cpe==1.2.1 cryptography==2.8 docker==4.1.0 -gitpython==3.0.3 +gitpython==3.0.4 packaging==19.2 pytz==2019.3 pyudev==0.21.0 From 615e68b29b17875a56f7d95581afa2c953062a2f Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 22 Oct 2019 13:39:46 +0200 Subject: [PATCH 20/21] Add discovery support for Almond (#1339) * Add discovery support for Almond * Fix docstring --- hassio/discovery/services/almond.py | 11 +++++++++++ tests/discovery/test_almond.py | 19 +++++++++++++++++++ tests/discovery/test_home_panel.py | 19 +++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 hassio/discovery/services/almond.py create mode 100644 tests/discovery/test_almond.py create mode 100644 tests/discovery/test_home_panel.py diff --git a/hassio/discovery/services/almond.py b/hassio/discovery/services/almond.py new file mode 100644 index 000000000..c8afa158e --- /dev/null +++ b/hassio/discovery/services/almond.py @@ -0,0 +1,11 @@ +"""Discovery service for Almond.""" +import voluptuous as vol + +from hassio.validate import NETWORK_PORT + +from ..const import ATTR_HOST, ATTR_PORT + + +SCHEMA = vol.Schema( + {vol.Required(ATTR_HOST): vol.Coerce(str), vol.Required(ATTR_PORT): NETWORK_PORT} +) diff --git a/tests/discovery/test_almond.py b/tests/discovery/test_almond.py new file mode 100644 index 000000000..78a8e186c --- /dev/null +++ b/tests/discovery/test_almond.py @@ -0,0 +1,19 @@ +"""Test adguard discovery.""" + +import voluptuous as vol +import pytest + +from hassio.discovery.validate import valid_discovery_config + + +def test_good_config(): + """Test good deconz config.""" + + valid_discovery_config("almond", {"host": "test", "port": 3812}) + + +def test_bad_config(): + """Test good adguard config.""" + + with pytest.raises(vol.Invalid): + valid_discovery_config("almond", {"host": "test"}) diff --git a/tests/discovery/test_home_panel.py b/tests/discovery/test_home_panel.py new file mode 100644 index 000000000..883aeb678 --- /dev/null +++ b/tests/discovery/test_home_panel.py @@ -0,0 +1,19 @@ +"""Test adguard discovery.""" + +import voluptuous as vol +import pytest + +from hassio.discovery.validate import valid_discovery_config + + +def test_good_config(): + """Test good deconz config.""" + + valid_discovery_config("home_panel", {"host": "test", "port": 3812}) + + +def test_bad_config(): + """Test good adguard config.""" + + with pytest.raises(vol.Invalid): + valid_discovery_config("home_panel", {"host": "test"}) From 74485262e783fc807517b929460ec1e9d0bc3154 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 22 Oct 2019 14:30:14 +0200 Subject: [PATCH 21/21] Prune network/interface on repair (#1340) * Prune network/interface on repair * Force disconnect --- hassio/addons/__init__.py | 3 +++ hassio/docker/__init__.py | 7 +++++++ hassio/docker/network.py | 9 +++++++++ hassio/homeassistant.py | 5 +++++ 4 files changed, 24 insertions(+) diff --git a/hassio/addons/__init__.py b/hassio/addons/__init__.py index 7b3114279..fe95b1d29 100644 --- a/hassio/addons/__init__.py +++ b/hassio/addons/__init__.py @@ -285,6 +285,9 @@ class AddonManager(CoreSysAttributes): for addon in needs_repair: _LOGGER.info("Start repair for add-on: %s", addon.slug) + await self.sys_run_in_executor( + self.sys_docker.network.stale_cleanup, addon.instance.name + ) with suppress(DockerAPIError, KeyError): # Need pull a image again diff --git a/hassio/docker/__init__.py b/hassio/docker/__init__.py index 66c0846ab..8274d506a 100644 --- a/hassio/docker/__init__.py +++ b/hassio/docker/__init__.py @@ -178,3 +178,10 @@ class DockerAPI: _LOGGER.debug("Volumes prune: %s", output) except docker.errors.APIError as err: _LOGGER.warning("Error for volumes prune: %s", err) + + _LOGGER.info("Prune stale networks") + try: + output = self.docker.api.prune_networks() + _LOGGER.debug("Networks prune: %s", output) + except docker.errors.APIError as err: + _LOGGER.warning("Error for networks prune: %s", err) diff --git a/hassio/docker/network.py b/hassio/docker/network.py index 3f4d0943b..610a4db61 100644 --- a/hassio/docker/network.py +++ b/hassio/docker/network.py @@ -1,4 +1,5 @@ """Internal network manager for Hass.io.""" +from contextlib import suppress from ipaddress import IPv4Address import logging from typing import List, Optional @@ -107,3 +108,11 @@ class DockerNetwork: except docker.errors.APIError as err: _LOGGER.warning("Can't disconnect container from default: %s", err) raise DockerAPIError() from None + + def stale_cleanup(self, container_name: str): + """Remove force a container from Network. + + Fix: https://github.com/moby/moby/issues/23302 + """ + with suppress(docker.errors.APIError): + self.network.disconnect(container_name, force=True) diff --git a/hassio/homeassistant.py b/hassio/homeassistant.py index 9fe656659..672c71856 100644 --- a/hassio/homeassistant.py +++ b/hassio/homeassistant.py @@ -605,6 +605,11 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): return _LOGGER.info("Repair Home Assistant %s", self.version) + await self.sys_run_in_executor( + self.sys_docker.network.stale_cleanup, self.instance.name + ) + + # Pull image try: await self.instance.install(self.version) except DockerAPIError: