mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Improve is docker env checks (#132404)
Co-authored-by: Franck Nijhof <frenck@frenck.nl> Co-authored-by: Sander Hoentjen <sander@hoentjen.eu> Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io> Co-authored-by: Robert Resch <robert@resch.dev>
This commit is contained in:
parent
5439613bff
commit
9e8df72c0d
@ -89,7 +89,7 @@ from .helpers import (
|
|||||||
)
|
)
|
||||||
from .helpers.dispatcher import async_dispatcher_send_internal
|
from .helpers.dispatcher import async_dispatcher_send_internal
|
||||||
from .helpers.storage import get_internal_store_manager
|
from .helpers.storage import get_internal_store_manager
|
||||||
from .helpers.system_info import async_get_system_info, is_official_image
|
from .helpers.system_info import async_get_system_info
|
||||||
from .helpers.typing import ConfigType
|
from .helpers.typing import ConfigType
|
||||||
from .setup import (
|
from .setup import (
|
||||||
# _setup_started is marked as protected to make it clear
|
# _setup_started is marked as protected to make it clear
|
||||||
@ -106,6 +106,7 @@ from .util.async_ import create_eager_task
|
|||||||
from .util.hass_dict import HassKey
|
from .util.hass_dict import HassKey
|
||||||
from .util.logging import async_activate_log_queue_handler
|
from .util.logging import async_activate_log_queue_handler
|
||||||
from .util.package import async_get_user_site, is_docker_env, is_virtual_env
|
from .util.package import async_get_user_site, is_docker_env, is_virtual_env
|
||||||
|
from .util.system_info import is_official_image
|
||||||
|
|
||||||
with contextlib.suppress(ImportError):
|
with contextlib.suppress(ImportError):
|
||||||
# Ensure anyio backend is imported to avoid it being imported in the event loop
|
# Ensure anyio backend is imported to avoid it being imported in the event loop
|
||||||
|
@ -23,10 +23,10 @@ from homeassistant.helpers.dispatcher import (
|
|||||||
async_dispatcher_send,
|
async_dispatcher_send,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.helpers.system_info import is_official_image
|
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
from homeassistant.util.signal_type import SignalType
|
from homeassistant.util.signal_type import SignalType
|
||||||
|
from homeassistant.util.system_info import is_official_image
|
||||||
|
|
||||||
DOMAIN = "ffmpeg"
|
DOMAIN = "ffmpeg"
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ from __future__ import annotations
|
|||||||
from functools import cache
|
from functools import cache
|
||||||
from getpass import getuser
|
from getpass import getuser
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import platform
|
import platform
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
@ -13,6 +12,7 @@ from homeassistant.const import __version__ as current_version
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
from homeassistant.util.package import is_docker_env, is_virtual_env
|
from homeassistant.util.package import is_docker_env, is_virtual_env
|
||||||
|
from homeassistant.util.system_info import is_official_image
|
||||||
|
|
||||||
from .hassio import is_hassio
|
from .hassio import is_hassio
|
||||||
from .importlib import async_import_module
|
from .importlib import async_import_module
|
||||||
@ -23,12 +23,6 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
_DATA_MAC_VER = "system_info_mac_ver"
|
_DATA_MAC_VER = "system_info_mac_ver"
|
||||||
|
|
||||||
|
|
||||||
@cache
|
|
||||||
def is_official_image() -> bool:
|
|
||||||
"""Return True if Home Assistant is running in an official container."""
|
|
||||||
return os.path.isfile("/OFFICIAL_IMAGE")
|
|
||||||
|
|
||||||
|
|
||||||
@singleton(_DATA_MAC_VER)
|
@singleton(_DATA_MAC_VER)
|
||||||
async def async_get_mac_ver(hass: HomeAssistant) -> str:
|
async def async_get_mac_ver(hass: HomeAssistant) -> str:
|
||||||
"""Return the macOS version."""
|
"""Return the macOS version."""
|
||||||
|
@ -15,6 +15,8 @@ from urllib.parse import urlparse
|
|||||||
|
|
||||||
from packaging.requirements import InvalidRequirement, Requirement
|
from packaging.requirements import InvalidRequirement, Requirement
|
||||||
|
|
||||||
|
from .system_info import is_official_image
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -28,8 +30,13 @@ def is_virtual_env() -> bool:
|
|||||||
|
|
||||||
@cache
|
@cache
|
||||||
def is_docker_env() -> bool:
|
def is_docker_env() -> bool:
|
||||||
"""Return True if we run in a docker env."""
|
"""Return True if we run in a container env."""
|
||||||
return Path("/.dockerenv").exists()
|
return (
|
||||||
|
Path("/.dockerenv").exists()
|
||||||
|
or Path("/run/.containerenv").exists()
|
||||||
|
or "KUBERNETES_SERVICE_HOST" in os.environ
|
||||||
|
or is_official_image()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_installed_versions(specifiers: set[str]) -> set[str]:
|
def get_installed_versions(specifiers: set[str]) -> set[str]:
|
||||||
|
12
homeassistant/util/system_info.py
Normal file
12
homeassistant/util/system_info.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
"""Util to gather system info."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from functools import cache
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def is_official_image() -> bool:
|
||||||
|
"""Return True if Home Assistant is running in an official container."""
|
||||||
|
return os.path.isfile("/OFFICIAL_IMAGE")
|
@ -9,17 +9,7 @@ import pytest
|
|||||||
from homeassistant.components import hassio
|
from homeassistant.components import hassio
|
||||||
from homeassistant.const import __version__ as current_version
|
from homeassistant.const import __version__ as current_version
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.system_info import async_get_system_info, is_official_image
|
from homeassistant.helpers.system_info import async_get_system_info
|
||||||
|
|
||||||
|
|
||||||
async def test_is_official_image() -> None:
|
|
||||||
"""Test is_official_image."""
|
|
||||||
is_official_image.cache_clear()
|
|
||||||
with patch("homeassistant.helpers.system_info.os.path.isfile", return_value=True):
|
|
||||||
assert is_official_image() is True
|
|
||||||
is_official_image.cache_clear()
|
|
||||||
with patch("homeassistant.helpers.system_info.os.path.isfile", return_value=False):
|
|
||||||
assert is_official_image() is False
|
|
||||||
|
|
||||||
|
|
||||||
async def test_get_system_info(hass: HomeAssistant) -> None:
|
async def test_get_system_info(hass: HomeAssistant) -> None:
|
||||||
|
@ -410,3 +410,47 @@ def test_check_package_previous_failed_install() -> None:
|
|||||||
with patch("homeassistant.util.package.version", return_value=None):
|
with patch("homeassistant.util.package.version", return_value=None):
|
||||||
assert not package.is_installed(installed_package)
|
assert not package.is_installed(installed_package)
|
||||||
assert not package.is_installed(f"{installed_package}=={installed_version}")
|
assert not package.is_installed(f"{installed_package}=={installed_version}")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("dockerenv", [True, False], ids=["dockerenv", "not_dockerenv"])
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"containerenv", [True, False], ids=["containerenv", "not_containerenv"]
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"kubernetes_service_host", [True, False], ids=["kubernetes", "not_kubernetes"]
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"is_official_image", [True, False], ids=["official_image", "not_official_image"]
|
||||||
|
)
|
||||||
|
async def test_is_docker_env(
|
||||||
|
dockerenv: bool,
|
||||||
|
containerenv: bool,
|
||||||
|
kubernetes_service_host: bool,
|
||||||
|
is_official_image: bool,
|
||||||
|
) -> None:
|
||||||
|
"""Test is_docker_env."""
|
||||||
|
|
||||||
|
def new_path_mock(path: str):
|
||||||
|
mock = Mock()
|
||||||
|
if path == "/.dockerenv":
|
||||||
|
mock.exists.return_value = dockerenv
|
||||||
|
elif path == "/run/.containerenv":
|
||||||
|
mock.exists.return_value = containerenv
|
||||||
|
return mock
|
||||||
|
|
||||||
|
env = {}
|
||||||
|
if kubernetes_service_host:
|
||||||
|
env["KUBERNETES_SERVICE_HOST"] = "True"
|
||||||
|
|
||||||
|
package.is_docker_env.cache_clear()
|
||||||
|
with (
|
||||||
|
patch("homeassistant.util.package.Path", side_effect=new_path_mock),
|
||||||
|
patch(
|
||||||
|
"homeassistant.util.package.is_official_image",
|
||||||
|
return_value=is_official_image,
|
||||||
|
),
|
||||||
|
patch.dict(os.environ, env),
|
||||||
|
):
|
||||||
|
assert package.is_docker_env() is any(
|
||||||
|
[dockerenv, containerenv, kubernetes_service_host, is_official_image]
|
||||||
|
)
|
||||||
|
15
tests/util/test_system_info.py
Normal file
15
tests/util/test_system_info.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
"""Tests for the system info helper."""
|
||||||
|
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from homeassistant.util.system_info import is_official_image
|
||||||
|
|
||||||
|
|
||||||
|
async def test_is_official_image() -> None:
|
||||||
|
"""Test is_official_image."""
|
||||||
|
is_official_image.cache_clear()
|
||||||
|
with patch("homeassistant.util.system_info.os.path.isfile", return_value=True):
|
||||||
|
assert is_official_image() is True
|
||||||
|
is_official_image.cache_clear()
|
||||||
|
with patch("homeassistant.util.system_info.os.path.isfile", return_value=False):
|
||||||
|
assert is_official_image() is False
|
Loading…
x
Reference in New Issue
Block a user