Update docstrings, comments and log messages (#707)

This commit is contained in:
Fabian Affolter
2018-09-18 23:47:47 +02:00
committed by GitHub
parent 67dcf1563b
commit 267791833e
46 changed files with 370 additions and 372 deletions

View File

@@ -1,4 +1,4 @@
"""Init file for HassIO addons."""
"""Init file for Hass.io add-ons."""
from contextlib import suppress
from copy import deepcopy
import logging
@@ -43,7 +43,7 @@ RE_WEBUI = re.compile(
class Addon(CoreSysAttributes):
"""Hold data for addon inside HassIO."""
"""Hold data for add-on inside Hass.io."""
def __init__(self, coresys, slug):
"""Initialize data holder."""
@@ -59,27 +59,27 @@ class Addon(CoreSysAttributes):
@property
def slug(self):
"""Return slug/id of addon."""
"""Return slug/id of add-on."""
return self._id
@property
def _mesh(self):
"""Return addon data from system or cache."""
"""Return add-on data from system or cache."""
return self._data.system.get(self._id, self._data.cache.get(self._id))
@property
def _data(self):
"""Return addons data storage."""
"""Return add-ons data storage."""
return self.sys_addons.data
@property
def is_installed(self):
"""Return True if an addon is installed."""
"""Return True if an add-on is installed."""
return self._id in self._data.system
@property
def is_detached(self):
"""Return True if addon is detached."""
"""Return True if add-on is detached."""
return self._id not in self._data.cache
@property
@@ -97,19 +97,19 @@ class Addon(CoreSysAttributes):
self._data.save_data()
def _set_uninstall(self):
"""Set addon as uninstalled."""
"""Set add-on as uninstalled."""
self._data.system.pop(self._id, None)
self._data.user.pop(self._id, None)
self._data.save_data()
def _set_update(self, version):
"""Update version of addon."""
"""Update version of add-on."""
self._data.system[self._id] = deepcopy(self._data.cache[self._id])
self._data.user[self._id][ATTR_VERSION] = version
self._data.save_data()
def _restore_data(self, user, system):
"""Restore data to addon."""
"""Restore data to add-on."""
self._data.user[self._id] = deepcopy(user)
self._data.system[self._id] = deepcopy(system)
self._data.save_data()
@@ -126,7 +126,7 @@ class Addon(CoreSysAttributes):
@options.setter
def options(self, value):
"""Store user addon options."""
"""Store user add-on options."""
if value is None:
self._data.user[self._id][ATTR_OPTIONS] = {}
else:
@@ -158,7 +158,7 @@ class Addon(CoreSysAttributes):
@property
def name(self):
"""Return name of addon."""
"""Return name of add-on."""
return self._mesh[ATTR_NAME]
@property
@@ -175,14 +175,14 @@ class Addon(CoreSysAttributes):
@property
def hassio_token(self):
"""Return access token for hass.io API."""
"""Return access token for Hass.io API."""
if self.is_installed:
return self._data.user[self._id].get(ATTR_ACCESS_TOKEN)
return None
@property
def description(self):
"""Return description of addon."""
"""Return description of add-on."""
return self._mesh[ATTR_DESCRIPTON]
@property
@@ -200,31 +200,31 @@ class Addon(CoreSysAttributes):
@property
def repository(self):
"""Return repository of addon."""
"""Return repository of add-on."""
return self._mesh[ATTR_REPOSITORY]
@property
def last_version(self):
"""Return version of addon."""
"""Return version of add-on."""
if self._id in self._data.cache:
return self._data.cache[self._id][ATTR_VERSION]
return self.version_installed
@property
def protected(self):
"""Return if addon is in protected mode."""
"""Return if add-on is in protected mode."""
if self.is_installed:
return self._data.user[self._id][ATTR_PROTECTED]
return True
@protected.setter
def protected(self, value):
"""Set addon in protected mode."""
"""Set add-on in protected mode."""
self._data.user[self._id][ATTR_PROTECTED] = value
@property
def startup(self):
"""Return startup type of addon."""
"""Return startup type of add-on."""
return self._mesh.get(ATTR_STARTUP)
@property
@@ -249,7 +249,7 @@ class Addon(CoreSysAttributes):
@property
def ports(self):
"""Return ports of addon."""
"""Return ports of add-on."""
if self.host_network or ATTR_PORTS not in self._mesh:
return None
@@ -260,7 +260,7 @@ class Addon(CoreSysAttributes):
@ports.setter
def ports(self, value):
"""Set custom ports of addon."""
"""Set custom ports of add-on."""
if value is None:
self._data.user[self._id].pop(ATTR_NETWORK, None)
else:
@@ -304,42 +304,42 @@ class Addon(CoreSysAttributes):
@property
def host_network(self):
"""Return True if addon run on host network."""
"""Return True if add-on run on host network."""
return self._mesh[ATTR_HOST_NETWORK]
@property
def host_pid(self):
"""Return True if addon run on host PID namespace."""
"""Return True if add-on run on host PID namespace."""
return self._mesh[ATTR_HOST_PID]
@property
def host_ipc(self):
"""Return True if addon run on host IPC namespace."""
"""Return True if add-on run on host IPC namespace."""
return self._mesh[ATTR_HOST_IPC]
@property
def host_dbus(self):
"""Return True if addon run on host DBUS."""
"""Return True if add-on run on host D-BUS."""
return self._mesh[ATTR_HOST_DBUS]
@property
def devices(self):
"""Return devices of addon."""
"""Return devices of add-on."""
return self._mesh.get(ATTR_DEVICES)
@property
def auto_uart(self):
"""Return True if we should map all uart device."""
"""Return True if we should map all UART device."""
return self._mesh.get(ATTR_AUTO_UART)
@property
def tmpfs(self):
"""Return tmpfs of addon."""
"""Return tmpfs of add-on."""
return self._mesh.get(ATTR_TMPFS)
@property
def environment(self):
"""Return environment of addon."""
"""Return environment of add-on."""
return self._mesh.get(ATTR_ENVIRONMENT)
@property
@@ -349,7 +349,7 @@ class Addon(CoreSysAttributes):
@property
def apparmor(self):
"""Return True if apparmor is enabled."""
"""Return True if AppArmor is enabled."""
if not self._mesh.get(ATTR_APPARMOR):
return SECURITY_DISABLE
elif self.sys_host.apparmor.exists(self.slug):
@@ -358,22 +358,22 @@ class Addon(CoreSysAttributes):
@property
def legacy(self):
"""Return if the add-on don't support hass labels."""
"""Return if the add-on don't support Home Assistant labels."""
return self._mesh.get(ATTR_LEGACY)
@property
def access_docker_api(self):
"""Return if the add-on need read-only docker API access."""
"""Return if the add-on need read-only Docker API access."""
return self._mesh.get(ATTR_DOCKER_API)
@property
def access_hassio_api(self):
"""Return True if the add-on access to hassio api."""
"""Return True if the add-on access to Hass.io REASTful API."""
return self._mesh[ATTR_HASSIO_API]
@property
def access_homeassistant_api(self):
"""Return True if the add-on access to Home-Assistant api proxy."""
"""Return True if the add-on access to Home Assistant API proxy."""
return self._mesh[ATTR_HOMEASSISTANT_API]
@property
@@ -388,7 +388,7 @@ class Addon(CoreSysAttributes):
@property
def with_gpio(self):
"""Return True if the add-on access to gpio interface."""
"""Return True if the add-on access to GPIO interface."""
return self._mesh[ATTR_GPIO]
@property
@@ -445,7 +445,7 @@ class Addon(CoreSysAttributes):
@property
def url(self):
"""Return url of addon."""
"""Return URL of add-on."""
return self._mesh.get(ATTR_URL)
@property
@@ -470,10 +470,10 @@ class Addon(CoreSysAttributes):
@property
def image(self):
"""Return image name of addon."""
"""Return image name of add-on."""
addon_data = self._mesh
# Repository with dockerhub images
# Repository with Dockerhub images
if ATTR_IMAGE in addon_data:
return addon_data[ATTR_IMAGE].format(arch=self.sys_arch)
@@ -484,12 +484,12 @@ class Addon(CoreSysAttributes):
@property
def need_build(self):
"""Return True if this addon need a local build."""
"""Return True if this add-on need a local build."""
return ATTR_IMAGE not in self._mesh
@property
def map_volumes(self):
"""Return a dict of {volume: policy} from addon."""
"""Return a dict of {volume: policy} from add-on."""
volumes = {}
for volume in self._mesh[ATTR_MAP]:
result = RE_VOLUME.match(volume)
@@ -499,37 +499,37 @@ class Addon(CoreSysAttributes):
@property
def path_data(self):
"""Return addon data path inside supervisor."""
"""Return add-on data path inside Supervisor."""
return Path(self.sys_config.path_addons_data, self._id)
@property
def path_extern_data(self):
"""Return addon data path external for docker."""
"""Return add-on data path external for Docker."""
return PurePath(self.sys_config.path_extern_addons_data, self._id)
@property
def path_options(self):
"""Return path to addons options."""
"""Return path to add-on options."""
return Path(self.path_data, "options.json")
@property
def path_location(self):
"""Return path to this addon."""
"""Return path to this add-on."""
return Path(self._mesh[ATTR_LOCATON])
@property
def path_icon(self):
"""Return path to addon icon."""
"""Return path to add-on icon."""
return Path(self.path_location, 'icon.png')
@property
def path_logo(self):
"""Return path to addon logo."""
"""Return path to add-on logo."""
return Path(self.path_location, 'logo.png')
@property
def path_changelog(self):
"""Return path to addon changelog."""
"""Return path to add-on changelog."""
return Path(self.path_location, 'CHANGELOG.md')
@property
@@ -544,15 +544,15 @@ class Addon(CoreSysAttributes):
@property
def path_extern_asound(self):
"""Return path to asound config for docker."""
"""Return path to asound config for Docker."""
return Path(self.sys_config.path_extern_tmp, f"{self.slug}_asound")
def save_data(self):
"""Save data of addon."""
"""Save data of add-on."""
self.sys_addons.data.save_data()
def write_options(self):
"""Return True if addon options is written to data."""
"""Return True if add-on options is written to data."""
schema = self.schema
options = self.options
@@ -560,10 +560,10 @@ class Addon(CoreSysAttributes):
schema(options)
write_json_file(self.path_options, options)
except vol.Invalid as ex:
_LOGGER.error("Addon %s have wrong options: %s", self._id,
_LOGGER.error("Add-on %s have wrong options: %s", self._id,
humanize_error(options, ex))
except (OSError, json.JSONDecodeError) as err:
_LOGGER.error("Addon %s can't write options: %s", self._id, err)
_LOGGER.error("Add-on %s can't write options: %s", self._id, err)
else:
return True
@@ -578,7 +578,7 @@ class Addon(CoreSysAttributes):
with self.path_asound.open('w') as config_file:
config_file.write(asound_config)
except OSError as err:
_LOGGER.error("Addon %s can't write asound: %s", self._id, err)
_LOGGER.error("Add-on %s can't write asound: %s", self._id, err)
return False
return True
@@ -606,7 +606,7 @@ class Addon(CoreSysAttributes):
@property
def schema(self):
"""Create a schema for addon options."""
"""Create a schema for add-on options."""
raw_schema = self._mesh[ATTR_SCHEMA]
if isinstance(raw_schema, bool):
@@ -614,7 +614,7 @@ class Addon(CoreSysAttributes):
return vol.Schema(vol.All(dict, validate_options(raw_schema)))
def test_update_schema(self):
"""Check if the exists config valid after update."""
"""Check if the existing configuration is valid after update."""
if not self.is_installed or self.is_detached:
return True
@@ -644,19 +644,19 @@ class Addon(CoreSysAttributes):
return True
async def install(self):
"""Install an addon."""
"""Install an add-on."""
if self.sys_arch not in self.supported_arch:
_LOGGER.error(
"Addon %s not supported on %s", self._id, self.sys_arch)
"Add-on %s not supported on %s", self._id, self.sys_arch)
return False
if self.is_installed:
_LOGGER.error("Addon %s is already installed", self._id)
_LOGGER.error("Add-on %s is already installed", self._id)
return False
if not self.path_data.is_dir():
_LOGGER.info(
"Create Home-Assistant addon data folder %s", self.path_data)
"Create Home Assistant add-on data folder %s", self.path_data)
self.path_data.mkdir()
# Setup/Fix AppArmor profile
@@ -670,13 +670,13 @@ class Addon(CoreSysAttributes):
@check_installed
async def uninstall(self):
"""Remove an addon."""
"""Remove an add-on."""
if not await self.instance.remove():
return False
if self.path_data.is_dir():
_LOGGER.info(
"Remove Home-Assistant addon data folder %s", self.path_data)
"Remove Home Assistant add-on data folder %s", self.path_data)
await remove_data(self.path_data)
# Cleanup audio settings
@@ -684,7 +684,7 @@ class Addon(CoreSysAttributes):
with suppress(OSError):
self.path_asound.unlink()
# Cleanup apparmor profile
# Cleanup AppArmor profile
if self.sys_host.apparmor.exists(self.slug):
with suppress(HostAppArmorError):
await self.sys_host.apparmor.remove_profile(self.slug)
@@ -693,7 +693,7 @@ class Addon(CoreSysAttributes):
return True
async def state(self):
"""Return running state of addon."""
"""Return running state of add-on."""
if not self.is_installed:
return STATE_NONE
@@ -703,9 +703,9 @@ class Addon(CoreSysAttributes):
@check_installed
async def start(self):
"""Set options and start addon."""
"""Set options and start add-on."""
if await self.instance.is_running():
_LOGGER.warning("%s allready running!", self.slug)
_LOGGER.warning("%s already running!", self.slug)
return
# Access Token
@@ -724,7 +724,7 @@ class Addon(CoreSysAttributes):
@check_installed
def stop(self):
"""Stop addon.
"""Stop add-on.
Return a coroutine.
"""
@@ -732,11 +732,11 @@ class Addon(CoreSysAttributes):
@check_installed
async def update(self):
"""Update addon."""
"""Update add-on."""
last_state = await self.state()
if self.last_version == self.version_installed:
_LOGGER.warning("No update available for Addon %s", self._id)
_LOGGER.warning("No update available for add-on %s", self._id)
return False
if not await self.instance.update(self.last_version):
@@ -753,13 +753,13 @@ class Addon(CoreSysAttributes):
@check_installed
async def restart(self):
"""Restart addon."""
"""Restart add-on."""
await self.stop()
return await self.start()
@check_installed
def logs(self):
"""Return addons log output.
"""Return add-ons log output.
Return a coroutine.
"""
@@ -775,11 +775,11 @@ class Addon(CoreSysAttributes):
@check_installed
async def rebuild(self):
"""Performe a rebuild of local build addon."""
"""Perform a rebuild of local build add-on."""
last_state = await self.state()
if not self.need_build:
_LOGGER.error("Can't rebuild a none local build addon!")
_LOGGER.error("Can't rebuild a none local build add-on!")
return False
# remove docker container but not addon config
@@ -808,7 +808,7 @@ class Addon(CoreSysAttributes):
@check_installed
async def snapshot(self, tar_file):
"""Snapshot state of an addon."""
"""Snapshot state of an add-on."""
with TemporaryDirectory(dir=str(self.sys_config.path_tmp)) as temp:
# store local image
if self.need_build and not await \
@@ -822,7 +822,7 @@ class Addon(CoreSysAttributes):
ATTR_STATE: await self.state(),
}
# store local configs/state
# Store local configs/state
try:
write_json_file(Path(temp, 'addon.json'), data)
except (OSError, json.JSONDecodeError) as err:
@@ -846,7 +846,7 @@ class Addon(CoreSysAttributes):
snapshot.add(self.path_data, arcname="data")
try:
_LOGGER.info("Build snapshot for addon %s", self._id)
_LOGGER.info("Build snapshot for add-on %s", self._id)
await self.sys_run_in_executor(_write_tarfile)
except (tarfile.TarError, OSError) as err:
_LOGGER.error("Can't write tarfile %s: %s", tar_file, err)
@@ -856,7 +856,7 @@ class Addon(CoreSysAttributes):
return True
async def restore(self, tar_file):
"""Restore state of an addon."""
"""Restore state of an add-on."""
with TemporaryDirectory(dir=str(self.sys_config.path_tmp)) as temp:
# extract snapshot
def _extract_tarfile():
@@ -870,13 +870,13 @@ class Addon(CoreSysAttributes):
_LOGGER.error("Can't read tarfile %s: %s", tar_file, err)
return False
# read snapshot data
# Read snapshot data
try:
data = read_json_file(Path(temp, 'addon.json'))
except (OSError, json.JSONDecodeError) as err:
_LOGGER.error("Can't read addon.json: %s", err)
# validate
# Validate
try:
data = SCHEMA_ADDON_SNAPSHOT(data)
except vol.Invalid as err:
@@ -884,11 +884,11 @@ class Addon(CoreSysAttributes):
self._id, humanize_error(data, err))
return False
# restore data / reload addon
# Restore data or reload add-on
_LOGGER.info("Restore config for addon %s", self._id)
self._restore_data(data[ATTR_USER], data[ATTR_SYSTEM])
# check version / restore image
# Check version / restore image
version = data[ATTR_VERSION]
if not await self.instance.exists():
_LOGGER.info("Restore image for addon %s", self._id)
@@ -902,7 +902,7 @@ class Addon(CoreSysAttributes):
else:
await self.instance.stop()
# restore data
# Restore data
def _restore_data():
"""Restore data."""
shutil.copytree(str(Path(temp, "data")), str(self.path_data))
@@ -926,9 +926,9 @@ class Addon(CoreSysAttributes):
_LOGGER.error("Can't restore AppArmor profile")
return False
# run addon
# Run add-on
if data[ATTR_STATE] == STATE_STARTED:
return await self.start()
_LOGGER.info("Finish restore for addon %s", self._id)
_LOGGER.info("Finish restore for add-on %s", self._id)
return True