mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-22 16:46:29 +00:00
Auto mapping UART devices from host (#276)
* Add hardware to docker api * set hardware to docker * add loop to dns * Use loop for dns * Update const.py * Update API.md * Update validate.py * Update addon.py * Update addon.py * fix lint * style * Update hardware.py
This commit is contained in:
parent
110cd32dc3
commit
c691f2a559
1
API.md
1
API.md
@ -389,6 +389,7 @@ Get all available addons.
|
|||||||
"host_dbus": "bool",
|
"host_dbus": "bool",
|
||||||
"privileged": ["NET_ADMIN", "SYS_ADMIN"],
|
"privileged": ["NET_ADMIN", "SYS_ADMIN"],
|
||||||
"devices": ["/dev/xy"],
|
"devices": ["/dev/xy"],
|
||||||
|
"auto_uart": "bool",
|
||||||
"logo": "bool",
|
"logo": "bool",
|
||||||
"changelog": "bool",
|
"changelog": "bool",
|
||||||
"hassio_api": "bool",
|
"hassio_api": "bool",
|
||||||
|
@ -22,7 +22,7 @@ from ..const import (
|
|||||||
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,
|
ATTR_HASSIO_API, ATTR_AUDIO, ATTR_AUDIO_OUTPUT, ATTR_AUDIO_INPUT,
|
||||||
ATTR_GPIO, ATTR_HOMEASSISTANT_API, ATTR_STDIN, ATTR_LEGACY, ATTR_HOST_IPC,
|
ATTR_GPIO, ATTR_HOMEASSISTANT_API, ATTR_STDIN, ATTR_LEGACY, ATTR_HOST_IPC,
|
||||||
ATTR_HOST_DBUS)
|
ATTR_HOST_DBUS, ATTR_AUTO_UART)
|
||||||
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
|
||||||
@ -259,6 +259,11 @@ class Addon(object):
|
|||||||
"""Return devices of addon."""
|
"""Return devices of addon."""
|
||||||
return self._mesh.get(ATTR_DEVICES)
|
return self._mesh.get(ATTR_DEVICES)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def auto_uart(self):
|
||||||
|
"""Return True if we should map all uart device."""
|
||||||
|
return self._mesh.get(ATTR_AUTO_UART)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tmpfs(self):
|
def tmpfs(self):
|
||||||
"""Return tmpfs of addon."""
|
"""Return tmpfs of addon."""
|
||||||
|
@ -17,7 +17,7 @@ from ..const import (
|
|||||||
ATTR_AUTO_UPDATE, ATTR_WEBUI, ATTR_AUDIO, ATTR_AUDIO_INPUT, ATTR_HOST_IPC,
|
ATTR_AUTO_UPDATE, ATTR_WEBUI, ATTR_AUDIO, ATTR_AUDIO_INPUT, ATTR_HOST_IPC,
|
||||||
ATTR_AUDIO_OUTPUT, ATTR_HASSIO_API, ATTR_BUILD_FROM, ATTR_SQUASH,
|
ATTR_AUDIO_OUTPUT, ATTR_HASSIO_API, ATTR_BUILD_FROM, ATTR_SQUASH,
|
||||||
ATTR_ARGS, ATTR_GPIO, ATTR_HOMEASSISTANT_API, ATTR_STDIN, ATTR_LEGACY,
|
ATTR_ARGS, ATTR_GPIO, ATTR_HOMEASSISTANT_API, ATTR_STDIN, ATTR_LEGACY,
|
||||||
ATTR_HOST_DBUS)
|
ATTR_HOST_DBUS, ATTR_AUTO_UART)
|
||||||
from ..validate import NETWORK_PORT, DOCKER_PORTS, ALSA_CHANNEL
|
from ..validate import NETWORK_PORT, DOCKER_PORTS, ALSA_CHANNEL
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -96,6 +96,7 @@ SCHEMA_ADDON_CONFIG = vol.Schema({
|
|||||||
vol.Optional(ATTR_HOST_IPC, default=False): vol.Boolean(),
|
vol.Optional(ATTR_HOST_IPC, default=False): vol.Boolean(),
|
||||||
vol.Optional(ATTR_HOST_DBUS, default=False): vol.Boolean(),
|
vol.Optional(ATTR_HOST_DBUS, default=False): vol.Boolean(),
|
||||||
vol.Optional(ATTR_DEVICES): [vol.Match(r"^(.*):(.*):([rwm]{1,3})$")],
|
vol.Optional(ATTR_DEVICES): [vol.Match(r"^(.*):(.*):([rwm]{1,3})$")],
|
||||||
|
vol.Optional(ATTR_AUTO_UART, default=False): vol.Boolean(),
|
||||||
vol.Optional(ATTR_TMPFS):
|
vol.Optional(ATTR_TMPFS):
|
||||||
vol.Match(r"^size=(\d)*[kmg](,uid=\d{1,4})?(,rw)?$"),
|
vol.Match(r"^size=(\d)*[kmg](,uid=\d{1,4})?(,rw)?$"),
|
||||||
vol.Optional(ATTR_MAP, default=[]): [vol.Match(RE_VOLUME)],
|
vol.Optional(ATTR_MAP, default=[]): [vol.Match(RE_VOLUME)],
|
||||||
|
@ -66,6 +66,7 @@ ATTR_SOURCE = 'source'
|
|||||||
ATTR_FEATURES = 'features'
|
ATTR_FEATURES = 'features'
|
||||||
ATTR_ADDONS = 'addons'
|
ATTR_ADDONS = 'addons'
|
||||||
ATTR_VERSION = 'version'
|
ATTR_VERSION = 'version'
|
||||||
|
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_BETA_CHANNEL = 'beta_channel'
|
ATTR_BETA_CHANNEL = 'beta_channel'
|
||||||
|
@ -42,8 +42,8 @@ class HassIO(object):
|
|||||||
self.scheduler = Scheduler(loop)
|
self.scheduler = Scheduler(loop)
|
||||||
self.api = RestAPI(config, loop)
|
self.api = RestAPI(config, loop)
|
||||||
self.hardware = Hardware()
|
self.hardware = Hardware()
|
||||||
self.docker = DockerAPI()
|
self.docker = DockerAPI(self.hardware)
|
||||||
self.dns = DNSForward()
|
self.dns = DNSForward(loop)
|
||||||
|
|
||||||
# init basic docker container
|
# init basic docker container
|
||||||
self.supervisor = DockerSupervisor(
|
self.supervisor = DockerSupervisor(
|
||||||
|
@ -11,8 +11,9 @@ COMMAND = "socat UDP-RECVFROM:53,fork UDP-SENDTO:127.0.0.11:53"
|
|||||||
class DNSForward(object):
|
class DNSForward(object):
|
||||||
"""Manage DNS forwarding to internal DNS."""
|
"""Manage DNS forwarding to internal DNS."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, loop):
|
||||||
"""Initialize DNS forwarding."""
|
"""Initialize DNS forwarding."""
|
||||||
|
self.loop = loop
|
||||||
self.proc = None
|
self.proc = None
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
@ -23,6 +24,7 @@ class DNSForward(object):
|
|||||||
stdin=asyncio.subprocess.DEVNULL,
|
stdin=asyncio.subprocess.DEVNULL,
|
||||||
stdout=asyncio.subprocess.DEVNULL,
|
stdout=asyncio.subprocess.DEVNULL,
|
||||||
stderr=asyncio.subprocess.DEVNULL,
|
stderr=asyncio.subprocess.DEVNULL,
|
||||||
|
loop=self.loop
|
||||||
)
|
)
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
_LOGGER.error("Can't start DNS forwarding -> %s", err)
|
_LOGGER.error("Can't start DNS forwarding -> %s", err)
|
||||||
|
@ -16,11 +16,12 @@ class DockerAPI(object):
|
|||||||
This class is not AsyncIO safe!
|
This class is not AsyncIO safe!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, hardware):
|
||||||
"""Initialize docker base wrapper."""
|
"""Initialize docker base wrapper."""
|
||||||
self.docker = docker.DockerClient(
|
self.docker = docker.DockerClient(
|
||||||
base_url="unix:/{}".format(str(SOCKET_DOCKER)), version='auto')
|
base_url="unix:/{}".format(str(SOCKET_DOCKER)), version='auto')
|
||||||
self.network = DockerNetwork(self.docker)
|
self.network = DockerNetwork(self.docker)
|
||||||
|
self.hardware = hardware
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def images(self):
|
def images(self):
|
||||||
|
@ -80,14 +80,17 @@ class DockerAddon(DockerInterface):
|
|||||||
"""Return needed devices."""
|
"""Return needed devices."""
|
||||||
devices = self.addon.devices or []
|
devices = self.addon.devices or []
|
||||||
|
|
||||||
# use audio devices
|
# Use audio devices
|
||||||
if self.addon.with_audio and AUDIO_DEVICE not in devices:
|
if self.addon.with_audio and AUDIO_DEVICE not in devices:
|
||||||
devices.append(AUDIO_DEVICE)
|
devices.append(AUDIO_DEVICE)
|
||||||
|
|
||||||
|
# Auto mapping UART devices
|
||||||
|
if self.addon.auto_uart:
|
||||||
|
for uart_dev in self.docker.hardware.serial_devices:
|
||||||
|
devices.append("{0}:{0}:rwm".format(uart_dev))
|
||||||
|
|
||||||
# Return None if no devices is present
|
# Return None if no devices is present
|
||||||
if devices:
|
return devices or None
|
||||||
return devices
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ports(self):
|
def ports(self):
|
||||||
|
@ -35,7 +35,7 @@ class Hardware(object):
|
|||||||
"""Return all serial and connected devices."""
|
"""Return all serial and connected devices."""
|
||||||
dev_list = set()
|
dev_list = set()
|
||||||
for device in self.context.list_devices(subsystem='tty'):
|
for device in self.context.list_devices(subsystem='tty'):
|
||||||
if 'ID_VENDOR' in device or RE_TTY.match(device.device_node):
|
if 'ID_VENDOR' in device or RE_TTY.search(device.device_node):
|
||||||
dev_list.add(device.device_node)
|
dev_list.add(device.device_node)
|
||||||
|
|
||||||
return dev_list
|
return dev_list
|
||||||
|
Loading…
x
Reference in New Issue
Block a user