mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-14 04:36:31 +00:00
some cleanups / auto remove old addons.
This commit is contained in:
parent
dbc080c24d
commit
40e5e6eb9d
@ -40,6 +40,15 @@ class AddonManager(AddonsData):
|
||||
return
|
||||
self.read_addons_repo()
|
||||
|
||||
# remove stalled addons
|
||||
tasks = []
|
||||
for addon in self.list_removed:
|
||||
_LOGGER.info("Old addon %s found")
|
||||
tasks.append(self.loop.create_task(self.dockers[addon].remove()))
|
||||
|
||||
if tasks:
|
||||
await asyncio.wait(tasks, loop=self.loop)
|
||||
|
||||
async def auto_boot(self, start_type):
|
||||
"""Boot addons with mode auto."""
|
||||
boot_list = self.list_startup(start_type)
|
||||
@ -48,18 +57,18 @@ class AddonManager(AddonsData):
|
||||
for addon in boot_list:
|
||||
tasks.append(self.loop.create_task(self.start_addon(addon)))
|
||||
|
||||
_LOGGER.info("Startup %s run %d addons.", start_type, len(tasks))
|
||||
_LOGGER.info("Startup %s run %d addons", start_type, len(tasks))
|
||||
if tasks:
|
||||
await asyncio.wait(tasks, loop=self.loop)
|
||||
|
||||
async def install_addon(self, addon, version=None):
|
||||
"""Install a addon."""
|
||||
if not self.exists_addon(addon):
|
||||
_LOGGER.error("Addon %s not exists for install.", addon)
|
||||
_LOGGER.error("Addon %s not exists for install", addon)
|
||||
return False
|
||||
|
||||
if self.is_installed(addon):
|
||||
_LOGGER.error("Addon %s is already installed.", addon)
|
||||
_LOGGER.error("Addon %s is already installed", addon)
|
||||
return False
|
||||
|
||||
if not os.path.isdir(self.path_data(addon)):
|
||||
@ -81,11 +90,11 @@ class AddonManager(AddonsData):
|
||||
async def uninstall_addon(self, addon):
|
||||
"""Remove a addon."""
|
||||
if not self.is_installed(addon):
|
||||
_LOGGER.error("Addon %s is already uninstalled.", addon)
|
||||
_LOGGER.error("Addon %s is already uninstalled", addon)
|
||||
return False
|
||||
|
||||
if addon not in self.dockers:
|
||||
_LOGGER.error("No docker found for addon %s.", addon)
|
||||
_LOGGER.error("No docker found for addon %s", addon)
|
||||
return False
|
||||
|
||||
if not await self.dockers[addon].remove():
|
||||
@ -103,7 +112,7 @@ class AddonManager(AddonsData):
|
||||
async def state_addon(self, addon):
|
||||
"""Return running state of addon."""
|
||||
if addon not in self.dockers:
|
||||
_LOGGER.error("No docker found for addon %s.", addon)
|
||||
_LOGGER.error("No docker found for addon %s", addon)
|
||||
return
|
||||
|
||||
if await self.dockers[addon].is_running():
|
||||
@ -113,11 +122,11 @@ class AddonManager(AddonsData):
|
||||
async def start_addon(self, addon):
|
||||
"""Set options and start addon."""
|
||||
if addon not in self.dockers:
|
||||
_LOGGER.error("No docker found for addon %s.", addon)
|
||||
_LOGGER.error("No docker found for addon %s", addon)
|
||||
return False
|
||||
|
||||
if not self.write_addon_options(addon):
|
||||
_LOGGER.error("Can't write options for addon %s.", addon)
|
||||
_LOGGER.error("Can't write options for addon %s", addon)
|
||||
return False
|
||||
|
||||
return await self.dockers[addon].run():
|
||||
@ -125,7 +134,7 @@ class AddonManager(AddonsData):
|
||||
async def stop_addon(self, addon):
|
||||
"""Stop addon."""
|
||||
if addon not in self.dockers:
|
||||
_LOGGER.error("No docker found for addon %s.", addon)
|
||||
_LOGGER.error("No docker found for addon %s", addon)
|
||||
return False
|
||||
|
||||
return await self.dockers[addon].stop():
|
||||
@ -133,11 +142,11 @@ class AddonManager(AddonsData):
|
||||
async def update_addon(self, addon, version=None):
|
||||
"""Update addon."""
|
||||
if self.is_installed(addon):
|
||||
_LOGGER.error("Addon %s is not installed.", addon)
|
||||
_LOGGER.error("Addon %s is not installed", addon)
|
||||
return False
|
||||
|
||||
if addon not in self.dockers:
|
||||
_LOGGER.error("No docker found for addon %s.", addon)
|
||||
_LOGGER.error("No docker found for addon %s", addon)
|
||||
return False
|
||||
|
||||
version = version or self.get_version(addon)
|
||||
|
@ -67,7 +67,7 @@ class AddonsData(Config):
|
||||
_LOGGER.warning("Can't read %s", addon)
|
||||
|
||||
except vol.Invalid as ex:
|
||||
_LOGGER.warning("Can't read %s -> %s.", addon,
|
||||
_LOGGER.warning("Can't read %s -> %s", addon,
|
||||
humanize_error(addon_config, ex))
|
||||
|
||||
@property
|
||||
@ -106,10 +106,21 @@ class AddonsData(Config):
|
||||
if self._addons_data[addon][ATTR_STARTUP] == start_type:
|
||||
addon_list.add(addon)
|
||||
except KeyError:
|
||||
_LOGGER.warning("Orphaned addon detect %s", addon)
|
||||
continue
|
||||
|
||||
return addon_list
|
||||
|
||||
@property
|
||||
def list_removed(self):
|
||||
"""Return local addons they not support from repo."""
|
||||
addon_list = set()
|
||||
for addon in self._data.keys():
|
||||
if addon not in self._addons_data:
|
||||
addon_list.add(addon)
|
||||
|
||||
return addon_list
|
||||
|
||||
def exists_addon(self, addon):
|
||||
"""Return True if a addon exists."""
|
||||
return addon in self._addons_data
|
||||
|
@ -31,9 +31,9 @@ class APIAddons(object):
|
||||
|
||||
# check data
|
||||
if not self.addons.exists_addon(addon):
|
||||
raise RuntimeError("Addon not exists.")
|
||||
raise RuntimeError("Addon not exists")
|
||||
if check_installed and not self.addons.is_installed(addon):
|
||||
raise RuntimeError("Addon is not installed.")
|
||||
raise RuntimeError("Addon is not installed")
|
||||
|
||||
return addon
|
||||
|
||||
@ -86,7 +86,7 @@ class APIAddons(object):
|
||||
addon = self._extract_addon(request)
|
||||
|
||||
if await self.addons.state_addon(addon) == STATE_STARTED:
|
||||
raise RuntimeError("Addon is already running.")
|
||||
raise RuntimeError("Addon is already running")
|
||||
|
||||
return await asyncio.shield(
|
||||
self.addons.addon_start(addon), loop=self.loop)
|
||||
@ -97,7 +97,7 @@ class APIAddons(object):
|
||||
addon = self._extract_addon(request)
|
||||
|
||||
if await self.addons.state_addon(addon) == STATE_STOPPED:
|
||||
raise RuntimeError("Addon is already stoped.")
|
||||
raise RuntimeError("Addon is already stoped")
|
||||
|
||||
return await asyncio.shield(
|
||||
self.addons.addon_stop(addon), loop=self.loop)
|
||||
@ -111,7 +111,7 @@ class APIAddons(object):
|
||||
ATTR_VERSION, self.addons.get_version(addon))
|
||||
|
||||
if version == self.addons.version_installed(addon):
|
||||
raise RuntimeError("Version is already in use.")
|
||||
raise RuntimeError("Version is already in use")
|
||||
|
||||
return await asyncio.shield(
|
||||
self.addons.addon_update(addon, version), loop=self.loop)
|
||||
|
@ -40,10 +40,10 @@ class APIHomeAssistant(object):
|
||||
version = body.get(ATTR_VERSION, self.config.current_homeassistant)
|
||||
|
||||
if self.dock_hass.in_progress:
|
||||
raise RuntimeError("Other task is in progress.")
|
||||
raise RuntimeError("Other task is in progress")
|
||||
|
||||
if version == self.dock_hass.version:
|
||||
raise RuntimeError("%s is already in use.", version)
|
||||
raise RuntimeError("Version is already in use")
|
||||
|
||||
return await asyncio.shield(
|
||||
self.dock_hass.update(version), loop=self.loop)
|
||||
|
@ -56,6 +56,6 @@ class APIHost(object):
|
||||
version = body.get(ATTR_VERSION)
|
||||
|
||||
if version == self.host_controll.version:
|
||||
raise RuntimeError("%s is already in use.", version)
|
||||
raise RuntimeError("Version is already in use")
|
||||
|
||||
return await self.host_controll.host_update(version=version)
|
||||
|
@ -62,6 +62,6 @@ class APISupervisor(object):
|
||||
version = body.get(ATTR_VERSION, self.config.current_hassio)
|
||||
|
||||
if version == HASSIO_VERSION:
|
||||
raise RuntimeError("%s is already in use.", version)
|
||||
raise RuntimeError("Version is already in use")
|
||||
|
||||
return await self.host_controll.supervisor_update(version=version)
|
||||
|
@ -88,6 +88,11 @@ class HassIO(object):
|
||||
# start api
|
||||
await self.api.start()
|
||||
|
||||
# HomeAssistant is already running / supervisor have only reboot
|
||||
if await self.homeassistant.is_running():
|
||||
_LOGGER.info("HassIO reboot detected")
|
||||
return
|
||||
|
||||
# start addon mark as before
|
||||
await self.addons.auto_boot(STARTUP_BEFORE)
|
||||
|
||||
|
@ -53,7 +53,7 @@ class DockerBase(object):
|
||||
|
||||
image.tag(self.image, tag='latest')
|
||||
self.version = get_version_from_env(image.attrs['Config']['Env'])
|
||||
_LOGGER.info("Tag image %s with version %s as latest.",
|
||||
_LOGGER.info("Tag image %s with version %s as latest",
|
||||
self.image, self.version)
|
||||
except docker.errors.APIError as err:
|
||||
_LOGGER.error("Can't install %s:%s -> %s.", self.image, tag, err)
|
||||
@ -122,7 +122,7 @@ class DockerBase(object):
|
||||
self.image = self.container.attrs['Config']['Image']
|
||||
self.version = get_version_from_env(
|
||||
self.container.attrs['Config']['Env'])
|
||||
_LOGGER.info("Attach to image %s with version %s.",
|
||||
_LOGGER.info("Attach to image %s with version %s",
|
||||
self.image, self.version)
|
||||
except (docker.errors.DockerException, KeyError):
|
||||
_LOGGER.fatal(
|
||||
@ -138,7 +138,7 @@ class DockerBase(object):
|
||||
return False
|
||||
|
||||
async with self._lock:
|
||||
_LOGGER.info("Run docker image %s with version %s.",
|
||||
_LOGGER.info("Run docker image %s with version %s",
|
||||
self.image, self.version)
|
||||
return await self.loop.run_in_executor(None, self._run)
|
||||
|
||||
@ -191,14 +191,14 @@ class DockerBase(object):
|
||||
|
||||
Need run inside executor.
|
||||
"""
|
||||
if self.container:
|
||||
if self._is_running():
|
||||
self._stop()
|
||||
|
||||
image = "{}:latest".format(self.image)
|
||||
try:
|
||||
self.dock.images.remove(image=image, force=True)
|
||||
except docker.errors.DockerException as err:
|
||||
_LOGGER.warning("Can't remove image %s -> %s.", image, err)
|
||||
_LOGGER.warning("Can't remove image %s -> %s", image, err)
|
||||
return False
|
||||
|
||||
return True
|
||||
@ -220,10 +220,10 @@ class DockerBase(object):
|
||||
|
||||
Need run inside executor.
|
||||
"""
|
||||
old_image = "{}:{}".format(self.image, self.version)
|
||||
old_run = self._is_running()
|
||||
old_image = "{}:{}".format(self.image, self.version)
|
||||
|
||||
_LOGGER.info("Update docker %s with %s:%s.",
|
||||
_LOGGER.info("Update docker %s with %s:%s",
|
||||
old_image, self.image, tag)
|
||||
|
||||
# update docker image
|
||||
@ -234,7 +234,7 @@ class DockerBase(object):
|
||||
self.dock.images.remove(image=old_image, force=True)
|
||||
except docker.errors.DockerException as err:
|
||||
_LOGGER.warning(
|
||||
"Can't remove old image %s -> %s.", old_image, err)
|
||||
"Can't remove old image %s -> %s", old_image, err)
|
||||
# restore
|
||||
if old_run:
|
||||
self._run()
|
||||
|
@ -70,7 +70,7 @@ class DockerAddon(DockerBase):
|
||||
self.version = get_version_from_env(
|
||||
self.container.attrs['Config']['Env'])
|
||||
except docker.errors.DockerException as err:
|
||||
_LOGGER.error("Can't run %s -> %s.", self.image, err)
|
||||
_LOGGER.error("Can't run %s -> %s", self.image, err)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
@ -60,7 +60,7 @@ class DockerHomeAssistant(DockerBase):
|
||||
self.version = get_version_from_env(
|
||||
self.container.attrs['Config']['Env'])
|
||||
except docker.errors.DockerException as err:
|
||||
_LOGGER.error("Can't run %s -> %s.", self.image, err)
|
||||
_LOGGER.error("Can't run %s -> %s", self.image, err)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
Loading…
x
Reference in New Issue
Block a user