diff --git a/API.md b/API.md index 08aa71395..b2d05a818 100644 --- a/API.md +++ b/API.md @@ -435,6 +435,10 @@ Output is the raw Docker log. - POST `/addons/{addon}/restart` +- POST `/addons/{addon}/rebuild` + +Only supported for local build addons + ## Host Control Communicate over UNIX socket with a host daemon. diff --git a/hassio/addons/addon.py b/hassio/addons/addon.py index 474756116..1a5666bc8 100644 --- a/hassio/addons/addon.py +++ b/hassio/addons/addon.py @@ -8,6 +8,7 @@ import shutil import tarfile from tempfile import TemporaryDirectory +from deepmerge import Merger import voluptuous as vol from voluptuous.humanize import humanize_error @@ -30,6 +31,8 @@ _LOGGER = logging.getLogger(__name__) RE_VOLUME = re.compile(MAP_VOLUME) RE_WEBUI = re.compile(r"^(.*\[HOST\]:)\[PORT:(\d+)\](.*)$") +MERGE_OPT = Merger([(dict, ['merge'])], ['override'], ['override']) + class Addon(object): """Hold data for addon inside HassIO.""" @@ -104,10 +107,10 @@ class Addon(object): def options(self): """Return options with local changes.""" if self.is_installed: - return { - **self.data.system[self._id][ATTR_OPTIONS], - **self.data.user[self._id][ATTR_OPTIONS], - } + return MERGE_OPT.merge( + self.data.system[self._id][ATTR_OPTIONS], + self.data.user[self._id][ATTR_OPTIONS], + ) return self.data.cache[self._id][ATTR_OPTIONS] @options.setter @@ -515,6 +518,27 @@ class Addon(object): """ return self.docker.logs() + @check_installed + async def rebuild(self): + """Performe a rebuild of local build addon.""" + last_state = await self.state() + + if not self.need_build: + _LOGGER.error("Can't rebuild a none local build addon!") + return False + + # remove docker container but not addon config + if not await self.docker.remove(): + return False + + if not await self.docker.install(self.version_installed): + return False + + # restore state + if last_state == STATE_STARTED: + await self.docker.run() + return True + @check_installed async def snapshot(self, tar_file): """Snapshot a state of a addon.""" diff --git a/hassio/api/__init__.py b/hassio/api/__init__.py index 645a4fca4..6323d8785 100644 --- a/hassio/api/__init__.py +++ b/hassio/api/__init__.py @@ -94,6 +94,8 @@ class RestAPI(object): '/addons/{addon}/update', api_addons.update) self.webapp.router.add_post( '/addons/{addon}/options', api_addons.options) + self.webapp.router.add_post( + '/addons/{addon}/rebuild', api_addons.rebuild) self.webapp.router.add_get('/addons/{addon}/logs', api_addons.logs) self.webapp.router.add_get('/addons/{addon}/logo', api_addons.logo) diff --git a/hassio/api/addons.py b/hassio/api/addons.py index b0dc165f9..e4e14ac87 100644 --- a/hassio/api/addons.py +++ b/hassio/api/addons.py @@ -213,6 +213,15 @@ class APIAddons(object): addon = self._extract_addon(request) return asyncio.shield(addon.restart(), loop=self.loop) + @api_process + def rebuild(self, request): + """Rebuild local build addon.""" + addon = self._extract_addon(request) + if not addon.need_build: + raise RuntimeError("Only local build addons are supported") + + return asyncio.shield(addon.rebuild(), loop=self.loop) + @api_process_raw(CONTENT_TYPE_BINARY) def logs(self, request): """Return logs from addon.""" diff --git a/hassio/const.py b/hassio/const.py index 19bbce092..5f575433a 100644 --- a/hassio/const.py +++ b/hassio/const.py @@ -1,7 +1,7 @@ """Const file for HassIO.""" from pathlib import Path -HASSIO_VERSION = '0.56' +HASSIO_VERSION = '0.57' URL_HASSIO_VERSION = ('https://raw.githubusercontent.com/home-assistant/' 'hassio/{}/version.json') diff --git a/hassio/dock/addon.py b/hassio/dock/addon.py index bbc119960..b7f9b083e 100644 --- a/hassio/dock/addon.py +++ b/hassio/dock/addon.py @@ -203,7 +203,9 @@ class DockerAddon(DockerBase): _LOGGER.info("Start build %s on %s", build_tag, build_dir) image = self.dock.images.build( - path=str(build_dir), tag=build_tag, pull=True) + path=str(build_dir), tag=build_tag, pull=True, + forcerm=True + ) image.tag(self.image, tag='latest') self.process_metadata(image.attrs, force=True) diff --git a/hassio/panel/hassio-main.html b/hassio/panel/hassio-main.html index a2347372f..221227634 100644 --- a/hassio/panel/hassio-main.html +++ b/hassio/panel/hassio-main.html @@ -1 +1,75 @@ -
Hostname | [[data.hostname]] |
Type | [[data.type]] |
OS | [[data.os]] |
Host Control version | [[data.version]] |
Latest available version | [[data.last_version]] |
Current version | [[data.version]] |
Latest version | [[data.last_version]] |
Version | [[data.version]] |
Beta channel | [[data.beta_channel]] |
Latest available version | [[data.last_version]] |
[[addonLogs]]
Configure which add-on repositories to fetch data from. One repository per line.
[[addon.description]]
Made available via repository [[addon.repository]].
This add-on will built locally on the device.
[[logs]]
[[_error]]
Looks like you don't have any snapshots yet.
Hostname | [[data.hostname]] |
Type | [[data.type]] |
OS | [[data.os]] |
Host Control version | [[data.version]] |
Latest available version | [[data.last_version]] |
Current version | [[data.version]] |
Latest version | [[data.last_version]] |
Version | [[data.version]] |
Beta channel | [[data.beta_channel]] |
Latest available version | [[data.last_version]] |
Container | Host |
---|---|
[[item.container]] |
[[addonLogs]]
Configure which add-on repositories to fetch data from. One repository per line.
[[addon.description]]
Made available via repository [[addon.repository]].
This add-on will built locally on the device.
[[logs]]
[[_error]]
Looks like you don't have any snapshots yet.