mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-23 09:06:29 +00:00
Expose new function to add-ons (#138)
* Expose new function to add-ons * Rename `hassio` to `hassio_api` * fix lint * done
This commit is contained in:
parent
cd3b382902
commit
8d468328f3
14
API.md
14
API.md
@ -336,7 +336,9 @@ Get all available addons.
|
|||||||
"privileged": ["NET_ADMIN", "SYS_ADMIN"],
|
"privileged": ["NET_ADMIN", "SYS_ADMIN"],
|
||||||
"devices": ["/dev/xy"],
|
"devices": ["/dev/xy"],
|
||||||
"url": "null|url",
|
"url": "null|url",
|
||||||
"logo": "bool"
|
"logo": "bool",
|
||||||
|
"audio": "bool",
|
||||||
|
"hassio_api": "bool"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"repositories": [
|
"repositories": [
|
||||||
@ -373,7 +375,11 @@ Get all available addons.
|
|||||||
"privileged": ["NET_ADMIN", "SYS_ADMIN"],
|
"privileged": ["NET_ADMIN", "SYS_ADMIN"],
|
||||||
"devices": ["/dev/xy"],
|
"devices": ["/dev/xy"],
|
||||||
"logo": "bool",
|
"logo": "bool",
|
||||||
"webui": "null|http(s)://[HOST]:port/xy/zx"
|
"hassio_api": "bool",
|
||||||
|
"webui": "null|http(s)://[HOST]:port/xy/zx",
|
||||||
|
"audio": "bool",
|
||||||
|
"audio_input": "null|0,0",
|
||||||
|
"audio_output": "null|0,0"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -389,10 +395,12 @@ Get all available addons.
|
|||||||
"CONTAINER": "port|[ip, port]"
|
"CONTAINER": "port|[ip, port]"
|
||||||
},
|
},
|
||||||
"options": {},
|
"options": {},
|
||||||
|
"audio_output": "null|0,0",
|
||||||
|
"audio_input": "null|0,0"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For reset custom network settings, set it `null`.
|
For reset custom network/audio settings, set it `null`.
|
||||||
|
|
||||||
- POST `/addons/{addon}/start`
|
- POST `/addons/{addon}/start`
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@ from ..const import (
|
|||||||
ATTR_URL, ATTR_ARCH, ATTR_LOCATON, ATTR_DEVICES, ATTR_ENVIRONMENT,
|
ATTR_URL, ATTR_ARCH, ATTR_LOCATON, ATTR_DEVICES, ATTR_ENVIRONMENT,
|
||||||
ATTR_HOST_NETWORK, ATTR_TMPFS, ATTR_PRIVILEGED, ATTR_STARTUP,
|
ATTR_HOST_NETWORK, ATTR_TMPFS, ATTR_PRIVILEGED, ATTR_STARTUP,
|
||||||
STATE_STARTED, STATE_STOPPED, STATE_NONE, ATTR_USER, ATTR_SYSTEM,
|
STATE_STARTED, STATE_STOPPED, STATE_NONE, ATTR_USER, ATTR_SYSTEM,
|
||||||
ATTR_STATE, ATTR_TIMEOUT, ATTR_AUTO_UPDATE, ATTR_NETWORK, ATTR_WEBUI)
|
ATTR_STATE, ATTR_TIMEOUT, ATTR_AUTO_UPDATE, ATTR_NETWORK, ATTR_WEBUI,
|
||||||
|
ATTR_HASSIO_API, ATTR_AUDIO, ATTR_AUDIO_OUTPUT, ATTR_AUDIO_INPUT)
|
||||||
from .util import check_installed
|
from .util import check_installed
|
||||||
from ..dock.addon import DockerAddon
|
from ..dock.addon import DockerAddon
|
||||||
from ..tools import write_json_file, read_json_file
|
from ..tools import write_json_file, read_json_file
|
||||||
@ -244,6 +245,56 @@ class Addon(object):
|
|||||||
"""Return list of privilege."""
|
"""Return list of privilege."""
|
||||||
return self._mesh.get(ATTR_PRIVILEGED)
|
return self._mesh.get(ATTR_PRIVILEGED)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def use_hassio_api(self):
|
||||||
|
"""Return True if the add-on access to hassio api."""
|
||||||
|
return self._mesh[ATTR_HASSIO_API]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def with_audio(self):
|
||||||
|
"""Return True if the add-on access to audio."""
|
||||||
|
return self._mesh[ATTR_AUDIO]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def audio_output(self):
|
||||||
|
"""Return ALSA config for output or None."""
|
||||||
|
if not self.with_audio:
|
||||||
|
return
|
||||||
|
|
||||||
|
setting = self.config.audio_output
|
||||||
|
if self.is_installed and ATTR_AUDIO_OUTPUT in self.data.user[self._id]:
|
||||||
|
setting = self.data.user[self._id][ATTR_AUDIO_OUTPUT]
|
||||||
|
return setting
|
||||||
|
|
||||||
|
@audio_output.setter
|
||||||
|
def audio_output(self, value):
|
||||||
|
"""Set/remove custom audio output settings."""
|
||||||
|
if value is None:
|
||||||
|
self.data.user[self._id].pop(ATTR_AUDIO_OUTPUT, None)
|
||||||
|
else:
|
||||||
|
self.data.user[self._id][ATTR_AUDIO_OUTPUT] = value
|
||||||
|
self.data.save()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def audio_input(self):
|
||||||
|
"""Return ALSA config for input or None."""
|
||||||
|
if not self.with_audio:
|
||||||
|
return
|
||||||
|
|
||||||
|
setting = self.config.audio_input
|
||||||
|
if self.is_installed and ATTR_AUDIO_INPUT in self.data.user[self._id]:
|
||||||
|
setting = self.data.user[self._id][ATTR_AUDIO_INPUT]
|
||||||
|
return setting
|
||||||
|
|
||||||
|
@audio_input.setter
|
||||||
|
def audio_input(self, value):
|
||||||
|
"""Set/remove custom audio input settings."""
|
||||||
|
if value is None:
|
||||||
|
self.data.user[self._id].pop(ATTR_AUDIO_INPUT, None)
|
||||||
|
else:
|
||||||
|
self.data.user[self._id][ATTR_AUDIO_INPUT] = value
|
||||||
|
self.data.save()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url(self):
|
def url(self):
|
||||||
"""Return url of addon."""
|
"""Return url of addon."""
|
||||||
|
@ -10,8 +10,9 @@ from ..const import (
|
|||||||
ARCH_AARCH64, ARCH_AMD64, ARCH_I386, ATTR_TMPFS, ATTR_PRIVILEGED,
|
ARCH_AARCH64, ARCH_AMD64, ARCH_I386, ATTR_TMPFS, ATTR_PRIVILEGED,
|
||||||
ATTR_USER, ATTR_STATE, ATTR_SYSTEM, STATE_STARTED, STATE_STOPPED,
|
ATTR_USER, ATTR_STATE, ATTR_SYSTEM, STATE_STARTED, STATE_STOPPED,
|
||||||
ATTR_LOCATON, ATTR_REPOSITORY, ATTR_TIMEOUT, ATTR_NETWORK,
|
ATTR_LOCATON, ATTR_REPOSITORY, ATTR_TIMEOUT, ATTR_NETWORK,
|
||||||
ATTR_AUTO_UPDATE, ATTR_WEBUI)
|
ATTR_AUTO_UPDATE, ATTR_WEBUI, ATTR_AUDIO, ATTR_AUDIO_INPUT,
|
||||||
from ..validate import NETWORK_PORT, DOCKER_PORTS
|
ATTR_AUDIO_OUTPUT, ATTR_HASSIO_API)
|
||||||
|
from ..validate import NETWORK_PORT, DOCKER_PORTS, ALSA_CHANNEL
|
||||||
|
|
||||||
|
|
||||||
MAP_VOLUME = r"^(config|ssl|addons|backup|share)(?::(rw|:ro))?$"
|
MAP_VOLUME = r"^(config|ssl|addons|backup|share)(?::(rw|:ro))?$"
|
||||||
@ -73,6 +74,8 @@ SCHEMA_ADDON_CONFIG = vol.Schema({
|
|||||||
vol.Optional(ATTR_MAP, default=[]): [vol.Match(MAP_VOLUME)],
|
vol.Optional(ATTR_MAP, default=[]): [vol.Match(MAP_VOLUME)],
|
||||||
vol.Optional(ATTR_ENVIRONMENT): {vol.Match(r"\w*"): vol.Coerce(str)},
|
vol.Optional(ATTR_ENVIRONMENT): {vol.Match(r"\w*"): vol.Coerce(str)},
|
||||||
vol.Optional(ATTR_PRIVILEGED): [vol.In(PRIVILEGED_ALL)],
|
vol.Optional(ATTR_PRIVILEGED): [vol.In(PRIVILEGED_ALL)],
|
||||||
|
vol.Optional(ATTR_AUDIO, default=False): vol.Boolean(),
|
||||||
|
vol.Optional(ATTR_HASSIO_API, default=False): vol.Boolean(),
|
||||||
vol.Required(ATTR_OPTIONS): dict,
|
vol.Required(ATTR_OPTIONS): dict,
|
||||||
vol.Required(ATTR_SCHEMA): vol.Any(vol.Schema({
|
vol.Required(ATTR_SCHEMA): vol.Any(vol.Schema({
|
||||||
vol.Coerce(str): vol.Any(ADDON_ELEMENT, [
|
vol.Coerce(str): vol.Any(ADDON_ELEMENT, [
|
||||||
@ -101,6 +104,8 @@ SCHEMA_ADDON_USER = vol.Schema({
|
|||||||
vol.Optional(ATTR_BOOT):
|
vol.Optional(ATTR_BOOT):
|
||||||
vol.In([BOOT_AUTO, BOOT_MANUAL]),
|
vol.In([BOOT_AUTO, BOOT_MANUAL]),
|
||||||
vol.Optional(ATTR_NETWORK): DOCKER_PORTS,
|
vol.Optional(ATTR_NETWORK): DOCKER_PORTS,
|
||||||
|
vol.Optional(ATTR_AUDIO_OUTPUT): ALSA_CHANNEL,
|
||||||
|
vol.Optional(ATTR_AUDIO_INPUT): ALSA_CHANNEL,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ from ..const import (
|
|||||||
ATTR_BUILD, ATTR_AUTO_UPDATE, ATTR_NETWORK, ATTR_HOST_NETWORK, ATTR_SLUG,
|
ATTR_BUILD, ATTR_AUTO_UPDATE, ATTR_NETWORK, ATTR_HOST_NETWORK, ATTR_SLUG,
|
||||||
ATTR_SOURCE, ATTR_REPOSITORIES, ATTR_ADDONS, ATTR_ARCH, ATTR_MAINTAINER,
|
ATTR_SOURCE, ATTR_REPOSITORIES, ATTR_ADDONS, ATTR_ARCH, ATTR_MAINTAINER,
|
||||||
ATTR_INSTALLED, ATTR_LOGO, ATTR_WEBUI, ATTR_DEVICES, ATTR_PRIVILEGED,
|
ATTR_INSTALLED, ATTR_LOGO, ATTR_WEBUI, ATTR_DEVICES, ATTR_PRIVILEGED,
|
||||||
|
ATTR_AUDIO, ATTR_AUDIO_INPUT, ATTR_AUDIO_OUTPUT, ATTR_HASSIO_API,
|
||||||
BOOT_AUTO, BOOT_MANUAL, CONTENT_TYPE_PNG, CONTENT_TYPE_BINARY)
|
BOOT_AUTO, BOOT_MANUAL, CONTENT_TYPE_PNG, CONTENT_TYPE_BINARY)
|
||||||
from ..validate import DOCKER_PORTS
|
from ..validate import DOCKER_PORTS
|
||||||
|
|
||||||
@ -76,6 +77,8 @@ class APIAddons(object):
|
|||||||
ATTR_DEVICES: self._pretty_devices(addon),
|
ATTR_DEVICES: self._pretty_devices(addon),
|
||||||
ATTR_URL: addon.url,
|
ATTR_URL: addon.url,
|
||||||
ATTR_LOGO: addon.with_logo,
|
ATTR_LOGO: addon.with_logo,
|
||||||
|
ATTR_HASSIO_API: addon.use_hassio_api,
|
||||||
|
ATTR_AUDIO: addon.with_audio,
|
||||||
})
|
})
|
||||||
|
|
||||||
data_repositories = []
|
data_repositories = []
|
||||||
@ -123,6 +126,10 @@ class APIAddons(object):
|
|||||||
ATTR_DEVICES: self._pretty_devices(addon),
|
ATTR_DEVICES: self._pretty_devices(addon),
|
||||||
ATTR_LOGO: addon.with_logo,
|
ATTR_LOGO: addon.with_logo,
|
||||||
ATTR_WEBUI: addon.webui,
|
ATTR_WEBUI: addon.webui,
|
||||||
|
ATTR_HASSIO_API: addon.use_hassio_api,
|
||||||
|
ATTR_AUDIO: addon.with_audio,
|
||||||
|
ATTR_AUDIO_INPUT: addon.audio_input,
|
||||||
|
ATTR_AUDIO_OUTPUT: addon.audio_output,
|
||||||
}
|
}
|
||||||
|
|
||||||
@api_process
|
@api_process
|
||||||
@ -144,6 +151,10 @@ class APIAddons(object):
|
|||||||
addon.auto_update = body[ATTR_AUTO_UPDATE]
|
addon.auto_update = body[ATTR_AUTO_UPDATE]
|
||||||
if ATTR_NETWORK in body:
|
if ATTR_NETWORK in body:
|
||||||
addon.ports = body[ATTR_NETWORK]
|
addon.ports = body[ATTR_NETWORK]
|
||||||
|
if ATTR_AUDIO_INPUT in body:
|
||||||
|
addon.audio_input = body[ATTR_AUDIO_INPUT]
|
||||||
|
if ATTR_AUDIO_OUTPUT in body:
|
||||||
|
addon.audio_output = body[ATTR_AUDIO_OUTPUT]
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -52,7 +52,6 @@ class APIHost(object):
|
|||||||
|
|
||||||
if ATTR_AUDIO_OUTPUT in body:
|
if ATTR_AUDIO_OUTPUT in body:
|
||||||
self.config.audio_output = body[ATTR_AUDIO_OUTPUT]
|
self.config.audio_output = body[ATTR_AUDIO_OUTPUT]
|
||||||
|
|
||||||
if ATTR_AUDIO_INPUT in body:
|
if ATTR_AUDIO_INPUT in body:
|
||||||
self.config.audio_input = body[ATTR_AUDIO_INPUT]
|
self.config.audio_input = body[ATTR_AUDIO_INPUT]
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ 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_FOLDERS = 'folders'
|
ATTR_FOLDERS = 'folders'
|
||||||
ATTR_SIZE = 'size'
|
ATTR_SIZE = 'size'
|
||||||
ATTR_TYPE = 'type'
|
ATTR_TYPE = 'type'
|
||||||
|
@ -32,6 +32,11 @@ class DockerAddon(DockerBase):
|
|||||||
def environment(self):
|
def environment(self):
|
||||||
"""Return environment for docker add-on."""
|
"""Return environment for docker add-on."""
|
||||||
addon_env = self.addon.environment or {}
|
addon_env = self.addon.environment or {}
|
||||||
|
if self.addon.with_audio:
|
||||||
|
addon_env.update({
|
||||||
|
'ALSA_OUTPUT': self.addon.audio_output,
|
||||||
|
'ALSA_INPUT': self.addon.audio_input,
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
**addon_env,
|
**addon_env,
|
||||||
@ -46,6 +51,16 @@ class DockerAddon(DockerBase):
|
|||||||
return {"/tmpfs": "{}".format(options)}
|
return {"/tmpfs": "{}".format(options)}
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mapping(self):
|
||||||
|
"""Return hosts mapping."""
|
||||||
|
if not self.addon.use_hassio_api:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return {
|
||||||
|
'hassio': self.config.api_endpoint,
|
||||||
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def volumes(self):
|
def volumes(self):
|
||||||
"""Generate volumes for mappings."""
|
"""Generate volumes for mappings."""
|
||||||
@ -111,6 +126,7 @@ class DockerAddon(DockerBase):
|
|||||||
detach=True,
|
detach=True,
|
||||||
network_mode=self.addon.network_mode,
|
network_mode=self.addon.network_mode,
|
||||||
ports=self.addon.ports,
|
ports=self.addon.ports,
|
||||||
|
extra_hosts=self.mapping,
|
||||||
devices=self.addon.devices,
|
devices=self.addon.devices,
|
||||||
cap_add=self.addon.privileged,
|
cap_add=self.addon.privileged,
|
||||||
environment=self.environment,
|
environment=self.environment,
|
||||||
|
@ -62,6 +62,7 @@ class Updater(JsonConfig):
|
|||||||
"""
|
"""
|
||||||
url = URL_HASSIO_VERSION.format(self.upstream)
|
url = URL_HASSIO_VERSION.format(self.upstream)
|
||||||
try:
|
try:
|
||||||
|
_LOGGER.info("Fetch update data from %s", url)
|
||||||
with async_timeout.timeout(10, loop=self.loop):
|
with async_timeout.timeout(10, loop=self.loop):
|
||||||
async with self.websession.get(url) as request:
|
async with self.websession.get(url) as request:
|
||||||
data = await request.json(content_type=None)
|
data = await request.json(content_type=None)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user