Merge pull request #890 from home-assistant/dev

Release 142
This commit is contained in:
Pascal Vizeli 2019-01-15 12:10:58 +01:00 committed by GitHub
commit 3974d5859f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 278 additions and 286 deletions

View File

@ -13,12 +13,6 @@
- Or use this command: hass --version - Or use this command: hass --version
--> -->
**Home Assistant release with the issue:**
<!--
- Frontend -> Developer tools -> Info
- Or use this command: hass --version
-->
**Operating environment (HassOS/Generic):** **Operating environment (HassOS/Generic):**
<!-- <!--
Please provide details about your environment. Please provide details about your environment.

12
API.md
View File

@ -314,9 +314,10 @@ Load host configs from a USB stick.
"CARD_ID": { "CARD_ID": {
"name": "xy", "name": "xy",
"type": "microphone", "type": "microphone",
"devices": { "devices": [
"DEV_ID": "type of device" "chan_id": "channel ID",
} "chan_type": "type of device"
]
} }
} }
} }
@ -352,7 +353,7 @@ Load host configs from a USB stick.
"port": 8123, "port": 8123,
"ssl": "bool", "ssl": "bool",
"watchdog": "bool", "watchdog": "bool",
"startup_time": 600 "wait_boot": 600
} }
``` ```
@ -386,7 +387,7 @@ Output is the raw Docker log.
"password": "", "password": "",
"refresh_token": "", "refresh_token": "",
"watchdog": "bool", "watchdog": "bool",
"startup_time": 600 "wait_boot": 600
} }
``` ```
@ -495,6 +496,7 @@ Get all available addons.
"stdin": "bool", "stdin": "bool",
"webui": "null|http(s)://[HOST]:port/xy/zx", "webui": "null|http(s)://[HOST]:port/xy/zx",
"gpio": "bool", "gpio": "bool",
"kernel_modules": "bool",
"devicetree": "bool", "devicetree": "bool",
"docker_api": "bool", "docker_api": "bool",
"audio": "bool", "audio": "bool",

View File

@ -28,7 +28,7 @@ from ..const import (
ATTR_HOST_DBUS, ATTR_AUTO_UART, ATTR_DISCOVERY, ATTR_SERVICES, ATTR_HOST_DBUS, ATTR_AUTO_UART, ATTR_DISCOVERY, ATTR_SERVICES,
ATTR_APPARMOR, ATTR_DEVICETREE, ATTR_DOCKER_API, ATTR_FULL_ACCESS, ATTR_APPARMOR, ATTR_DEVICETREE, ATTR_DOCKER_API, ATTR_FULL_ACCESS,
ATTR_PROTECTED, ATTR_ACCESS_TOKEN, ATTR_HOST_PID, ATTR_HASSIO_ROLE, ATTR_PROTECTED, ATTR_ACCESS_TOKEN, ATTR_HOST_PID, ATTR_HASSIO_ROLE,
ATTR_MACHINE, ATTR_AUTH_API, ATTR_MACHINE, ATTR_AUTH_API, ATTR_KERNEL_MODULES,
SECURITY_PROFILE, SECURITY_DISABLE, SECURITY_DEFAULT) SECURITY_PROFILE, SECURITY_DISABLE, SECURITY_DEFAULT)
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..docker.addon import DockerAddon from ..docker.addon import DockerAddon
@ -401,6 +401,11 @@ class Addon(CoreSysAttributes):
"""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] return self._mesh[ATTR_GPIO]
@property
def with_kernel_modules(self):
"""Return True if the add-on access to kernel modules."""
return self._mesh[ATTR_KERNEL_MODULES]
@property @property
def with_full_access(self): def with_full_access(self):
"""Return True if the add-on want full access to hardware.""" """Return True if the add-on want full access to hardware."""

View File

@ -20,7 +20,6 @@ class AddonBuild(JsonConfig, CoreSysAttributes):
def save_data(self): def save_data(self):
"""Ignore save function.""" """Ignore save function."""
pass
@property @property
def addon(self): def addon(self):

View File

@ -7,7 +7,8 @@ import re
from ..const import ( from ..const import (
SECURITY_DISABLE, SECURITY_PROFILE, PRIVILEGED_NET_ADMIN, SECURITY_DISABLE, SECURITY_PROFILE, PRIVILEGED_NET_ADMIN,
PRIVILEGED_SYS_ADMIN, PRIVILEGED_SYS_RAWIO, PRIVILEGED_SYS_PTRACE, PRIVILEGED_SYS_ADMIN, PRIVILEGED_SYS_RAWIO, PRIVILEGED_SYS_PTRACE,
PRIVILEGED_DAC_READ_SEARCH, ROLE_ADMIN, ROLE_MANAGER) PRIVILEGED_DAC_READ_SEARCH, PRIVILEGED_SYS_MODULE, ROLE_ADMIN,
ROLE_MANAGER)
RE_SHA1 = re.compile(r"[a-f0-9]{8}") RE_SHA1 = re.compile(r"[a-f0-9]{8}")
@ -33,10 +34,17 @@ def rating_security(addon):
rating += 1 rating += 1
# Privileged options # Privileged options
if any(privilege in addon.privileged if any(
for privilege in (PRIVILEGED_NET_ADMIN, PRIVILEGED_SYS_ADMIN, privilege in addon.privileged
PRIVILEGED_SYS_RAWIO, PRIVILEGED_SYS_PTRACE, for privilege in (
PRIVILEGED_DAC_READ_SEARCH)): PRIVILEGED_NET_ADMIN,
PRIVILEGED_SYS_ADMIN,
PRIVILEGED_SYS_RAWIO,
PRIVILEGED_SYS_PTRACE,
PRIVILEGED_SYS_MODULE,
PRIVILEGED_DAC_READ_SEARCH,
)
):
rating += -1 rating += -1
# API Hass.io role # API Hass.io role
@ -81,6 +89,7 @@ def extract_hash_from_path(path):
def check_installed(method): def check_installed(method):
"""Wrap function with check if add-on is installed.""" """Wrap function with check if add-on is installed."""
async def wrap_check(addon, *args, **kwargs): async def wrap_check(addon, *args, **kwargs):
"""Return False if not installed or the function.""" """Return False if not installed or the function."""
if not addon.is_installed: if not addon.is_installed:
@ -95,8 +104,7 @@ async def remove_data(folder):
"""Remove folder and reset privileged.""" """Remove folder and reset privileged."""
try: try:
proc = await asyncio.create_subprocess_exec( proc = await asyncio.create_subprocess_exec(
"rm", "-rf", str(folder), "rm", "-rf", str(folder), stdout=asyncio.subprocess.DEVNULL
stdout=asyncio.subprocess.DEVNULL
) )
_, error_msg = await proc.communicate() _, error_msg = await proc.communicate()

View File

@ -20,11 +20,12 @@ from ..const import (
ATTR_HOST_DBUS, ATTR_AUTO_UART, ATTR_SERVICES, ATTR_DISCOVERY, ATTR_HOST_DBUS, ATTR_AUTO_UART, ATTR_SERVICES, ATTR_DISCOVERY,
ATTR_APPARMOR, ATTR_DEVICETREE, ATTR_DOCKER_API, ATTR_PROTECTED, ATTR_APPARMOR, ATTR_DEVICETREE, ATTR_DOCKER_API, ATTR_PROTECTED,
ATTR_FULL_ACCESS, ATTR_ACCESS_TOKEN, ATTR_HOST_PID, ATTR_HASSIO_ROLE, ATTR_FULL_ACCESS, ATTR_ACCESS_TOKEN, ATTR_HOST_PID, ATTR_HASSIO_ROLE,
ATTR_MACHINE, ATTR_AUTH_API, ATTR_MACHINE, ATTR_AUTH_API, ATTR_KERNEL_MODULES,
PRIVILEGED_NET_ADMIN, PRIVILEGED_SYS_ADMIN, PRIVILEGED_SYS_RAWIO, PRIVILEGED_NET_ADMIN, PRIVILEGED_SYS_ADMIN, PRIVILEGED_SYS_RAWIO,
PRIVILEGED_IPC_LOCK, PRIVILEGED_SYS_TIME, PRIVILEGED_SYS_NICE, PRIVILEGED_IPC_LOCK, PRIVILEGED_SYS_TIME, PRIVILEGED_SYS_NICE,
PRIVILEGED_SYS_RESOURCE, PRIVILEGED_SYS_PTRACE, PRIVILEGED_DAC_READ_SEARCH, PRIVILEGED_SYS_RESOURCE, PRIVILEGED_SYS_PTRACE, PRIVILEGED_DAC_READ_SEARCH,
ROLE_DEFAULT, ROLE_HOMEASSISTANT, ROLE_MANAGER, ROLE_ADMIN, ROLE_BACKUP) PRIVILEGED_SYS_MODULE, ROLE_DEFAULT, ROLE_HOMEASSISTANT, ROLE_MANAGER,
ROLE_ADMIN, ROLE_BACKUP)
from ..validate import ( from ..validate import (
NETWORK_PORT, DOCKER_PORTS, ALSA_DEVICE, UUID_MATCH, SHA256) NETWORK_PORT, DOCKER_PORTS, ALSA_DEVICE, UUID_MATCH, SHA256)
from ..services.validate import DISCOVERY_SERVICES from ..services.validate import DISCOVERY_SERVICES
@ -82,6 +83,7 @@ PRIVILEGED_ALL = [
PRIVILEGED_SYS_NICE, PRIVILEGED_SYS_NICE,
PRIVILEGED_SYS_RESOURCE, PRIVILEGED_SYS_RESOURCE,
PRIVILEGED_SYS_PTRACE, PRIVILEGED_SYS_PTRACE,
PRIVILEGED_SYS_MODULE,
PRIVILEGED_DAC_READ_SEARCH, PRIVILEGED_DAC_READ_SEARCH,
] ]
@ -142,6 +144,7 @@ SCHEMA_ADDON_CONFIG = vol.Schema({
vol.Optional(ATTR_AUDIO, default=False): vol.Boolean(), vol.Optional(ATTR_AUDIO, default=False): vol.Boolean(),
vol.Optional(ATTR_GPIO, default=False): vol.Boolean(), vol.Optional(ATTR_GPIO, default=False): vol.Boolean(),
vol.Optional(ATTR_DEVICETREE, default=False): vol.Boolean(), vol.Optional(ATTR_DEVICETREE, default=False): vol.Boolean(),
vol.Optional(ATTR_KERNEL_MODULES, default=False): vol.Boolean(),
vol.Optional(ATTR_HASSIO_API, default=False): vol.Boolean(), vol.Optional(ATTR_HASSIO_API, default=False): vol.Boolean(),
vol.Optional(ATTR_HASSIO_ROLE, default=ROLE_DEFAULT): vol.In(ROLE_ALL), vol.Optional(ATTR_HASSIO_ROLE, default=ROLE_DEFAULT): vol.In(ROLE_ALL),
vol.Optional(ATTR_HOMEASSISTANT_API, default=False): vol.Boolean(), vol.Optional(ATTR_HOMEASSISTANT_API, default=False): vol.Boolean(),

View File

@ -21,6 +21,7 @@ from ..const import (
ATTR_DISCOVERY, ATTR_APPARMOR, ATTR_DEVICETREE, ATTR_DOCKER_API, ATTR_DISCOVERY, ATTR_APPARMOR, ATTR_DEVICETREE, ATTR_DOCKER_API,
ATTR_FULL_ACCESS, ATTR_PROTECTED, ATTR_RATING, ATTR_HOST_PID, ATTR_FULL_ACCESS, ATTR_PROTECTED, ATTR_RATING, ATTR_HOST_PID,
ATTR_HASSIO_ROLE, ATTR_MACHINE, ATTR_AVAILABLE, ATTR_AUTH_API, ATTR_HASSIO_ROLE, ATTR_MACHINE, ATTR_AVAILABLE, ATTR_AUTH_API,
ATTR_KERNEL_MODULES,
CONTENT_TYPE_PNG, CONTENT_TYPE_BINARY, CONTENT_TYPE_TEXT, REQUEST_FROM) CONTENT_TYPE_PNG, CONTENT_TYPE_BINARY, CONTENT_TYPE_TEXT, REQUEST_FROM)
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..validate import DOCKER_PORTS, ALSA_DEVICE from ..validate import DOCKER_PORTS, ALSA_DEVICE
@ -152,6 +153,7 @@ class APIAddons(CoreSysAttributes):
ATTR_AUTH_API: addon.access_auth_api, ATTR_AUTH_API: addon.access_auth_api,
ATTR_HOMEASSISTANT_API: addon.access_homeassistant_api, ATTR_HOMEASSISTANT_API: addon.access_homeassistant_api,
ATTR_GPIO: addon.with_gpio, ATTR_GPIO: addon.with_gpio,
ATTR_KERNEL_MODULES: addon.with_kernel_modules,
ATTR_DEVICETREE: addon.with_devicetree, ATTR_DEVICETREE: addon.with_devicetree,
ATTR_DOCKER_API: addon.access_docker_api, ATTR_DOCKER_API: addon.access_docker_api,
ATTR_AUDIO: addon.with_audio, ATTR_AUDIO: addon.with_audio,

View File

@ -2,17 +2,16 @@
from pathlib import Path from pathlib import Path
from ipaddress import ip_network from ipaddress import ip_network
HASSIO_VERSION = '141' HASSIO_VERSION = "142"
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 = "https://s3.amazonaws.com/hassio-version/{channel}.json"
"https://s3.amazonaws.com/hassio-version/{channel}.json" URL_HASSIO_APPARMOR = "https://s3.amazonaws.com/hassio-version/apparmor.txt"
URL_HASSIO_APPARMOR = \
"https://s3.amazonaws.com/hassio-version/apparmor.txt"
URL_HASSOS_OTA = ( URL_HASSOS_OTA = (
"https://github.com/home-assistant/hassos/releases/download/" "https://github.com/home-assistant/hassos/releases/download/"
"{version}/hassos_{board}-{version}.raucb") "{version}/hassos_{board}-{version}.raucb"
)
HASSIO_DATA = Path("/data") HASSIO_DATA = Path("/data")
@ -26,239 +25,241 @@ FILE_HASSIO_DISCOVERY = Path(HASSIO_DATA, "discovery.json")
SOCKET_DOCKER = Path("/var/run/docker.sock") SOCKET_DOCKER = Path("/var/run/docker.sock")
DOCKER_NETWORK = 'hassio' DOCKER_NETWORK = "hassio"
DOCKER_NETWORK_MASK = ip_network('172.30.32.0/23') DOCKER_NETWORK_MASK = ip_network("172.30.32.0/23")
DOCKER_NETWORK_RANGE = ip_network('172.30.33.0/24') DOCKER_NETWORK_RANGE = ip_network("172.30.33.0/24")
LABEL_VERSION = 'io.hass.version' LABEL_VERSION = "io.hass.version"
LABEL_ARCH = 'io.hass.arch' LABEL_ARCH = "io.hass.arch"
LABEL_TYPE = 'io.hass.type' LABEL_TYPE = "io.hass.type"
LABEL_MACHINE = 'io.hass.machine' LABEL_MACHINE = "io.hass.machine"
META_ADDON = 'addon' META_ADDON = "addon"
META_SUPERVISOR = 'supervisor' META_SUPERVISOR = "supervisor"
META_HOMEASSISTANT = 'homeassistant' META_HOMEASSISTANT = "homeassistant"
JSON_RESULT = 'result' JSON_RESULT = "result"
JSON_DATA = 'data' JSON_DATA = "data"
JSON_MESSAGE = 'message' JSON_MESSAGE = "message"
RESULT_ERROR = 'error' RESULT_ERROR = "error"
RESULT_OK = 'ok' RESULT_OK = "ok"
CONTENT_TYPE_BINARY = 'application/octet-stream' CONTENT_TYPE_BINARY = "application/octet-stream"
CONTENT_TYPE_PNG = 'image/png' CONTENT_TYPE_PNG = "image/png"
CONTENT_TYPE_JSON = 'application/json' CONTENT_TYPE_JSON = "application/json"
CONTENT_TYPE_TEXT = 'text/plain' CONTENT_TYPE_TEXT = "text/plain"
CONTENT_TYPE_TAR = 'application/tar' CONTENT_TYPE_TAR = "application/tar"
CONTENT_TYPE_URL = 'application/x-www-form-urlencoded' CONTENT_TYPE_URL = "application/x-www-form-urlencoded"
HEADER_HA_ACCESS = 'x-ha-access' HEADER_HA_ACCESS = "x-ha-access"
HEADER_TOKEN = 'x-hassio-key' HEADER_TOKEN = "x-hassio-key"
ENV_TOKEN = 'HASSIO_TOKEN' ENV_TOKEN = "HASSIO_TOKEN"
ENV_TIME = 'TZ' ENV_TIME = "TZ"
REQUEST_FROM = 'HASSIO_FROM' REQUEST_FROM = "HASSIO_FROM"
ATTR_MACHINE = 'machine' ATTR_MACHINE = "machine"
ATTR_WAIT_BOOT = 'wait_boot' ATTR_WAIT_BOOT = "wait_boot"
ATTR_DEPLOYMENT = 'deployment' ATTR_DEPLOYMENT = "deployment"
ATTR_WATCHDOG = 'watchdog' ATTR_WATCHDOG = "watchdog"
ATTR_CHANGELOG = 'changelog' ATTR_CHANGELOG = "changelog"
ATTR_DATE = 'date' ATTR_DATE = "date"
ATTR_ARCH = 'arch' ATTR_ARCH = "arch"
ATTR_LONG_DESCRIPTION = 'long_description' ATTR_LONG_DESCRIPTION = "long_description"
ATTR_HOSTNAME = 'hostname' ATTR_HOSTNAME = "hostname"
ATTR_TIMEZONE = 'timezone' ATTR_TIMEZONE = "timezone"
ATTR_ARGS = 'args' ATTR_ARGS = "args"
ATTR_OPERATING_SYSTEM = 'operating_system' ATTR_OPERATING_SYSTEM = "operating_system"
ATTR_CHASSIS = 'chassis' ATTR_CHASSIS = "chassis"
ATTR_TYPE = 'type' ATTR_TYPE = "type"
ATTR_SOURCE = 'source' ATTR_SOURCE = "source"
ATTR_FEATURES = 'features' ATTR_FEATURES = "features"
ATTR_ADDONS = 'addons' ATTR_ADDONS = "addons"
ATTR_PROVIDERS = 'providers' ATTR_PROVIDERS = "providers"
ATTR_VERSION = 'version' ATTR_VERSION = "version"
ATTR_VERSION_LATEST = 'version_latest' ATTR_VERSION_LATEST = "version_latest"
ATTR_AUTO_UART = 'auto_uart' ATTR_AUTO_UART = "auto_uart"
ATTR_LAST_BOOT = 'last_boot' ATTR_LAST_BOOT = "last_boot"
ATTR_LAST_VERSION = 'last_version' ATTR_LAST_VERSION = "last_version"
ATTR_CHANNEL = 'channel' ATTR_CHANNEL = "channel"
ATTR_NAME = 'name' ATTR_NAME = "name"
ATTR_SLUG = 'slug' ATTR_SLUG = "slug"
ATTR_DESCRIPTON = 'description' ATTR_DESCRIPTON = "description"
ATTR_STARTUP = 'startup' ATTR_STARTUP = "startup"
ATTR_BOOT = 'boot' ATTR_BOOT = "boot"
ATTR_PORTS = 'ports' ATTR_PORTS = "ports"
ATTR_PORT = 'port' ATTR_PORT = "port"
ATTR_SSL = 'ssl' ATTR_SSL = "ssl"
ATTR_MAP = 'map' ATTR_MAP = "map"
ATTR_WEBUI = 'webui' ATTR_WEBUI = "webui"
ATTR_OPTIONS = 'options' ATTR_OPTIONS = "options"
ATTR_INSTALLED = 'installed' ATTR_INSTALLED = "installed"
ATTR_DETACHED = 'detached' ATTR_DETACHED = "detached"
ATTR_STATE = 'state' ATTR_STATE = "state"
ATTR_SCHEMA = 'schema' ATTR_SCHEMA = "schema"
ATTR_IMAGE = 'image' ATTR_IMAGE = "image"
ATTR_ICON = 'icon' ATTR_ICON = "icon"
ATTR_LOGO = 'logo' ATTR_LOGO = "logo"
ATTR_STDIN = 'stdin' ATTR_STDIN = "stdin"
ATTR_ADDONS_REPOSITORIES = 'addons_repositories' ATTR_ADDONS_REPOSITORIES = "addons_repositories"
ATTR_REPOSITORY = 'repository' ATTR_REPOSITORY = "repository"
ATTR_REPOSITORIES = 'repositories' ATTR_REPOSITORIES = "repositories"
ATTR_URL = 'url' ATTR_URL = "url"
ATTR_MAINTAINER = 'maintainer' ATTR_MAINTAINER = "maintainer"
ATTR_PASSWORD = 'password' ATTR_PASSWORD = "password"
ATTR_TOTP = 'totp' ATTR_TOTP = "totp"
ATTR_INITIALIZE = 'initialize' ATTR_INITIALIZE = "initialize"
ATTR_LOCATON = 'location' ATTR_LOCATON = "location"
ATTR_BUILD = 'build' ATTR_BUILD = "build"
ATTR_DEVICES = 'devices' ATTR_DEVICES = "devices"
ATTR_ENVIRONMENT = 'environment' ATTR_ENVIRONMENT = "environment"
ATTR_HOST_NETWORK = 'host_network' ATTR_HOST_NETWORK = "host_network"
ATTR_HOST_PID = 'host_pid' ATTR_HOST_PID = "host_pid"
ATTR_HOST_IPC = 'host_ipc' ATTR_HOST_IPC = "host_ipc"
ATTR_HOST_DBUS = 'host_dbus' ATTR_HOST_DBUS = "host_dbus"
ATTR_NETWORK = 'network' ATTR_NETWORK = "network"
ATTR_TMPFS = 'tmpfs' ATTR_TMPFS = "tmpfs"
ATTR_PRIVILEGED = 'privileged' ATTR_PRIVILEGED = "privileged"
ATTR_USER = 'user' ATTR_USER = "user"
ATTR_SYSTEM = 'system' ATTR_SYSTEM = "system"
ATTR_SNAPSHOTS = 'snapshots' ATTR_SNAPSHOTS = "snapshots"
ATTR_HOMEASSISTANT = 'homeassistant' ATTR_HOMEASSISTANT = "homeassistant"
ATTR_HASSIO = 'hassio' ATTR_HASSIO = "hassio"
ATTR_HASSIO_API = 'hassio_api' ATTR_HASSIO_API = "hassio_api"
ATTR_HOMEASSISTANT_API = 'homeassistant_api' ATTR_HOMEASSISTANT_API = "homeassistant_api"
ATTR_UUID = 'uuid' ATTR_UUID = "uuid"
ATTR_FOLDERS = 'folders' ATTR_FOLDERS = "folders"
ATTR_SIZE = 'size' ATTR_SIZE = "size"
ATTR_TYPE = 'type' ATTR_TYPE = "type"
ATTR_TIMEOUT = 'timeout' ATTR_TIMEOUT = "timeout"
ATTR_AUTO_UPDATE = 'auto_update' ATTR_AUTO_UPDATE = "auto_update"
ATTR_CUSTOM = 'custom' ATTR_CUSTOM = "custom"
ATTR_AUDIO = 'audio' ATTR_AUDIO = "audio"
ATTR_AUDIO_INPUT = 'audio_input' ATTR_AUDIO_INPUT = "audio_input"
ATTR_AUDIO_OUTPUT = 'audio_output' ATTR_AUDIO_OUTPUT = "audio_output"
ATTR_INPUT = 'input' ATTR_INPUT = "input"
ATTR_OUTPUT = 'output' ATTR_OUTPUT = "output"
ATTR_DISK = 'disk' ATTR_DISK = "disk"
ATTR_SERIAL = 'serial' ATTR_SERIAL = "serial"
ATTR_SECURITY = 'security' ATTR_SECURITY = "security"
ATTR_BUILD_FROM = 'build_from' ATTR_BUILD_FROM = "build_from"
ATTR_SQUASH = 'squash' ATTR_SQUASH = "squash"
ATTR_GPIO = 'gpio' ATTR_GPIO = "gpio"
ATTR_LEGACY = 'legacy' ATTR_LEGACY = "legacy"
ATTR_ADDONS_CUSTOM_LIST = 'addons_custom_list' ATTR_ADDONS_CUSTOM_LIST = "addons_custom_list"
ATTR_CPU_PERCENT = 'cpu_percent' ATTR_CPU_PERCENT = "cpu_percent"
ATTR_NETWORK_RX = 'network_rx' ATTR_NETWORK_RX = "network_rx"
ATTR_NETWORK_TX = 'network_tx' ATTR_NETWORK_TX = "network_tx"
ATTR_MEMORY_LIMIT = 'memory_limit' ATTR_MEMORY_LIMIT = "memory_limit"
ATTR_MEMORY_USAGE = 'memory_usage' ATTR_MEMORY_USAGE = "memory_usage"
ATTR_BLK_READ = 'blk_read' ATTR_BLK_READ = "blk_read"
ATTR_BLK_WRITE = 'blk_write' ATTR_BLK_WRITE = "blk_write"
ATTR_ADDON = 'addon' ATTR_ADDON = "addon"
ATTR_AVAILABLE = 'available' ATTR_AVAILABLE = "available"
ATTR_HOST = 'host' ATTR_HOST = "host"
ATTR_USERNAME = 'username' ATTR_USERNAME = "username"
ATTR_PROTOCOL = 'protocol' ATTR_PROTOCOL = "protocol"
ATTR_DISCOVERY = 'discovery' ATTR_DISCOVERY = "discovery"
ATTR_CONFIG = 'config' ATTR_CONFIG = "config"
ATTR_SERVICES = 'services' ATTR_SERVICES = "services"
ATTR_SERVICE = 'service' ATTR_SERVICE = "service"
ATTR_DISCOVERY = 'discovery' ATTR_DISCOVERY = "discovery"
ATTR_PROTECTED = 'protected' ATTR_PROTECTED = "protected"
ATTR_CRYPTO = 'crypto' ATTR_CRYPTO = "crypto"
ATTR_BRANCH = 'branch' ATTR_BRANCH = "branch"
ATTR_KERNEL = 'kernel' ATTR_KERNEL = "kernel"
ATTR_APPARMOR = 'apparmor' ATTR_APPARMOR = "apparmor"
ATTR_DEVICETREE = 'devicetree' ATTR_DEVICETREE = "devicetree"
ATTR_CPE = 'cpe' ATTR_CPE = "cpe"
ATTR_BOARD = 'board' ATTR_BOARD = "board"
ATTR_HASSOS = 'hassos' ATTR_HASSOS = "hassos"
ATTR_HASSOS_CLI = 'hassos_cli' ATTR_HASSOS_CLI = "hassos_cli"
ATTR_VERSION_CLI = 'version_cli' ATTR_VERSION_CLI = "version_cli"
ATTR_VERSION_CLI_LATEST = 'version_cli_latest' ATTR_VERSION_CLI_LATEST = "version_cli_latest"
ATTR_REFRESH_TOKEN = 'refresh_token' ATTR_REFRESH_TOKEN = "refresh_token"
ATTR_ACCESS_TOKEN = 'access_token' ATTR_ACCESS_TOKEN = "access_token"
ATTR_DOCKER_API = 'docker_api' ATTR_DOCKER_API = "docker_api"
ATTR_FULL_ACCESS = 'full_access' ATTR_FULL_ACCESS = "full_access"
ATTR_PROTECTED = 'protected' ATTR_PROTECTED = "protected"
ATTR_RATING = 'rating' ATTR_RATING = "rating"
ATTR_HASSIO_ROLE = 'hassio_role' ATTR_HASSIO_ROLE = "hassio_role"
ATTR_SUPERVISOR = 'supervisor' ATTR_SUPERVISOR = "supervisor"
ATTR_AUTH_API = 'auth_api' ATTR_AUTH_API = "auth_api"
ATTR_KERNEL_MODULES = "kernel_modules"
SERVICE_MQTT = 'mqtt' SERVICE_MQTT = "mqtt"
PROVIDE_SERVICE = 'provide' PROVIDE_SERVICE = "provide"
NEED_SERVICE = 'need' NEED_SERVICE = "need"
WANT_SERVICE = 'want' WANT_SERVICE = "want"
STARTUP_INITIALIZE = 'initialize' STARTUP_INITIALIZE = "initialize"
STARTUP_SYSTEM = 'system' STARTUP_SYSTEM = "system"
STARTUP_SERVICES = 'services' STARTUP_SERVICES = "services"
STARTUP_APPLICATION = 'application' STARTUP_APPLICATION = "application"
STARTUP_ONCE = 'once' STARTUP_ONCE = "once"
BOOT_AUTO = 'auto' BOOT_AUTO = "auto"
BOOT_MANUAL = 'manual' BOOT_MANUAL = "manual"
STATE_STARTED = 'started' STATE_STARTED = "started"
STATE_STOPPED = 'stopped' STATE_STOPPED = "stopped"
STATE_NONE = 'none' STATE_NONE = "none"
MAP_CONFIG = 'config' MAP_CONFIG = "config"
MAP_SSL = 'ssl' MAP_SSL = "ssl"
MAP_ADDONS = 'addons' MAP_ADDONS = "addons"
MAP_BACKUP = 'backup' MAP_BACKUP = "backup"
MAP_SHARE = 'share' MAP_SHARE = "share"
ARCH_ARMHF = 'armhf' ARCH_ARMHF = "armhf"
ARCH_AARCH64 = 'aarch64' ARCH_AARCH64 = "aarch64"
ARCH_AMD64 = 'amd64' ARCH_AMD64 = "amd64"
ARCH_I386 = 'i386' ARCH_I386 = "i386"
CHANNEL_STABLE = 'stable' CHANNEL_STABLE = "stable"
CHANNEL_BETA = 'beta' CHANNEL_BETA = "beta"
CHANNEL_DEV = 'dev' CHANNEL_DEV = "dev"
REPOSITORY_CORE = 'core' REPOSITORY_CORE = "core"
REPOSITORY_LOCAL = 'local' REPOSITORY_LOCAL = "local"
FOLDER_HOMEASSISTANT = 'homeassistant' FOLDER_HOMEASSISTANT = "homeassistant"
FOLDER_SHARE = 'share' FOLDER_SHARE = "share"
FOLDER_ADDONS = 'addons/local' FOLDER_ADDONS = "addons/local"
FOLDER_SSL = 'ssl' FOLDER_SSL = "ssl"
SNAPSHOT_FULL = 'full' SNAPSHOT_FULL = "full"
SNAPSHOT_PARTIAL = 'partial' SNAPSHOT_PARTIAL = "partial"
CRYPTO_AES128 = 'aes128' CRYPTO_AES128 = "aes128"
SECURITY_PROFILE = 'profile' SECURITY_PROFILE = "profile"
SECURITY_DEFAULT = 'default' SECURITY_DEFAULT = "default"
SECURITY_DISABLE = 'disable' SECURITY_DISABLE = "disable"
PRIVILEGED_NET_ADMIN = 'NET_ADMIN' PRIVILEGED_NET_ADMIN = "NET_ADMIN"
PRIVILEGED_SYS_ADMIN = 'SYS_ADMIN' PRIVILEGED_SYS_ADMIN = "SYS_ADMIN"
PRIVILEGED_SYS_RAWIO = 'SYS_RAWIO' PRIVILEGED_SYS_RAWIO = "SYS_RAWIO"
PRIVILEGED_IPC_LOCK = 'IPC_LOCK' PRIVILEGED_IPC_LOCK = "IPC_LOCK"
PRIVILEGED_SYS_TIME = 'SYS_TIME' PRIVILEGED_SYS_TIME = "SYS_TIME"
PRIVILEGED_SYS_NICE = 'SYS_NICE' PRIVILEGED_SYS_NICE = "SYS_NICE"
PRIVILEGED_SYS_RESOURCE = 'SYS_RESOURCE' PRIVILEGED_SYS_MODULE = "SYS_MODULE"
PRIVILEGED_SYS_PTRACE = 'SYS_PTRACE' PRIVILEGED_SYS_RESOURCE = "SYS_RESOURCE"
PRIVILEGED_DAC_READ_SEARCH = 'DAC_READ_SEARCH' PRIVILEGED_SYS_PTRACE = "SYS_PTRACE"
PRIVILEGED_DAC_READ_SEARCH = "DAC_READ_SEARCH"
FEATURES_SHUTDOWN = 'shutdown' FEATURES_SHUTDOWN = "shutdown"
FEATURES_REBOOT = 'reboot' FEATURES_REBOOT = "reboot"
FEATURES_HASSOS = 'hassos' FEATURES_HASSOS = "hassos"
FEATURES_HOSTNAME = 'hostname' FEATURES_HOSTNAME = "hostname"
FEATURES_SERVICES = 'services' FEATURES_SERVICES = "services"
ROLE_DEFAULT = 'default' ROLE_DEFAULT = "default"
ROLE_HOMEASSISTANT = 'homeassistant' ROLE_HOMEASSISTANT = "homeassistant"
ROLE_BACKUP = 'backup' ROLE_BACKUP = "backup"
ROLE_MANAGER = 'manager' ROLE_MANAGER = "manager"
ROLE_ADMIN = 'admin' ROLE_ADMIN = "admin"
CHAN_ID = 'chan_id' CHAN_ID = "chan_id"
CHAN_TYPE = 'chan_type' CHAN_TYPE = "chan_type"

View File

@ -61,12 +61,11 @@ class HassIO(CoreSysAttributes):
async def start(self): async def start(self):
"""Start Hass.io orchestration.""" """Start Hass.io orchestration."""
# on release channel, try update itself # on release channel, try update itself
# on dev mode, only read new versions if self.sys_supervisor.need_update:
if not self.sys_dev and self.sys_supervisor.need_update: if self.sys_dev:
if await self.sys_supervisor.update(): _LOGGER.warning("Ignore Hass.io updates on dev!")
elif await self.sys_supervisor.update():
return return
else:
_LOGGER.info("Ignore Hass.io auto updates on dev channel")
# start api # start api
await self.sys_api.start() await self.sys_api.start()

View File

@ -65,7 +65,8 @@ class DockerAPI:
# Create container # Create container
try: try:
container = self.docker.containers.create(image, **kwargs) container = self.docker.containers.create(
image, use_config_proxy=False, **kwargs)
except docker.errors.DockerException as err: except docker.errors.DockerException as err:
_LOGGER.error("Can't create container from %s: %s", name, err) _LOGGER.error("Can't create container from %s: %s", name, err)
return False return False
@ -101,6 +102,7 @@ class DockerAPI:
image, image,
command=command, command=command,
network=self.network.name, network=self.network.name,
use_config_proxy=False,
**kwargs **kwargs
) )

View File

@ -233,6 +233,14 @@ class DockerAddon(DockerInterface):
}, },
}) })
# Kernel Modules support
if self.addon.with_kernel_modules:
volumes.update({
"/lib/modules": {
'bind': "/lib/modules", 'mode': 'ro'
},
})
# Docker API support # Docker API support
if not self.addon.protected and self.addon.access_docker_api: if not self.addon.protected and self.addon.access_docker_api:
volumes.update({ volumes.update({
@ -320,6 +328,7 @@ class DockerAddon(DockerInterface):
_LOGGER.info("Start build %s:%s", self.image, tag) _LOGGER.info("Start build %s:%s", self.image, tag)
try: try:
image, log = self.sys_docker.images.build( image, log = self.sys_docker.images.build(
use_config_proxy=False,
**build_env.get_docker_args(tag)) **build_env.get_docker_args(tag))
_LOGGER.debug("Build %s:%s done: %s", self.image, tag, log) _LOGGER.debug("Build %s:%s done: %s", self.image, tag, log)

View File

@ -3,118 +3,98 @@
class HassioError(Exception): class HassioError(Exception):
"""Root exception.""" """Root exception."""
pass
class HassioNotSupportedError(HassioError): class HassioNotSupportedError(HassioError):
"""Function is not supported.""" """Function is not supported."""
pass
# HomeAssistant # HomeAssistant
class HomeAssistantError(HassioError): class HomeAssistantError(HassioError):
"""Home Assistant exception.""" """Home Assistant exception."""
pass
class HomeAssistantUpdateError(HomeAssistantError): class HomeAssistantUpdateError(HomeAssistantError):
"""Error on update of a Home Assistant.""" """Error on update of a Home Assistant."""
pass
class HomeAssistantAPIError(HomeAssistantError): class HomeAssistantAPIError(HomeAssistantError):
"""Home Assistant API exception.""" """Home Assistant API exception."""
pass
class HomeAssistantAuthError(HomeAssistantAPIError): class HomeAssistantAuthError(HomeAssistantAPIError):
"""Home Assistant Auth API exception.""" """Home Assistant Auth API exception."""
pass
# HassOS # HassOS
class HassOSError(HassioError): class HassOSError(HassioError):
"""HassOS exception.""" """HassOS exception."""
pass
class HassOSUpdateError(HassOSError): class HassOSUpdateError(HassOSError):
"""Error on update of a HassOS.""" """Error on update of a HassOS."""
pass
class HassOSNotSupportedError(HassioNotSupportedError): class HassOSNotSupportedError(HassioNotSupportedError):
"""Function not supported by HassOS.""" """Function not supported by HassOS."""
pass
# Updater # Updater
class HassioUpdaterError(HassioError): class HassioUpdaterError(HassioError):
"""Error on Updater.""" """Error on Updater."""
pass
# Auth # Auth
class AuthError(HassioError): class AuthError(HassioError):
"""Auth errors.""" """Auth errors."""
pass
# Host # Host
class HostError(HassioError): class HostError(HassioError):
"""Internal Host error.""" """Internal Host error."""
pass
class HostNotSupportedError(HassioNotSupportedError): class HostNotSupportedError(HassioNotSupportedError):
"""Host function is not supprted.""" """Host function is not supprted."""
pass
class HostServiceError(HostError): class HostServiceError(HostError):
"""Host service functions fails.""" """Host service functions fails."""
pass
class HostAppArmorError(HostError): class HostAppArmorError(HostError):
"""Host apparmor functions fails.""" """Host apparmor functions fails."""
pass
# API # API
class APIError(HassioError, RuntimeError): class APIError(HassioError, RuntimeError):
"""API errors.""" """API errors."""
pass
class APIForbidden(APIError): class APIForbidden(APIError):
"""API forbidden error.""" """API forbidden error."""
pass
# Service / Discovery # Service / Discovery
class DiscoveryError(HassioError): class DiscoveryError(HassioError):
"""Discovery Errors.""" """Discovery Errors."""
pass
class ServicesError(HassioError): class ServicesError(HassioError):
"""Services Errors.""" """Services Errors."""
pass
# utils/gdbus # utils/gdbus
class DBusError(HassioError): class DBusError(HassioError):
"""DBus generic error.""" """DBus generic error."""
pass
class DBusNotConnectedError(HostNotSupportedError): class DBusNotConnectedError(HostNotSupportedError):
@ -123,26 +103,21 @@ class DBusNotConnectedError(HostNotSupportedError):
class DBusFatalError(DBusError): class DBusFatalError(DBusError):
"""DBus call going wrong.""" """DBus call going wrong."""
pass
class DBusParseError(DBusError): class DBusParseError(DBusError):
"""DBus parse error.""" """DBus parse error."""
pass
# util/apparmor # util/apparmor
class AppArmorError(HostAppArmorError): class AppArmorError(HostAppArmorError):
"""General AppArmor error.""" """General AppArmor error."""
pass
class AppArmorFileError(AppArmorError): class AppArmorFileError(AppArmorError):
"""AppArmor profile file error.""" """AppArmor profile file error."""
pass
class AppArmorInvalidError(AppArmorError): class AppArmorInvalidError(AppArmorError):
"""AppArmor profile validate error.""" """AppArmor profile validate error."""
pass

View File

@ -211,15 +211,8 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
while True: while True:
if await self.instance.install('landingpage'): if await self.instance.install('landingpage'):
break break
_LOGGER.warning("Fails install landingpage, retry after 60sec") _LOGGER.warning("Fails install landingpage, retry after 30sec")
await asyncio.sleep(60) await asyncio.sleep(30)
# Run landingpage after installation
_LOGGER.info("Start landing page")
try:
await self._start()
except HomeAssistantError:
_LOGGER.warning("Can't start landing page")
@process_lock @process_lock
async def install(self): async def install(self):
@ -233,8 +226,8 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
tag = self.last_version tag = self.last_version
if tag and await self.instance.install(tag): if tag and await self.instance.install(tag):
break break
_LOGGER.warning("Error on install Home Assistant. Retry in 60sec") _LOGGER.warning("Error on install Home Assistant. Retry in 30sec")
await asyncio.sleep(60) await asyncio.sleep(30)
# finishing # finishing
_LOGGER.info("Home Assistant docker now installed") _LOGGER.info("Home Assistant docker now installed")

View File

@ -1,7 +1,7 @@
attrs==18.2.0 attrs==18.2.0
async_timeout==3.0.1 async_timeout==3.0.1
aiohttp==3.4.4 aiohttp==3.5.2
docker==3.5.0 docker==3.7.0
colorlog==3.1.4 colorlog==3.1.4
voluptuous==0.11.5 voluptuous==0.11.5
gitpython==2.1.10 gitpython==2.1.10

View File

@ -4,8 +4,8 @@ envlist = lint, tests
[testenv] [testenv]
deps = deps =
flake8==3.6.0 flake8==3.6.0
pylint==2.1.1 pylint==2.2.2
pytest==4.0.0 pytest==4.1.1
-r{toxinidir}/requirements.txt -r{toxinidir}/requirements.txt
[testenv:lint] [testenv:lint]