This commit is contained in:
Pascal Vizeli 2018-04-23 15:32:23 +02:00
parent 42dd4d9557
commit b486883ff6
13 changed files with 132 additions and 56 deletions

View File

@ -5,7 +5,6 @@ import logging
import sys
import hassio.bootstrap as bootstrap
import hassio.core as core
_LOGGER = logging.getLogger(__name__)
@ -34,14 +33,13 @@ if __name__ == "__main__":
_LOGGER.info("Initialize Hassio setup")
coresys = bootstrap.initialize_coresys(loop)
hassio = core.HassIO(coresys)
bootstrap.migrate_system_env(coresys)
_LOGGER.info("Setup HassIO")
loop.run_until_complete(hassio.setup())
loop.run_until_complete(coresys.core.setup())
loop.call_soon_threadsafe(loop.create_task, hassio.start())
loop.call_soon_threadsafe(loop.create_task, coresys.core.start())
loop.call_soon_threadsafe(bootstrap.reg_signal, loop)
try:
@ -49,7 +47,7 @@ if __name__ == "__main__":
loop.run_forever()
finally:
_LOGGER.info("Stopping HassIO")
loop.run_until_complete(hassio.stop())
loop.run_until_complete(coresys.core.stop())
executor.shutdown(wait=False)
loop.close()

View File

@ -376,7 +376,7 @@ class Addon(CoreSysAttributes):
if self.is_installed and \
ATTR_AUDIO_OUTPUT in self._data.user[self._id]:
return self._data.user[self._id][ATTR_AUDIO_OUTPUT]
return self.sys_alsa.default.output
return self.sys_host.alsa.default.output
@audio_output.setter
def audio_output(self, value):
@ -394,7 +394,7 @@ class Addon(CoreSysAttributes):
if self.is_installed and ATTR_AUDIO_INPUT in self._data.user[self._id]:
return self._data.user[self._id][ATTR_AUDIO_INPUT]
return self.sys_alsa.default.input
return self.sys_host.alsa.default.input
@audio_input.setter
def audio_input(self, value):
@ -537,7 +537,7 @@ class Addon(CoreSysAttributes):
def write_asound(self):
"""Write asound config to file and return True on success."""
asound_config = self.sys_alsa.asound(
asound_config = self.sys_host.alsa.asound(
alsa_input=self.audio_input, alsa_output=self.audio_output)
try:

View File

@ -28,7 +28,7 @@ class APIHardware(CoreSysAttributes):
"""Show ALSA audio devices."""
return {
ATTR_AUDIO: {
ATTR_INPUT: self.sys_alsa.input_devices,
ATTR_OUTPUT: self.sys_alsa.output_devices,
ATTR_INPUT: self.sys_host.alsa.input_devices,
ATTR_OUTPUT: self.sys_host.alsa.output_devices,
}
}

View File

@ -7,6 +7,7 @@ from pathlib import Path
from colorlog import ColoredFormatter
from .core import HassIO
from .addons import AddonManager
from .api import RestAPI
from .const import SOCKET_DOCKER
@ -18,7 +19,6 @@ from .tasks import Tasks
from .updater import Updater
from .services import ServiceManager
from .services import Discovery
from .host import AlsaAudio
from .host import HostManager
from .dbus import DBusManager
@ -30,9 +30,9 @@ def initialize_coresys(loop):
coresys = CoreSys(loop)
# Initialize core objects
coresys.core = HassIO(coresys)
coresys.updater = Updater(coresys)
coresys.api = RestAPI(coresys)
coresys.alsa = AlsaAudio(coresys)
coresys.supervisor = Supervisor(coresys)
coresys.homeassistant = HomeAssistant(coresys)
coresys.addons = AddonManager(coresys)
@ -154,7 +154,12 @@ def check_environment():
# check socat exec
if not shutil.which('socat'):
_LOGGER.fatal("Can0t find socat program!")
_LOGGER.fatal("Can't find socat program!")
return False
# check socat exec
if not shutil.which('gdbus'):
_LOGGER.fatal("Can't find gdbus program!")
return False
return True

View File

@ -18,7 +18,6 @@ FILE_HASSIO_UPDATER = Path(HASSIO_DATA, "updater.json")
FILE_HASSIO_SERVICES = Path(HASSIO_DATA, "services.json")
SOCKET_DOCKER = Path("/var/run/docker.sock")
SOCKET_HC = Path("/var/run/hassio-hc.sock")
DOCKER_NETWORK = 'hassio'
DOCKER_NETWORK_MASK = ip_network('172.30.32.0/23')

View File

@ -23,16 +23,19 @@ class HassIO(CoreSysAttributes):
if self.sys_config.timezone == 'UTC':
self.sys_config.timezone = await fetch_timezone(self._websession)
# supervisor
# Load DBus
await self.sys_dbus.load()
# Load Host
await self.sys_host.load()
# Load Supervisor
await self.sys_supervisor.load()
# hostcontrol
await self._host_control.load()
# Load homeassistant
# Load Home Assistant
await self.sys_homeassistant.load()
# Load addons
# Load Add-ons
await self.sys_addons.load()
# rest api views
@ -50,9 +53,6 @@ class HassIO(CoreSysAttributes):
# start dns forwarding
self.sys_create_task(self.sys_dns.start())
# start addon mark as initialize
await self.sys_addons.auto_boot(STARTUP_INITIALIZE)
async def start(self):
"""Start HassIO orchestration."""
# on release channel, try update itself
@ -67,6 +67,9 @@ class HassIO(CoreSysAttributes):
await self.sys_api.start()
_LOGGER.info("Start API on %s", self.sys_docker.network.supervisor)
# start addon mark as initialize
await self.sys_addons.auto_boot(STARTUP_INITIALIZE)
try:
# HomeAssistant is already running / supervisor have only reboot
if self.sys_hardware.last_boot == self.sys_config.last_boot:

View File

@ -32,6 +32,7 @@ class CoreSys:
self._dns = DNSForward(loop=loop)
# Internal objects pointers
self._core = None
self._homeassistant = None
self._supervisor = None
self._addons = None
@ -40,9 +41,9 @@ class CoreSys:
self._snapshots = None
self._tasks = None
self._host = None
self._dbus = None
self._services = None
self._discovery = None
self._alsa = None
@property
def arch(self):
@ -104,9 +105,16 @@ class CoreSys:
return self._dns
@property
def systemd(self):
"""Return systemd object."""
return self._systemd
def core(self):
"""Return HassIO object."""
return self._core
@core.setter
def core(self, value):
"""Set a HassIO object."""
if self._core:
raise RuntimeError("HassIO already set!")
self._core = value
@property
def homeassistant(self):
@ -217,16 +225,16 @@ class CoreSys:
self._discovery = value
@property
def alsa(self):
"""Return ALSA Audio object."""
return self._alsa
def dbus(self):
"""Return DBusManager object."""
return self._dbus
@alsa.setter
def alsa(self, value):
"""Set a ALSA Audio object."""
if self._alsa:
raise RuntimeError("ALSA already set!")
self._alsa = value
@dbus.setter
def dbus(self, value):
"""Set a DBusManager object."""
if self._dbus:
raise RuntimeError("DBusManager already set!")
self._dbus = value
@property
def host(self):

View File

@ -7,8 +7,9 @@ from ..coresys import CoreSysAttributes
class DBusManager(CoreSysAttributes):
"""DBus Interface handler."""
def __init__(self):
def __init__(self, coresys):
"""Initialize DBus Interface."""
self.coresys = coresys
self._systemd = Systemd()
@property

1
hassio/dbus/hostname.py Normal file
View File

@ -0,0 +1 @@
"""DBus interface for hostname."""

View File

@ -1,8 +1,9 @@
"""Interface to Systemd over dbus."""
import logging
from ..exceptions import HassioInternalError
from ..utils.gdbus import DBus, DBusError
from .utils import dbus_connected
from ..exceptions import DBusError
from ..utils.gdbus import DBus
_LOGGER = logging.getLogger(__name__)
@ -29,18 +30,18 @@ class Systemd:
except DBusError:
_LOGGER.warning("Can't connect to systemd")
async def reboot(self):
"""Reboot host computer."""
try:
await self.dbus.Manager.Reboot()
except DBusError:
_LOGGER.error("Can't reboot host")
raise HassioInternalError() from None
@dbus_connected
def reboot(self):
"""Reboot host computer.
async def shutdown(self):
"""Shutdown host computer."""
try:
await self.dbus.Manager.PowerOff()
except DBusError:
_LOGGER.error("Can't PowerOff host")
raise HassioInternalError() from None
Return a coroutine.
"""
return self.dbus.Manager.Reboot()
@dbus_connected
def shutdown(self):
"""Shutdown host computer.
Return a coroutine.
"""
return self.dbus.Manager.PowerOff()

14
hassio/dbus/utils.py Normal file
View File

@ -0,0 +1,14 @@
"""Utils for dbus."""
from ..exceptions import HassioNotSupportedError
def dbus_connected(method):
"""Wrapper for check if dbus is connected."""
def wrap_dbus(self, *args, **kwargs):
"""Check if dbus is connected before call a method."""
if self.dbus is None:
raise HassioNotSupportedError(f"{self!s} not connected to dbus!")
return self.method(*args, **kwargs)
return wrap_dbus

View File

@ -1,6 +1,7 @@
"""Host function like audio/dbus/systemd."""
from .alsa import AlsaAudio # noqa
from .alsa import AlsaAudio
from .power import PowerControl
from ..const import FEATURES_REBOOT, FEATURES_SHUTDOWN
from ..coresys import CoreSysAttributes
@ -11,13 +12,25 @@ class HostManager(CoreSysAttributes):
def __init__(self, coresys):
"""Initialize Host manager."""
self.coresys = coresys
self._alsa = AlsaAudio(coresys)
self._power = PowerControl(coresys)
@property
def alsa(self):
"""Return host ALSA handler."""
return self._alsa
@property
def power(self):
"""Return host power handler."""
return self._power
@property
def supperted_features(self):
"""Return a list of supported host features."""
features = []
if self.sys_systemd.is_connected:
if self.sys_dbus.systemd.is_connected:
features.extend([
FEATURES_REBOOT,
FEATURES_SHUTDOWN,
@ -27,4 +40,4 @@ class HostManager(CoreSysAttributes):
async def load(self):
"""Load host functions."""
await self.sys_systemd.connect()
pass

33
hassio/host/power.py Normal file
View File

@ -0,0 +1,33 @@
"""Power control for host."""
from ..coresys import CoreSysAttributes
from ..exceptions import HassioNotSupportedError
class PowerControl(CoreSysAttributes):
"""Handle host power controls."""
def __init__(self, coresys):
"""Initialize host power handling."""
self.coresys = coresys
def _check_systemd(self):
"""Check if systemd is connect or raise error."""
if not self.sys_dbus.systemd.is_connected:
raise HassioNotSupportedError("No systemd connections")
async def reboot(self):
"""Reboot host system."""
self._check_systemd()
try:
await self.sys_core.shutdown()
finally:
await self.sys_dbus.systemd.reboot()
async def shutdown(self):
"""Shutdown host system."""
self._check_systemd()
try:
await self.sys_core.shutdown()
finally:
await self.sys_dbus.systemd.shutdown()