mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-27 11:06:32 +00:00
commit
1dc9f35e12
@ -2,7 +2,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ipaddress import ip_network
|
from ipaddress import ip_network
|
||||||
|
|
||||||
HASSIO_VERSION = '127'
|
HASSIO_VERSION = '128'
|
||||||
|
|
||||||
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"
|
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"
|
||||||
URL_HASSIO_VERSION = \
|
URL_HASSIO_VERSION = \
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""HomeAssistant control object."""
|
"""HomeAssistant control object."""
|
||||||
import asyncio
|
import asyncio
|
||||||
from contextlib import asynccontextmanager, suppress
|
from contextlib import asynccontextmanager, suppress
|
||||||
|
from datetime import datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@ -46,6 +47,7 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
|
|||||||
self._error_state = False
|
self._error_state = False
|
||||||
# We don't persist access tokens. Instead we fetch new ones when needed
|
# We don't persist access tokens. Instead we fetch new ones when needed
|
||||||
self.access_token = None
|
self.access_token = None
|
||||||
|
self._access_token_expires = None
|
||||||
|
|
||||||
async def load(self):
|
async def load(self):
|
||||||
"""Prepare HomeAssistant object."""
|
"""Prepare HomeAssistant object."""
|
||||||
@ -352,7 +354,8 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
|
|||||||
|
|
||||||
async def ensure_access_token(self):
|
async def ensure_access_token(self):
|
||||||
"""Ensures there is an access token."""
|
"""Ensures there is an access token."""
|
||||||
if self.access_token is not None:
|
if (self.access_token is not None and
|
||||||
|
self._access_token_expires > datetime.utcnow()):
|
||||||
return
|
return
|
||||||
|
|
||||||
with suppress(asyncio.TimeoutError, aiohttp.ClientError):
|
with suppress(asyncio.TimeoutError, aiohttp.ClientError):
|
||||||
@ -364,14 +367,15 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
|
|||||||
"refresh_token": self.refresh_token
|
"refresh_token": self.refresh_token
|
||||||
}
|
}
|
||||||
) as resp:
|
) as resp:
|
||||||
if resp.status == 200:
|
if resp.status != 200:
|
||||||
_LOGGER.info("Updated HomeAssistant API token")
|
_LOGGER.error("Can't update HomeAssistant access token!")
|
||||||
tokens = await resp.json()
|
raise HomeAssistantAuthError()
|
||||||
self.access_token = tokens['access_token']
|
|
||||||
return
|
|
||||||
|
|
||||||
_LOGGER.error("Can't update HomeAssistant access token!")
|
_LOGGER.info("Updated HomeAssistant API token")
|
||||||
raise HomeAssistantAuthError()
|
tokens = await resp.json()
|
||||||
|
self.access_token = tokens['access_token']
|
||||||
|
self._access_token_expires = \
|
||||||
|
datetime.utcnow() + timedelta(seconds=tokens['expires_in'])
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def make_request(self, method, path, json=None, content_type=None,
|
async def make_request(self, method, path, json=None, content_type=None,
|
||||||
|
@ -293,6 +293,7 @@ class SnapshotManager(CoreSysAttributes):
|
|||||||
# Stop Home-Assistant if they will be restored later
|
# Stop Home-Assistant if they will be restored later
|
||||||
if homeassistant and FOLDER_HOMEASSISTANT in folders:
|
if homeassistant and FOLDER_HOMEASSISTANT in folders:
|
||||||
await self.sys_homeassistant.stop()
|
await self.sys_homeassistant.stop()
|
||||||
|
snapshot.restore_homeassistant()
|
||||||
|
|
||||||
# Process folders
|
# Process folders
|
||||||
if folders:
|
if folders:
|
||||||
@ -304,7 +305,6 @@ class SnapshotManager(CoreSysAttributes):
|
|||||||
if homeassistant:
|
if homeassistant:
|
||||||
_LOGGER.info("Restore %s run Home-Assistant",
|
_LOGGER.info("Restore %s run Home-Assistant",
|
||||||
snapshot.slug)
|
snapshot.slug)
|
||||||
snapshot.restore_homeassistant()
|
|
||||||
task_hass = self.sys_create_task(
|
task_hass = self.sys_create_task(
|
||||||
self.sys_homeassistant.update(
|
self.sys_homeassistant.update(
|
||||||
snapshot.homeassistant_version))
|
snapshot.homeassistant_version))
|
||||||
@ -322,12 +322,20 @@ class SnapshotManager(CoreSysAttributes):
|
|||||||
_LOGGER.info("Restore %s old add-ons", snapshot.slug)
|
_LOGGER.info("Restore %s old add-ons", snapshot.slug)
|
||||||
await snapshot.restore_addons(addon_list)
|
await snapshot.restore_addons(addon_list)
|
||||||
|
|
||||||
# make sure homeassistant run agen
|
# Make sure homeassistant run agen
|
||||||
if task_hass:
|
if task_hass:
|
||||||
_LOGGER.info("Restore %s wait for Home-Assistant",
|
_LOGGER.info("Restore %s wait for Home-Assistant",
|
||||||
snapshot.slug)
|
snapshot.slug)
|
||||||
await task_hass
|
await task_hass
|
||||||
await self.sys_homeassistant.start()
|
|
||||||
|
# Do we need start HomeAssistant?
|
||||||
|
if not await self.sys_homeassistant.is_running():
|
||||||
|
await self.sys_homeassistant.start()
|
||||||
|
|
||||||
|
# Check If we can access to API / otherwise restart
|
||||||
|
if not await self.sys_homeassistant.check_api_state():
|
||||||
|
_LOGGER.warning("Need restart HomeAssistant for API")
|
||||||
|
await self.sys_homeassistant.restart()
|
||||||
|
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
_LOGGER.exception("Restore %s error", snapshot.slug)
|
_LOGGER.exception("Restore %s error", snapshot.slug)
|
||||||
|
@ -20,7 +20,7 @@ from ..const import (
|
|||||||
ATTR_HOMEASSISTANT, ATTR_FOLDERS, ATTR_VERSION, ATTR_TYPE, ATTR_IMAGE,
|
ATTR_HOMEASSISTANT, ATTR_FOLDERS, ATTR_VERSION, ATTR_TYPE, ATTR_IMAGE,
|
||||||
ATTR_PORT, ATTR_SSL, ATTR_PASSWORD, ATTR_WATCHDOG, ATTR_BOOT, ATTR_CRYPTO,
|
ATTR_PORT, ATTR_SSL, ATTR_PASSWORD, ATTR_WATCHDOG, ATTR_BOOT, ATTR_CRYPTO,
|
||||||
ATTR_LAST_VERSION, ATTR_PROTECTED, ATTR_WAIT_BOOT, ATTR_SIZE,
|
ATTR_LAST_VERSION, ATTR_PROTECTED, ATTR_WAIT_BOOT, ATTR_SIZE,
|
||||||
CRYPTO_AES128)
|
ATTR_REFRESH_TOKEN, CRYPTO_AES128)
|
||||||
from ..coresys import CoreSysAttributes
|
from ..coresys import CoreSysAttributes
|
||||||
from ..utils.json import write_json_file
|
from ..utils.json import write_json_file
|
||||||
from ..utils.tar import SecureTarFile
|
from ..utils.tar import SecureTarFile
|
||||||
@ -387,6 +387,8 @@ class Snapshot(CoreSysAttributes):
|
|||||||
# API/Proxy
|
# API/Proxy
|
||||||
self.homeassistant[ATTR_PORT] = self.sys_homeassistant.api_port
|
self.homeassistant[ATTR_PORT] = self.sys_homeassistant.api_port
|
||||||
self.homeassistant[ATTR_SSL] = self.sys_homeassistant.api_ssl
|
self.homeassistant[ATTR_SSL] = self.sys_homeassistant.api_ssl
|
||||||
|
self.homeassistant[ATTR_REFRESH_TOKEN] = \
|
||||||
|
self._encrypt_data(self.sys_homeassistant.refresh_token)
|
||||||
self.homeassistant[ATTR_PASSWORD] = \
|
self.homeassistant[ATTR_PASSWORD] = \
|
||||||
self._encrypt_data(self.sys_homeassistant.api_password)
|
self._encrypt_data(self.sys_homeassistant.api_password)
|
||||||
|
|
||||||
@ -405,6 +407,8 @@ class Snapshot(CoreSysAttributes):
|
|||||||
# API/Proxy
|
# API/Proxy
|
||||||
self.sys_homeassistant.api_port = self.homeassistant[ATTR_PORT]
|
self.sys_homeassistant.api_port = self.homeassistant[ATTR_PORT]
|
||||||
self.sys_homeassistant.api_ssl = self.homeassistant[ATTR_SSL]
|
self.sys_homeassistant.api_ssl = self.homeassistant[ATTR_SSL]
|
||||||
|
self.sys_homeassistant.refresh_token = \
|
||||||
|
self._decrypt_data(self.homeassistant[ATTR_REFRESH_TOKEN])
|
||||||
self.sys_homeassistant.api_password = \
|
self.sys_homeassistant.api_password = \
|
||||||
self._decrypt_data(self.homeassistant[ATTR_PASSWORD])
|
self._decrypt_data(self.homeassistant[ATTR_PASSWORD])
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ from ..const import (
|
|||||||
ATTR_VERSION, ATTR_HOMEASSISTANT, ATTR_FOLDERS, ATTR_TYPE, ATTR_IMAGE,
|
ATTR_VERSION, ATTR_HOMEASSISTANT, ATTR_FOLDERS, ATTR_TYPE, ATTR_IMAGE,
|
||||||
ATTR_PASSWORD, ATTR_PORT, ATTR_SSL, ATTR_WATCHDOG, ATTR_BOOT, ATTR_SIZE,
|
ATTR_PASSWORD, ATTR_PORT, ATTR_SSL, ATTR_WATCHDOG, ATTR_BOOT, ATTR_SIZE,
|
||||||
ATTR_LAST_VERSION, ATTR_WAIT_BOOT, ATTR_PROTECTED, ATTR_CRYPTO,
|
ATTR_LAST_VERSION, ATTR_WAIT_BOOT, ATTR_PROTECTED, ATTR_CRYPTO,
|
||||||
|
ATTR_REFRESH_TOKEN,
|
||||||
FOLDER_SHARE, FOLDER_HOMEASSISTANT, FOLDER_ADDONS, FOLDER_SSL,
|
FOLDER_SHARE, FOLDER_HOMEASSISTANT, FOLDER_ADDONS, FOLDER_SSL,
|
||||||
SNAPSHOT_FULL, SNAPSHOT_PARTIAL, CRYPTO_AES128)
|
SNAPSHOT_FULL, SNAPSHOT_PARTIAL, CRYPTO_AES128)
|
||||||
from ..validate import NETWORK_PORT, REPOSITORIES, DOCKER_IMAGE
|
from ..validate import NETWORK_PORT, REPOSITORIES, DOCKER_IMAGE
|
||||||
@ -40,6 +41,7 @@ SCHEMA_SNAPSHOT = vol.Schema({
|
|||||||
vol.Optional(ATTR_SSL, default=False): vol.Boolean(),
|
vol.Optional(ATTR_SSL, default=False): vol.Boolean(),
|
||||||
vol.Optional(ATTR_PORT, default=8123): NETWORK_PORT,
|
vol.Optional(ATTR_PORT, default=8123): NETWORK_PORT,
|
||||||
vol.Optional(ATTR_PASSWORD): vol.Maybe(vol.Coerce(str)),
|
vol.Optional(ATTR_PASSWORD): vol.Maybe(vol.Coerce(str)),
|
||||||
|
vol.Optional(ATTR_REFRESH_TOKEN): vol.Maybe(vol.Coerce(str)),
|
||||||
vol.Optional(ATTR_WATCHDOG, default=True): vol.Boolean(),
|
vol.Optional(ATTR_WATCHDOG, default=True): vol.Boolean(),
|
||||||
vol.Optional(ATTR_WAIT_BOOT, default=600):
|
vol.Optional(ATTR_WAIT_BOOT, default=600):
|
||||||
vol.All(vol.Coerce(int), vol.Range(min=60)),
|
vol.All(vol.Coerce(int), vol.Range(min=60)),
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
attr==0.3.1
|
attr==0.3.1
|
||||||
async_timeout==3.0.0
|
async_timeout==3.0.0
|
||||||
aiohttp==3.3.2
|
aiohttp==3.4.0
|
||||||
docker==3.5.0
|
docker==3.5.0
|
||||||
colorlog==3.1.2
|
colorlog==3.1.2
|
||||||
voluptuous==0.11.5
|
voluptuous==0.11.5
|
||||||
gitpython==2.1.10
|
gitpython==2.1.10
|
||||||
pytz==2018.4
|
pytz==2018.4
|
||||||
pyudev==0.21.0
|
pyudev==0.21.0
|
||||||
pycryptodome==3.6.4
|
pycryptodome==3.6.6
|
||||||
cpe==1.2.1
|
cpe==1.2.1
|
||||||
uvloop==0.11.2
|
uvloop==0.11.2
|
||||||
cchardet==2.1.1
|
cchardet==2.1.1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user