mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Extract instance ID helper from updater (#35043)
This commit is contained in:
parent
b3e637ca7a
commit
e54e9279e3
@ -1,9 +1,7 @@
|
||||
"""Support to check for available updates."""
|
||||
from datetime import timedelta
|
||||
from distutils.version import StrictVersion
|
||||
import json
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
import async_timeout
|
||||
from distro import linux_distribution # pylint: disable=import-error
|
||||
@ -25,7 +23,6 @@ CONF_COMPONENT_REPORTING = "include_used_components"
|
||||
DOMAIN = "updater"
|
||||
|
||||
UPDATER_URL = "https://updater.home-assistant.io/"
|
||||
UPDATER_UUID_FILE = ".uuid"
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
@ -52,26 +49,6 @@ class Updater:
|
||||
self.newest_version = newest_version
|
||||
|
||||
|
||||
def _create_uuid(hass, filename=UPDATER_UUID_FILE):
|
||||
"""Create UUID and save it in a file."""
|
||||
with open(hass.config.path(filename), "w") as fptr:
|
||||
_uuid = uuid.uuid4().hex
|
||||
fptr.write(json.dumps({"uuid": _uuid}))
|
||||
return _uuid
|
||||
|
||||
|
||||
def _load_uuid(hass, filename=UPDATER_UUID_FILE):
|
||||
"""Load UUID from a file or return None."""
|
||||
try:
|
||||
with open(hass.config.path(filename)) as fptr:
|
||||
jsonf = json.loads(fptr.read())
|
||||
return uuid.UUID(jsonf["uuid"], version=4).hex
|
||||
except (ValueError, AttributeError):
|
||||
return None
|
||||
except FileNotFoundError:
|
||||
return _create_uuid(hass, filename)
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
"""Set up the updater component."""
|
||||
if "dev" in current_version:
|
||||
@ -80,7 +57,7 @@ async def async_setup(hass, config):
|
||||
|
||||
conf = config.get(DOMAIN, {})
|
||||
if conf.get(CONF_REPORTING):
|
||||
huuid = await hass.async_add_job(_load_uuid, hass)
|
||||
huuid = await hass.helpers.instance_id.async_get()
|
||||
else:
|
||||
huuid = None
|
||||
|
||||
|
@ -7,7 +7,6 @@ import uuid
|
||||
import attr
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.loader import bind_hass
|
||||
|
||||
from .singleton import singleton
|
||||
from .typing import HomeAssistantType
|
||||
@ -367,7 +366,6 @@ class DeviceRegistry:
|
||||
self._async_update_device(dev_id, area_id=None)
|
||||
|
||||
|
||||
@bind_hass
|
||||
@singleton(DATA_REGISTRY)
|
||||
async def async_get_registry(hass: HomeAssistantType) -> DeviceRegistry:
|
||||
"""Create entity registry."""
|
||||
|
@ -34,7 +34,6 @@ from homeassistant.const import (
|
||||
)
|
||||
from homeassistant.core import Event, callback, split_entity_id, valid_entity_id
|
||||
from homeassistant.helpers.device_registry import EVENT_DEVICE_REGISTRY_UPDATED
|
||||
from homeassistant.loader import bind_hass
|
||||
from homeassistant.util import slugify
|
||||
from homeassistant.util.yaml import load_yaml
|
||||
|
||||
@ -491,7 +490,6 @@ class EntityRegistry:
|
||||
self.async_remove(entity_id)
|
||||
|
||||
|
||||
@bind_hass
|
||||
@singleton(DATA_REGISTRY)
|
||||
async def async_get_registry(hass: HomeAssistantType) -> EntityRegistry:
|
||||
"""Create entity registry."""
|
||||
|
31
homeassistant/helpers/instance_id.py
Normal file
31
homeassistant/helpers/instance_id.py
Normal file
@ -0,0 +1,31 @@
|
||||
"""Helper to create a unique instance ID."""
|
||||
from typing import Dict, Optional
|
||||
import uuid
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import singleton, storage
|
||||
|
||||
DATA_KEY = "core.uuid"
|
||||
DATA_VERSION = 1
|
||||
|
||||
LEGACY_UUID_FILE = ".uuid"
|
||||
|
||||
|
||||
@singleton.singleton(DATA_KEY)
|
||||
async def async_get(hass: HomeAssistant) -> str:
|
||||
"""Get unique ID for the hass instance."""
|
||||
store = storage.Store(hass, DATA_VERSION, DATA_KEY, True)
|
||||
|
||||
data: Optional[Dict[str, str]] = await storage.async_migrator( # type: ignore
|
||||
hass, hass.config.path(LEGACY_UUID_FILE), store,
|
||||
)
|
||||
|
||||
if data is not None:
|
||||
return data["uuid"]
|
||||
|
||||
data = {"uuid": uuid.uuid4().hex}
|
||||
|
||||
await store.async_save(data)
|
||||
|
||||
return data["uuid"]
|
@ -4,6 +4,7 @@ import functools
|
||||
from typing import Awaitable, Callable, TypeVar, cast
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.loader import bind_hass
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@ -19,6 +20,7 @@ def singleton(data_key: str) -> Callable[[FUNC], FUNC]:
|
||||
def wrapper(func: FUNC) -> FUNC:
|
||||
"""Wrap a function with caching logic."""
|
||||
|
||||
@bind_hass
|
||||
@functools.wraps(func)
|
||||
async def wrapped(hass: HomeAssistant) -> T:
|
||||
obj_or_evt = hass.data.get(data_key)
|
||||
|
@ -20,29 +20,32 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@bind_hass
|
||||
async def async_migrator(
|
||||
hass,
|
||||
old_path,
|
||||
store,
|
||||
*,
|
||||
old_conf_load_func=json_util.load_json,
|
||||
old_conf_migrate_func=None,
|
||||
hass, old_path, store, *, old_conf_load_func=None, old_conf_migrate_func=None,
|
||||
):
|
||||
"""Migrate old data to a store and then load data.
|
||||
|
||||
async def old_conf_migrate_func(old_data)
|
||||
"""
|
||||
store_data = await store.async_load()
|
||||
|
||||
# If we already have store data we have already migrated in the past.
|
||||
if store_data is not None:
|
||||
return store_data
|
||||
|
||||
def load_old_config():
|
||||
"""Load old config."""
|
||||
if not os.path.isfile(old_path):
|
||||
return None
|
||||
|
||||
return old_conf_load_func(old_path)
|
||||
if old_conf_load_func is not None:
|
||||
return old_conf_load_func(old_path)
|
||||
|
||||
return json_util.load_json(old_path)
|
||||
|
||||
config = await hass.async_add_executor_job(load_old_config)
|
||||
|
||||
if config is None:
|
||||
return await store.async_load()
|
||||
return None
|
||||
|
||||
if old_conf_migrate_func is not None:
|
||||
config = await old_conf_migrate_func(config)
|
||||
|
@ -37,7 +37,7 @@ def mock_get_newest_version_fixture():
|
||||
@pytest.fixture(name="mock_get_uuid", autouse=True)
|
||||
def mock_get_uuid_fixture():
|
||||
"""Fixture to mock get_uuid."""
|
||||
with patch("homeassistant.components.updater._load_uuid") as mock:
|
||||
with patch("homeassistant.helpers.instance_id.async_get") as mock:
|
||||
yield mock
|
||||
|
||||
|
||||
|
26
tests/helpers/test_instance_id.py
Normal file
26
tests/helpers/test_instance_id.py
Normal file
@ -0,0 +1,26 @@
|
||||
"""Tests for instance ID helper."""
|
||||
from tests.async_mock import patch
|
||||
|
||||
|
||||
async def test_get_id_empty(hass, hass_storage):
|
||||
"""Get unique ID."""
|
||||
uuid = await hass.helpers.instance_id.async_get()
|
||||
assert uuid is not None
|
||||
# Assert it's stored
|
||||
assert hass_storage["core.uuid"]["data"]["uuid"] == uuid
|
||||
|
||||
|
||||
async def test_get_id_migrate(hass, hass_storage):
|
||||
"""Migrate existing file."""
|
||||
with patch(
|
||||
"homeassistant.util.json.load_json", return_value={"uuid": "1234"}
|
||||
), patch("os.path.isfile", return_value=True), patch("os.remove") as mock_remove:
|
||||
uuid = await hass.helpers.instance_id.async_get()
|
||||
|
||||
assert uuid == "1234"
|
||||
|
||||
# Assert it's stored
|
||||
assert hass_storage["core.uuid"]["data"]["uuid"] == uuid
|
||||
|
||||
# assert old deleted
|
||||
assert len(mock_remove.mock_calls) == 1
|
Loading…
x
Reference in New Issue
Block a user