diff --git a/hassio/homeassistant.py b/hassio/homeassistant.py index 405d2de24..72d178a4c 100644 --- a/hassio/homeassistant.py +++ b/hassio/homeassistant.py @@ -8,7 +8,6 @@ import os from pathlib import Path import re import secrets -import socket import time from typing import Any, AsyncContextManager, Awaitable, Dict, Optional from uuid import UUID @@ -42,7 +41,7 @@ from .exceptions import ( HomeAssistantError, HomeAssistantUpdateError, ) -from .utils import convert_to_ascii, process_lock +from .utils import convert_to_ascii, process_lock, check_port from .utils.json import JsonConfig from .validate import SCHEMA_HASS_CONFIG @@ -511,22 +510,14 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): async def _block_till_run(self) -> None: """Block until Home-Assistant is booting up or startup timeout.""" start_time = time.monotonic() + + # Database migration migration_progress = False migration_file = Path(self.sys_config.path_homeassistant, ".migration_progress") - def check_port(): - """Check if port is mapped.""" - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - result = sock.connect_ex((str(self.ip_address), self.api_port)) - sock.close() - - # Check if the port is available - if result == 0: - return True - except OSError: - pass - return False + # PIP installation + pip_progress = False + pip_file = Path(self.sys_config.path_homeassistant, ".pip_progress") while True: await asyncio.sleep(5) @@ -537,7 +528,9 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): break # 2: Check if API response - if await self.sys_run_in_executor(check_port): + if await self.sys_run_in_executor( + check_port, self.ip_address, self.api_port + ): _LOGGER.info("Detect a running Home Assistant instance") self._error_state = False return @@ -553,7 +546,18 @@ class HomeAssistant(JsonConfig, CoreSysAttributes): start_time = time.monotonic() _LOGGER.info("Home Assistant record migration done") - # 4: Timeout + # 4: Running PIP installation + if pip_file.exists(): + if not pip_progress: + pip_progress = True + _LOGGER.info("Home Assistant pip installation in progress") + continue + elif pip_progress: + pip_progress = False # Reset start time + start_time = time.monotonic() + _LOGGER.info("Home Assistant pip installation done") + + # 5: Timeout if time.monotonic() - start_time > self.wait_boot: _LOGGER.warning("Don't wait anymore of Home Assistant startup!") break diff --git a/hassio/utils/__init__.py b/hassio/utils/__init__.py index ec433e58c..0f46f7f58 100644 --- a/hassio/utils/__init__.py +++ b/hassio/utils/__init__.py @@ -1,13 +1,15 @@ """Tools file for Hass.io.""" +from datetime import datetime +from ipaddress import IPv4Address import logging import re -from datetime import datetime +import socket _LOGGER = logging.getLogger(__name__) RE_STRING = re.compile(r"\x1b(\[.*?[@-~]|\].*?(\x07|\x1b\\))") -def convert_to_ascii(raw) -> str: +def convert_to_ascii(raw: bytes) -> str: """Convert binary to ascii and remove colors.""" return RE_STRING.sub("", raw.decode()) @@ -53,3 +55,18 @@ class AsyncThrottle: return await method(*args, **kwargs) return wrapper + + +def check_port(address: IPv4Address, port: int) -> bool: + """Check if port is mapped.""" + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + result = sock.connect_ex((str(address), port)) + sock.close() + + # Check if the port is available + if result == 0: + return True + except OSError: + pass + return False diff --git a/tests/discovery/test_adguard.py b/tests/discovery/test_adguard.py new file mode 100644 index 000000000..9f54a1961 --- /dev/null +++ b/tests/discovery/test_adguard.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("adguard", {"host": "test", "port": 3812}) + + +def test_bad_config(): + """Test good adguard config.""" + + with pytest.raises(vol.Invalid): + valid_discovery_config("adguard", {"host": "test"}) diff --git a/tests/utils/test_check_port.py b/tests/utils/test_check_port.py new file mode 100644 index 000000000..f38e9c94d --- /dev/null +++ b/tests/utils/test_check_port.py @@ -0,0 +1,14 @@ +"""Check ports.""" +from ipaddress import ip_address + +from hassio.utils import check_port + + +def test_exists_open_port(): + """Test a exists network port.""" + assert check_port(ip_address("8.8.8.8"), 53) + + +def test_not_exists_port(): + """Test a not exists network service.""" + assert not check_port(ip_address("192.0.2.1"), 53)