mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-27 02:56:31 +00:00
Fix version conflict
This commit is contained in:
commit
0d4a5a7ffb
2
API.md
2
API.md
@ -427,6 +427,8 @@ Get all available addons.
|
|||||||
"host_ipc": "bool",
|
"host_ipc": "bool",
|
||||||
"host_dbus": "bool",
|
"host_dbus": "bool",
|
||||||
"privileged": ["NET_ADMIN", "SYS_ADMIN"],
|
"privileged": ["NET_ADMIN", "SYS_ADMIN"],
|
||||||
|
"seccomp": "disable|default|profile",
|
||||||
|
"apparmor": "disable|default|profile",
|
||||||
"devices": ["/dev/xy"],
|
"devices": ["/dev/xy"],
|
||||||
"auto_uart": "bool",
|
"auto_uart": "bool",
|
||||||
"icon": "bool",
|
"icon": "bool",
|
||||||
|
@ -23,7 +23,9 @@ 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_AUTO_UART, ATTR_DISCOVERY, ATTR_SERVICES)
|
ATTR_HOST_DBUS, ATTR_AUTO_UART, ATTR_DISCOVERY, ATTR_SERVICES,
|
||||||
|
ATTR_SECCOMP, ATTR_APPARMOR, SECURITY_PROFILE, SECURITY_DISABLE,
|
||||||
|
SECURITY_DEFAULT)
|
||||||
from ..coresys import CoreSysAttributes
|
from ..coresys import CoreSysAttributes
|
||||||
from ..docker.addon import DockerAddon
|
from ..docker.addon import DockerAddon
|
||||||
from ..utils.json import write_json_file, read_json_file
|
from ..utils.json import write_json_file, read_json_file
|
||||||
@ -316,6 +318,24 @@ class Addon(CoreSysAttributes):
|
|||||||
"""Return list of privilege."""
|
"""Return list of privilege."""
|
||||||
return self._mesh.get(ATTR_PRIVILEGED)
|
return self._mesh.get(ATTR_PRIVILEGED)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def seccomp(self):
|
||||||
|
"""Return True if seccomp is enabled."""
|
||||||
|
if not self._mesh.get(ATTR_SECCOMP):
|
||||||
|
return SECURITY_DISABLE
|
||||||
|
elif self.path_seccomp.exists():
|
||||||
|
return SECURITY_PROFILE
|
||||||
|
return SECURITY_DEFAULT
|
||||||
|
|
||||||
|
@property
|
||||||
|
def apparmor(self):
|
||||||
|
"""Return True if seccomp is enabled."""
|
||||||
|
if not self._mesh.get(ATTR_APPARMOR):
|
||||||
|
return SECURITY_DISABLE
|
||||||
|
elif self.path_apparmor.exists():
|
||||||
|
return SECURITY_PROFILE
|
||||||
|
return SECURITY_DEFAULT
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def legacy(self):
|
def legacy(self):
|
||||||
"""Return if the add-on don't support hass labels."""
|
"""Return if the add-on don't support hass labels."""
|
||||||
@ -474,6 +494,16 @@ class Addon(CoreSysAttributes):
|
|||||||
"""Return path to addon changelog."""
|
"""Return path to addon changelog."""
|
||||||
return Path(self.path_location, 'CHANGELOG.md')
|
return Path(self.path_location, 'CHANGELOG.md')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def path_seccomp(self):
|
||||||
|
"""Return path to custom seccomp profile."""
|
||||||
|
return Path(self.path_location, 'seccomp.json')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def path_apparmor(self):
|
||||||
|
"""Return path to custom AppArmor profile."""
|
||||||
|
return Path(self.path_location, 'apparmor')
|
||||||
|
|
||||||
def save_data(self):
|
def save_data(self):
|
||||||
"""Save data of addon."""
|
"""Save data of addon."""
|
||||||
self._addons.data.save_data()
|
self._addons.data.save_data()
|
||||||
|
@ -55,8 +55,8 @@ class AddonBuild(JsonConfig, CoreSysAttributes):
|
|||||||
'io.hass.version': version,
|
'io.hass.version': version,
|
||||||
'io.hass.arch': self._arch,
|
'io.hass.arch': self._arch,
|
||||||
'io.hass.type': META_ADDON,
|
'io.hass.type': META_ADDON,
|
||||||
'io.hass.name': self.addon.name,
|
'io.hass.name': self._fix_label('name'),
|
||||||
'io.hass.description': self.addon.description,
|
'io.hass.description': self._fix_label('description'),
|
||||||
},
|
},
|
||||||
'buildargs': {
|
'buildargs': {
|
||||||
'BUILD_FROM': self.base_image,
|
'BUILD_FROM': self.base_image,
|
||||||
@ -70,3 +70,8 @@ class AddonBuild(JsonConfig, CoreSysAttributes):
|
|||||||
args['labels']['io.hass.url'] = self.addon.url
|
args['labels']['io.hass.url'] = self.addon.url
|
||||||
|
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
def _fix_label(self, label_name):
|
||||||
|
"""Remove characters they are not supported."""
|
||||||
|
label = getattr(self.addon, label_name, "")
|
||||||
|
return label.replace("'", "")
|
||||||
|
@ -17,7 +17,8 @@ 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_AUTO_UART, ATTR_SERVICES, ATTR_DISCOVERY)
|
ATTR_HOST_DBUS, ATTR_AUTO_UART, ATTR_SERVICES, ATTR_DISCOVERY,
|
||||||
|
ATTR_SECCOMP, ATTR_APPARMOR)
|
||||||
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__)
|
||||||
@ -107,6 +108,8 @@ SCHEMA_ADDON_CONFIG = vol.Schema({
|
|||||||
vol.Optional(ATTR_MAP, default=list): [vol.Match(RE_VOLUME)],
|
vol.Optional(ATTR_MAP, default=list): [vol.Match(RE_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_SECCOMP, default=True): vol.Boolean(),
|
||||||
|
vol.Optional(ATTR_APPARMOR, default=True): vol.Boolean(),
|
||||||
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_HASSIO_API, default=False): vol.Boolean(),
|
vol.Optional(ATTR_HASSIO_API, default=False): vol.Boolean(),
|
||||||
|
@ -51,178 +51,163 @@ class RestAPI(CoreSysAttributes):
|
|||||||
api_host = APIHost()
|
api_host = APIHost()
|
||||||
api_host.coresys = self.coresys
|
api_host.coresys = self.coresys
|
||||||
|
|
||||||
self.webapp.router.add_get('/host/info', api_host.info)
|
self.webapp.add_routes([
|
||||||
self.webapp.router.add_get('/host/hardware', api_host.hardware)
|
web.get('/host/info', api_host.info),
|
||||||
self.webapp.router.add_post('/host/reboot', api_host.reboot)
|
web.get('/host/hardware', api_host.hardware),
|
||||||
self.webapp.router.add_post('/host/shutdown', api_host.shutdown)
|
web.post('/host/reboot', api_host.reboot),
|
||||||
self.webapp.router.add_post('/host/update', api_host.update)
|
web.post('/host/shutdown', api_host.shutdown),
|
||||||
self.webapp.router.add_post('/host/options', api_host.options)
|
web.post('/host/update', api_host.update),
|
||||||
self.webapp.router.add_post('/host/reload', api_host.reload)
|
web.post('/host/options', api_host.options),
|
||||||
|
web.post('/host/reload', api_host.reload),
|
||||||
|
])
|
||||||
|
|
||||||
def _register_network(self):
|
def _register_network(self):
|
||||||
"""Register network function."""
|
"""Register network function."""
|
||||||
api_net = APINetwork()
|
api_net = APINetwork()
|
||||||
api_net.coresys = self.coresys
|
api_net.coresys = self.coresys
|
||||||
|
|
||||||
self.webapp.router.add_get('/network/info', api_net.info)
|
self.webapp.add_routes([
|
||||||
self.webapp.router.add_post('/network/options', api_net.options)
|
web.get('/network/info', api_net.info),
|
||||||
|
web.post('/network/options', api_net.options),
|
||||||
|
])
|
||||||
|
|
||||||
def _register_supervisor(self):
|
def _register_supervisor(self):
|
||||||
"""Register supervisor function."""
|
"""Register supervisor function."""
|
||||||
api_supervisor = APISupervisor()
|
api_supervisor = APISupervisor()
|
||||||
api_supervisor.coresys = self.coresys
|
api_supervisor.coresys = self.coresys
|
||||||
|
|
||||||
self.webapp.router.add_get('/supervisor/ping', api_supervisor.ping)
|
self.webapp.add_routes([
|
||||||
self.webapp.router.add_get('/supervisor/info', api_supervisor.info)
|
web.get('/supervisor/ping', api_supervisor.ping),
|
||||||
self.webapp.router.add_get('/supervisor/stats', api_supervisor.stats)
|
web.get('/supervisor/info', api_supervisor.info),
|
||||||
self.webapp.router.add_post(
|
web.get('/supervisor/stats', api_supervisor.stats),
|
||||||
'/supervisor/update', api_supervisor.update)
|
web.get('/supervisor/logs', api_supervisor.logs),
|
||||||
self.webapp.router.add_post(
|
web.post('/supervisor/update', api_supervisor.update),
|
||||||
'/supervisor/reload', api_supervisor.reload)
|
web.post('/supervisor/reload', api_supervisor.reload),
|
||||||
self.webapp.router.add_post(
|
web.post('/supervisor/options', api_supervisor.options),
|
||||||
'/supervisor/options', api_supervisor.options)
|
])
|
||||||
self.webapp.router.add_get('/supervisor/logs', api_supervisor.logs)
|
|
||||||
|
|
||||||
def _register_homeassistant(self):
|
def _register_homeassistant(self):
|
||||||
"""Register homeassistant function."""
|
"""Register homeassistant function."""
|
||||||
api_hass = APIHomeAssistant()
|
api_hass = APIHomeAssistant()
|
||||||
api_hass.coresys = self.coresys
|
api_hass.coresys = self.coresys
|
||||||
|
|
||||||
self.webapp.router.add_get('/homeassistant/info', api_hass.info)
|
self.webapp.add_routes([
|
||||||
self.webapp.router.add_get('/homeassistant/logs', api_hass.logs)
|
web.get('/homeassistant/info', api_hass.info),
|
||||||
self.webapp.router.add_get('/homeassistant/stats', api_hass.stats)
|
web.get('/homeassistant/logs', api_hass.logs),
|
||||||
self.webapp.router.add_post('/homeassistant/options', api_hass.options)
|
web.get('/homeassistant/stats', api_hass.stats),
|
||||||
self.webapp.router.add_post('/homeassistant/update', api_hass.update)
|
web.post('/homeassistant/options', api_hass.options),
|
||||||
self.webapp.router.add_post('/homeassistant/restart', api_hass.restart)
|
web.post('/homeassistant/update', api_hass.update),
|
||||||
self.webapp.router.add_post('/homeassistant/stop', api_hass.stop)
|
web.post('/homeassistant/restart', api_hass.restart),
|
||||||
self.webapp.router.add_post('/homeassistant/start', api_hass.start)
|
web.post('/homeassistant/stop', api_hass.stop),
|
||||||
self.webapp.router.add_post('/homeassistant/check', api_hass.check)
|
web.post('/homeassistant/start', api_hass.start),
|
||||||
|
web.post('/homeassistant/check', api_hass.check),
|
||||||
|
])
|
||||||
|
|
||||||
def _register_proxy(self):
|
def _register_proxy(self):
|
||||||
"""Register HomeAssistant API Proxy."""
|
"""Register HomeAssistant API Proxy."""
|
||||||
api_proxy = APIProxy()
|
api_proxy = APIProxy()
|
||||||
api_proxy.coresys = self.coresys
|
api_proxy.coresys = self.coresys
|
||||||
|
|
||||||
self.webapp.router.add_get(
|
self.webapp.add_routes([
|
||||||
'/homeassistant/api/websocket', api_proxy.websocket)
|
web.get('/homeassistant/api/websocket', api_proxy.websocket),
|
||||||
self.webapp.router.add_get(
|
web.get('/homeassistant/websocket', api_proxy.websocket),
|
||||||
'/homeassistant/websocket', api_proxy.websocket)
|
web.get('/homeassistant/api/stream', api_proxy.stream),
|
||||||
self.webapp.router.add_get(
|
web.post('/homeassistant/api/{path:.+}', api_proxy.api),
|
||||||
'/homeassistant/api/stream', api_proxy.stream)
|
web.get('/homeassistant/api/{path:.+}', api_proxy.api),
|
||||||
self.webapp.router.add_post(
|
web.get('/homeassistant/api/', api_proxy.api),
|
||||||
'/homeassistant/api/{path:.+}', api_proxy.api)
|
])
|
||||||
self.webapp.router.add_get(
|
|
||||||
'/homeassistant/api/{path:.+}', api_proxy.api)
|
|
||||||
self.webapp.router.add_get(
|
|
||||||
'/homeassistant/api/', api_proxy.api)
|
|
||||||
|
|
||||||
def _register_addons(self):
|
def _register_addons(self):
|
||||||
"""Register homeassistant function."""
|
"""Register homeassistant function."""
|
||||||
api_addons = APIAddons()
|
api_addons = APIAddons()
|
||||||
api_addons.coresys = self.coresys
|
api_addons.coresys = self.coresys
|
||||||
|
|
||||||
self.webapp.router.add_get('/addons', api_addons.list)
|
self.webapp.add_routes([
|
||||||
self.webapp.router.add_post('/addons/reload', api_addons.reload)
|
web.get('/addons', api_addons.list),
|
||||||
self.webapp.router.add_get('/addons/{addon}/info', api_addons.info)
|
web.post('/addons/reload', api_addons.reload),
|
||||||
self.webapp.router.add_post(
|
web.get('/addons/{addon}/info', api_addons.info),
|
||||||
'/addons/{addon}/install', api_addons.install)
|
web.post('/addons/{addon}/install', api_addons.install),
|
||||||
self.webapp.router.add_post(
|
web.post('/addons/{addon}/uninstall', api_addons.uninstall),
|
||||||
'/addons/{addon}/uninstall', api_addons.uninstall)
|
web.post('/addons/{addon}/start', api_addons.start),
|
||||||
self.webapp.router.add_post('/addons/{addon}/start', api_addons.start)
|
web.post('/addons/{addon}/stop', api_addons.stop),
|
||||||
self.webapp.router.add_post('/addons/{addon}/stop', api_addons.stop)
|
web.post('/addons/{addon}/restart', api_addons.restart),
|
||||||
self.webapp.router.add_post(
|
web.post('/addons/{addon}/update', api_addons.update),
|
||||||
'/addons/{addon}/restart', api_addons.restart)
|
web.post('/addons/{addon}/options', api_addons.options),
|
||||||
self.webapp.router.add_post(
|
web.post('/addons/{addon}/rebuild', api_addons.rebuild),
|
||||||
'/addons/{addon}/update', api_addons.update)
|
web.get('/addons/{addon}/logs', api_addons.logs),
|
||||||
self.webapp.router.add_post(
|
web.get('/addons/{addon}/icon', api_addons.icon),
|
||||||
'/addons/{addon}/options', api_addons.options)
|
web.get('/addons/{addon}/logo', api_addons.logo),
|
||||||
self.webapp.router.add_post(
|
web.get('/addons/{addon}/changelog', api_addons.changelog),
|
||||||
'/addons/{addon}/rebuild', api_addons.rebuild)
|
web.post('/addons/{addon}/stdin', api_addons.stdin),
|
||||||
self.webapp.router.add_get('/addons/{addon}/logs', api_addons.logs)
|
web.get('/addons/{addon}/stats', api_addons.stats),
|
||||||
self.webapp.router.add_get('/addons/{addon}/icon', api_addons.icon)
|
])
|
||||||
self.webapp.router.add_get('/addons/{addon}/logo', api_addons.logo)
|
|
||||||
self.webapp.router.add_get(
|
|
||||||
'/addons/{addon}/changelog', api_addons.changelog)
|
|
||||||
self.webapp.router.add_post('/addons/{addon}/stdin', api_addons.stdin)
|
|
||||||
self.webapp.router.add_get('/addons/{addon}/stats', api_addons.stats)
|
|
||||||
|
|
||||||
def _register_snapshots(self):
|
def _register_snapshots(self):
|
||||||
"""Register snapshots function."""
|
"""Register snapshots function."""
|
||||||
api_snapshots = APISnapshots()
|
api_snapshots = APISnapshots()
|
||||||
api_snapshots.coresys = self.coresys
|
api_snapshots.coresys = self.coresys
|
||||||
|
|
||||||
self.webapp.router.add_get('/snapshots', api_snapshots.list)
|
self.webapp.add_routes([
|
||||||
self.webapp.router.add_post('/snapshots/reload', api_snapshots.reload)
|
web.get('/snapshots', api_snapshots.list),
|
||||||
|
web.post('/snapshots/reload', api_snapshots.reload),
|
||||||
self.webapp.router.add_post(
|
web.post('/snapshots/new/full', api_snapshots.snapshot_full),
|
||||||
'/snapshots/new/full', api_snapshots.snapshot_full)
|
web.post('/snapshots/new/partial', api_snapshots.snapshot_partial),
|
||||||
self.webapp.router.add_post(
|
web.post('/snapshots/new/upload', api_snapshots.upload),
|
||||||
'/snapshots/new/partial', api_snapshots.snapshot_partial)
|
web.get('/snapshots/{snapshot}/info', api_snapshots.info),
|
||||||
self.webapp.router.add_post(
|
web.post('/snapshots/{snapshot}/remove', api_snapshots.remove),
|
||||||
'/snapshots/new/upload', api_snapshots.upload)
|
web.post('/snapshots/{snapshot}/restore/full',
|
||||||
|
api_snapshots.restore_full),
|
||||||
self.webapp.router.add_get(
|
web.post('/snapshots/{snapshot}/restore/partial',
|
||||||
'/snapshots/{snapshot}/info', api_snapshots.info)
|
api_snapshots.restore_partial),
|
||||||
self.webapp.router.add_post(
|
web.get('/snapshots/{snapshot}/download', api_snapshots.download),
|
||||||
'/snapshots/{snapshot}/remove', api_snapshots.remove)
|
])
|
||||||
self.webapp.router.add_post(
|
|
||||||
'/snapshots/{snapshot}/restore/full', api_snapshots.restore_full)
|
|
||||||
self.webapp.router.add_post(
|
|
||||||
'/snapshots/{snapshot}/restore/partial',
|
|
||||||
api_snapshots.restore_partial)
|
|
||||||
self.webapp.router.add_get(
|
|
||||||
'/snapshots/{snapshot}/download',
|
|
||||||
api_snapshots.download)
|
|
||||||
|
|
||||||
def _register_services(self):
|
def _register_services(self):
|
||||||
api_services = APIServices()
|
api_services = APIServices()
|
||||||
api_services.coresys = self.coresys
|
api_services.coresys = self.coresys
|
||||||
|
|
||||||
self.webapp.router.add_get('/services', api_services.list)
|
self.webapp.add_routes([
|
||||||
|
web.get('/services', api_services.list),
|
||||||
self.webapp.router.add_get(
|
web.get('/services/{service}', api_services.get_service),
|
||||||
'/services/{service}', api_services.get_service)
|
web.post('/services/{service}', api_services.set_service),
|
||||||
self.webapp.router.add_post(
|
web.delete('/services/{service}', api_services.del_service),
|
||||||
'/services/{service}', api_services.set_service)
|
])
|
||||||
self.webapp.router.add_delete(
|
|
||||||
'/services/{service}', api_services.del_service)
|
|
||||||
|
|
||||||
def _register_discovery(self):
|
def _register_discovery(self):
|
||||||
api_discovery = APIDiscovery()
|
api_discovery = APIDiscovery()
|
||||||
api_discovery.coresys = self.coresys
|
api_discovery.coresys = self.coresys
|
||||||
|
|
||||||
self.webapp.router.add_get(
|
self.webapp.add_routes([
|
||||||
'/services/discovery', api_discovery.list)
|
web.get('/services/discovery', api_discovery.list),
|
||||||
self.webapp.router.add_get(
|
web.get('/services/discovery/{uuid}', api_discovery.get_discovery),
|
||||||
'/services/discovery/{uuid}', api_discovery.get_discovery)
|
web.delete('/services/discovery/{uuid}',
|
||||||
self.webapp.router.add_delete(
|
api_discovery.del_discovery),
|
||||||
'/services/discovery/{uuid}', api_discovery.del_discovery)
|
web.post('/services/discovery', api_discovery.set_discovery),
|
||||||
self.webapp.router.add_post(
|
])
|
||||||
'/services/discovery', api_discovery.set_discovery)
|
|
||||||
|
|
||||||
def _register_panel(self):
|
def _register_panel(self):
|
||||||
"""Register panel for homeassistant."""
|
"""Register panel for homeassistant."""
|
||||||
def create_panel_response(build_type):
|
def create_response(build_type):
|
||||||
"""Create a function to generate a response."""
|
"""Create a function to generate a response."""
|
||||||
path = Path(__file__).parent.joinpath(
|
path = Path(__file__).parent.joinpath(
|
||||||
f"panel/{build_type}.html")
|
f"panel/{build_type}.html")
|
||||||
return lambda request: web.FileResponse(path)
|
return lambda request: web.FileResponse(path)
|
||||||
|
|
||||||
# This route is for backwards compatibility with HA < 0.58
|
# This route is for backwards compatibility with HA < 0.58
|
||||||
self.webapp.router.add_get(
|
self.webapp.add_routes([
|
||||||
'/panel', create_panel_response('hassio-main-es5'))
|
web.get('/panel', create_response('hassio-main-es5'))])
|
||||||
|
|
||||||
# This route is for backwards compatibility with HA 0.58 - 0.61
|
# This route is for backwards compatibility with HA 0.58 - 0.61
|
||||||
self.webapp.router.add_get(
|
self.webapp.add_routes([
|
||||||
'/panel_es5', create_panel_response('hassio-main-es5'))
|
web.get('/panel_es5', create_response('hassio-main-es5')),
|
||||||
self.webapp.router.add_get(
|
web.get('/panel_latest', create_response('hassio-main-latest')),
|
||||||
'/panel_latest', create_panel_response('hassio-main-latest'))
|
])
|
||||||
|
|
||||||
# This route is for HA > 0.61
|
# This route is for HA > 0.61
|
||||||
self.webapp.router.add_get(
|
self.webapp.add_routes([
|
||||||
'/app-es5/index.html', create_panel_response('index'))
|
web.get('/app-es5/index.html', create_response('index')),
|
||||||
self.webapp.router.add_get(
|
web.get('/app-es5/hassio-app.html', create_response('hassio-app')),
|
||||||
'/app-es5/hassio-app.html', create_panel_response('hassio-app'))
|
])
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
"""Run rest api webserver."""
|
"""Run rest api webserver."""
|
||||||
|
@ -17,7 +17,7 @@ from ..const import (
|
|||||||
ATTR_CHANGELOG, ATTR_HOST_IPC, ATTR_HOST_DBUS, ATTR_LONG_DESCRIPTION,
|
ATTR_CHANGELOG, ATTR_HOST_IPC, ATTR_HOST_DBUS, ATTR_LONG_DESCRIPTION,
|
||||||
ATTR_CPU_PERCENT, ATTR_MEMORY_LIMIT, ATTR_MEMORY_USAGE, ATTR_NETWORK_TX,
|
ATTR_CPU_PERCENT, ATTR_MEMORY_LIMIT, ATTR_MEMORY_USAGE, ATTR_NETWORK_TX,
|
||||||
ATTR_NETWORK_RX, ATTR_BLK_READ, ATTR_BLK_WRITE, ATTR_ICON, ATTR_SERVICES,
|
ATTR_NETWORK_RX, ATTR_BLK_READ, ATTR_BLK_WRITE, ATTR_ICON, ATTR_SERVICES,
|
||||||
ATTR_DISCOVERY,
|
ATTR_DISCOVERY, ATTR_SECCOMP, ATTR_APPARMOR,
|
||||||
CONTENT_TYPE_PNG, CONTENT_TYPE_BINARY, CONTENT_TYPE_TEXT)
|
CONTENT_TYPE_PNG, CONTENT_TYPE_BINARY, CONTENT_TYPE_TEXT)
|
||||||
from ..coresys import CoreSysAttributes
|
from ..coresys import CoreSysAttributes
|
||||||
from ..validate import DOCKER_PORTS
|
from ..validate import DOCKER_PORTS
|
||||||
@ -123,6 +123,8 @@ class APIAddons(CoreSysAttributes):
|
|||||||
ATTR_HOST_IPC: addon.host_ipc,
|
ATTR_HOST_IPC: addon.host_ipc,
|
||||||
ATTR_HOST_DBUS: addon.host_dbus,
|
ATTR_HOST_DBUS: addon.host_dbus,
|
||||||
ATTR_PRIVILEGED: addon.privileged,
|
ATTR_PRIVILEGED: addon.privileged,
|
||||||
|
ATTR_SECCOMP: addon.seccomp,
|
||||||
|
ATTR_APPARMOR: addon.apparmor,
|
||||||
ATTR_DEVICES: self._pretty_devices(addon),
|
ATTR_DEVICES: self._pretty_devices(addon),
|
||||||
ATTR_ICON: addon.with_icon,
|
ATTR_ICON: addon.with_icon,
|
||||||
ATTR_LOGO: addon.with_logo,
|
ATTR_LOGO: addon.with_logo,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ipaddress import ip_network
|
from ipaddress import ip_network
|
||||||
|
|
||||||
HASSIO_VERSION = '0.99'
|
HASSIO_VERSION = '1.0'
|
||||||
|
|
||||||
URL_HASSIO_VERSION = ('https://raw.githubusercontent.com/home-assistant/'
|
URL_HASSIO_VERSION = ('https://raw.githubusercontent.com/home-assistant/'
|
||||||
'hassio/{}/version.json')
|
'hassio/{}/version.json')
|
||||||
@ -159,6 +159,8 @@ ATTR_DISCOVERY = 'discovery'
|
|||||||
ATTR_PROTECTED = 'protected'
|
ATTR_PROTECTED = 'protected'
|
||||||
ATTR_CRYPTO = 'crypto'
|
ATTR_CRYPTO = 'crypto'
|
||||||
ATTR_BRANCH = 'branch'
|
ATTR_BRANCH = 'branch'
|
||||||
|
ATTR_SECCOMP = 'seccomp'
|
||||||
|
ATTR_APPARMOR = 'apparmor'
|
||||||
|
|
||||||
SERVICE_MQTT = 'mqtt'
|
SERVICE_MQTT = 'mqtt'
|
||||||
|
|
||||||
@ -202,3 +204,7 @@ SNAPSHOT_FULL = 'full'
|
|||||||
SNAPSHOT_PARTIAL = 'partial'
|
SNAPSHOT_PARTIAL = 'partial'
|
||||||
|
|
||||||
CRYPTO_AES128 = 'aes128'
|
CRYPTO_AES128 = 'aes128'
|
||||||
|
|
||||||
|
SECURITY_PROFILE = 'profile'
|
||||||
|
SECURITY_DEFAULT = 'default'
|
||||||
|
SECURITY_DISABLE = 'disable'
|
||||||
|
@ -9,7 +9,7 @@ from .interface import DockerInterface
|
|||||||
from ..addons.build import AddonBuild
|
from ..addons.build import AddonBuild
|
||||||
from ..const import (
|
from ..const import (
|
||||||
MAP_CONFIG, MAP_SSL, MAP_ADDONS, MAP_BACKUP, MAP_SHARE, ENV_TOKEN,
|
MAP_CONFIG, MAP_SSL, MAP_ADDONS, MAP_BACKUP, MAP_SHARE, ENV_TOKEN,
|
||||||
ENV_TIME)
|
ENV_TIME, SECURITY_PROFILE, SECURITY_DISABLE)
|
||||||
from ..utils import process_lock
|
from ..utils import process_lock
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -121,14 +121,21 @@ class DockerAddon(DockerInterface):
|
|||||||
@property
|
@property
|
||||||
def security_opt(self):
|
def security_opt(self):
|
||||||
"""Controlling security opt."""
|
"""Controlling security opt."""
|
||||||
privileged = self.addon.privileged or []
|
security = []
|
||||||
|
|
||||||
# Disable AppArmor sinse it make troubles wit SYS_ADMIN
|
# AppArmor
|
||||||
if 'SYS_ADMIN' in privileged:
|
if self.addon.apparmor == SECURITY_DISABLE:
|
||||||
return [
|
security.append("apparmor:unconfined")
|
||||||
"apparmor:unconfined",
|
elif self.addon.apparmor == SECURITY_PROFILE:
|
||||||
]
|
security.append(f"apparmor={self.addon.slug}")
|
||||||
return None
|
|
||||||
|
# Seccomp
|
||||||
|
if self.addon.seccomp == SECURITY_DISABLE:
|
||||||
|
security.append("seccomp=unconfined")
|
||||||
|
elif self.addon.seccomp == SECURITY_PROFILE:
|
||||||
|
security.append(f"seccomp={self.addon.path_seccomp}")
|
||||||
|
|
||||||
|
return security or None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tmpfs(self):
|
def tmpfs(self):
|
||||||
|
@ -264,31 +264,6 @@ class DockerInterface(CoreSysAttributes):
|
|||||||
except docker.errors.DockerException as err:
|
except docker.errors.DockerException as err:
|
||||||
_LOGGER.warning("Can't grap logs from %s: %s", self.image, err)
|
_LOGGER.warning("Can't grap logs from %s: %s", self.image, err)
|
||||||
|
|
||||||
@process_lock
|
|
||||||
def restart(self):
|
|
||||||
"""Restart docker container."""
|
|
||||||
return self._loop.run_in_executor(None, self._restart)
|
|
||||||
|
|
||||||
def _restart(self):
|
|
||||||
"""Restart docker container.
|
|
||||||
|
|
||||||
Need run inside executor.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
container = self._docker.containers.get(self.name)
|
|
||||||
except docker.errors.DockerException:
|
|
||||||
return False
|
|
||||||
|
|
||||||
_LOGGER.info("Restart %s", self.image)
|
|
||||||
|
|
||||||
try:
|
|
||||||
container.restart(timeout=self.timeout)
|
|
||||||
except docker.errors.DockerException as err:
|
|
||||||
_LOGGER.warning("Can't restart %s: %s", self.image, err)
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
@process_lock
|
@process_lock
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
"""Check if old version exists and cleanup."""
|
"""Check if old version exists and cleanup."""
|
||||||
|
@ -216,17 +216,19 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
|
|||||||
|
|
||||||
async def _start(self):
|
async def _start(self):
|
||||||
"""Start HomeAssistant docker & wait."""
|
"""Start HomeAssistant docker & wait."""
|
||||||
if await self.instance.run():
|
|
||||||
await self._block_till_run()
|
|
||||||
|
|
||||||
@process_lock
|
|
||||||
async def start(self):
|
|
||||||
"""Run HomeAssistant docker."""
|
|
||||||
if not await self.instance.run():
|
if not await self.instance.run():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return await self._block_till_run()
|
return await self._block_till_run()
|
||||||
|
|
||||||
|
@process_lock
|
||||||
|
def start(self):
|
||||||
|
"""Run HomeAssistant docker.
|
||||||
|
|
||||||
|
Return a coroutine.
|
||||||
|
"""
|
||||||
|
return self._start()
|
||||||
|
|
||||||
|
@process_lock
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""Stop HomeAssistant docker.
|
"""Stop HomeAssistant docker.
|
||||||
|
|
||||||
@ -237,10 +239,8 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
|
|||||||
@process_lock
|
@process_lock
|
||||||
async def restart(self):
|
async def restart(self):
|
||||||
"""Restart HomeAssistant docker."""
|
"""Restart HomeAssistant docker."""
|
||||||
if not await self.instance.restart():
|
await self.instance.stop()
|
||||||
return False
|
return await self._start()
|
||||||
|
|
||||||
return await self._block_till_run()
|
|
||||||
|
|
||||||
def logs(self):
|
def logs(self):
|
||||||
"""Get HomeAssistant docker logs.
|
"""Get HomeAssistant docker logs.
|
||||||
|
6
setup.py
6
setup.py
@ -40,9 +40,9 @@ setup(
|
|||||||
],
|
],
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'async_timeout==2.0.0',
|
'async_timeout==2.0.1',
|
||||||
'aiohttp==3.0.9',
|
'aiohttp==3.1.2',
|
||||||
'docker==3.1.1',
|
'docker==3.2.0',
|
||||||
'colorlog==3.1.2',
|
'colorlog==3.1.2',
|
||||||
'voluptuous==0.11.1',
|
'voluptuous==0.11.1',
|
||||||
'gitpython==2.1.8',
|
'gitpython==2.1.8',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"hassio": "0.99",
|
"hassio": "1.0",
|
||||||
"homeassistant": "0.67.0b0",
|
"homeassistant": "0.67.0b0",
|
||||||
"resinos": "1.3",
|
"resinos": "1.3",
|
||||||
"resinhup": "0.3",
|
"resinhup": "0.3",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user