Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 42 additions & 44 deletions supervisor/addons/addon.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion supervisor/addons/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def base_image(self) -> str:
# Evaluate correct base image
if self.arch not in self._data[ATTR_BUILD_FROM]:
raise HassioArchNotFound(
f"Add-on {self.addon.slug} is not supported on {self.arch}"
f"App {self.addon.slug} is not supported on {self.arch}"
)
return self._data[ATTR_BUILD_FROM][self.arch]

Expand Down
48 changes: 24 additions & 24 deletions supervisor/addons/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ async def load(self) -> None:
tasks.append(addon.load())

# Run initial tasks
_LOGGER.info("Found %d installed add-ons", len(self.data.system))
_LOGGER.info("Found %d installed apps", len(self.data.system))
if tasks:
await asyncio.gather(*tasks)

Expand All @@ -116,15 +116,15 @@ async def boot(self, stage: AddonStartup) -> None:
in self.sys_resolution.unhealthy
):
_LOGGER.warning(
"Skipping boot of add-on %s because gateway firewall"
"Skipping boot of app %s because gateway firewall"
" rules are not active",
addon.slug,
)
continue
tasks.append(addon)

# Evaluate add-ons which need to be started
_LOGGER.info("Phase '%s' starting %d add-ons", stage, len(tasks))
_LOGGER.info("Phase '%s' starting %d apps", stage, len(tasks))
if not tasks:
return

Expand All @@ -148,7 +148,7 @@ async def boot(self, stage: AddonStartup) -> None:
else:
continue

_LOGGER.warning("Can't start Add-on %s", addon.slug)
_LOGGER.warning("Can't start App %s", addon.slug)

# Ignore exceptions from waiting for addon startup, addon errors handled elsewhere
await asyncio.gather(*wait_boot, return_exceptions=True)
Expand All @@ -175,7 +175,7 @@ async def shutdown(self, stage: AddonStartup) -> None:
tasks.append(addon)

# Evaluate add-ons which need to be stopped
_LOGGER.info("Phase '%s' stopping %d add-ons", stage, len(tasks))
_LOGGER.info("Phase '%s' stopping %d apps", stage, len(tasks))
if not tasks:
return

Expand All @@ -185,7 +185,7 @@ async def shutdown(self, stage: AddonStartup) -> None:
try:
await addon.stop()
except Exception as err: # pylint: disable=broad-except
_LOGGER.warning("Can't stop Add-on %s: %s", addon.slug, err)
_LOGGER.warning("Can't stop App %s: %s", addon.slug, err)
await async_capture_exception(err)

@Job(
Expand All @@ -204,11 +204,11 @@ async def install(
self.sys_jobs.current.reference = slug

if slug in self.local:
raise AddonsError(f"Add-on {slug} is already installed", _LOGGER.warning)
raise AddonsError(f"App {slug} is already installed", _LOGGER.warning)
store = self.store.get(slug)

if not store:
raise AddonsError(f"Add-on {slug} does not exist", _LOGGER.error)
raise AddonsError(f"App {slug} does not exist", _LOGGER.error)

store.validate_availability()

Expand All @@ -218,13 +218,13 @@ async def install(

await Addon(self.coresys, slug).install()

_LOGGER.info("Add-on '%s' successfully installed", slug)
_LOGGER.info("App '%s' successfully installed", slug)

@Job(name="addon_manager_uninstall")
async def uninstall(self, slug: str, *, remove_config: bool = False) -> None:
"""Remove an add-on."""
if slug not in self.local:
_LOGGER.warning("Add-on %s is not installed", slug)
_LOGGER.warning("App %s is not installed", slug)
return

shared_image = any(
Expand All @@ -237,7 +237,7 @@ async def uninstall(self, slug: str, *, remove_config: bool = False) -> None:
remove_config=remove_config, remove_image=not shared_image
)

_LOGGER.info("Add-on '%s' successfully removed", slug)
_LOGGER.info("App '%s' successfully removed", slug)

@Job(
name="addon_manager_update",
Expand Down Expand Up @@ -266,17 +266,17 @@ async def update(
self.sys_jobs.current.reference = slug

if slug not in self.local:
raise AddonsError(f"Add-on {slug} is not installed", _LOGGER.error)
raise AddonsError(f"App {slug} is not installed", _LOGGER.error)
addon = self.local[slug]

if addon.is_detached:
raise AddonsError(
f"Add-on {slug} is not available inside store", _LOGGER.error
f"App {slug} is not available inside store", _LOGGER.error
)
store = self.store[slug]

if addon.version == store.version:
raise AddonsError(f"No update available for add-on {slug}", _LOGGER.warning)
raise AddonsError(f"No update available for app {slug}", _LOGGER.warning)

# Check if available, Maybe something have changed
store.validate_availability()
Expand All @@ -294,7 +294,7 @@ async def update(

task = await addon.update()

_LOGGER.info("Add-on '%s' successfully updated", slug)
_LOGGER.info("App '%s' successfully updated", slug)
return task

@Job(
Expand All @@ -315,12 +315,12 @@ async def rebuild(self, slug: str, *, force: bool = False) -> asyncio.Task | Non
self.sys_jobs.current.reference = slug

if slug not in self.local:
raise AddonsError(f"Add-on {slug} is not installed", _LOGGER.error)
raise AddonsError(f"App {slug} is not installed", _LOGGER.error)
addon = self.local[slug]

if addon.is_detached:
raise AddonsError(
f"Add-on {slug} is not available inside store", _LOGGER.error
f"App {slug} is not available inside store", _LOGGER.error
)
store = self.store[slug]

Expand All @@ -331,7 +331,7 @@ async def rebuild(self, slug: str, *, force: bool = False) -> asyncio.Task | Non
)
if not force and not addon.need_build:
raise AddonNotSupportedError(
"Can't rebuild a image based add-on", _LOGGER.error
"Can't rebuild an image-based app", _LOGGER.error
)

return await addon.rebuild()
Expand All @@ -354,19 +354,19 @@ async def restore(self, slug: str, tar_file: SecureTarFile) -> asyncio.Task | No
self.sys_jobs.current.reference = slug

if slug not in self.local:
_LOGGER.debug("Add-on %s is not local available for restore", slug)
_LOGGER.debug("App %s is not locally available for restore", slug)
addon = Addon(self.coresys, slug)
had_ingress: bool | None = False
else:
_LOGGER.debug("Add-on %s is local available for restore", slug)
_LOGGER.debug("App %s is locally available for restore", slug)
addon = self.local[slug]
had_ingress = addon.ingress_panel

wait_for_start = await addon.restore(tar_file)

# Check if new
if slug not in self.local:
_LOGGER.info("Detect new Add-on after restore %s", slug)
_LOGGER.info("Detect new App after restore %s", slug)
self.local[slug] = addon

# Update ingress
Expand All @@ -390,12 +390,12 @@ async def repair(self) -> None:
continue
needs_repair.append(addon)

_LOGGER.info("Found %d add-ons to repair", len(needs_repair))
_LOGGER.info("Found %d apps to repair", len(needs_repair))
if not needs_repair:
return

for addon in needs_repair:
_LOGGER.info("Repairing for add-on: %s", addon.slug)
_LOGGER.info("Repairing for app: %s", addon.slug)
with suppress(DockerError, KeyError):
# Need pull a image again
if not addon.need_build:
Expand Down Expand Up @@ -423,7 +423,7 @@ async def sync_dns(self) -> None:
if not await addon.instance.is_running():
continue
except DockerError as err:
_LOGGER.warning("Add-on %s is corrupt: %s", addon.slug, err)
_LOGGER.warning("App %s is corrupt: %s", addon.slug, err)
self.sys_resolution.create_issue(
IssueType.CORRUPT_DOCKER,
ContextType.ADDON,
Expand Down
2 changes: 1 addition & 1 deletion supervisor/addons/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,4 @@ def remove_data(folder: Path) -> None:
else:
return

_LOGGER.error("Can't remove Add-on Data: %s", error_msg)
_LOGGER.error("Can't remove App Data: %s", error_msg)
36 changes: 18 additions & 18 deletions supervisor/addons/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,13 @@ def _warn_addon_config(config: dict[str, Any]):
"""Warn about miss configs."""
name = config.get(ATTR_NAME)
if not name:
raise vol.Invalid("Invalid Add-on config!")
raise vol.Invalid("Invalid App config!")

if ATTR_ADVANCED in config:
# Deprecated since Supervisor 2026.03.0; this field is ignored and the
# warning can be removed once that version is the minimum supported.
_LOGGER.warning(
"Add-on '%s' uses deprecated 'advanced' field in config. "
"App '%s' uses deprecated 'advanced' field in config. "
"This field is ignored by the Supervisor. Please report this to the maintainer.",
name,
)
Expand All @@ -208,23 +208,23 @@ def _warn_addon_config(config: dict[str, Any]):
or config.get(ATTR_GPIO)
):
_LOGGER.warning(
"Add-on have full device access, and selective device access in the configuration. Please report this to the maintainer of %s",
"App has full device access, and selective device access in the configuration. Please report this to the maintainer of %s",
name,
)

if config.get(ATTR_BACKUP, AddonBackupMode.HOT) == AddonBackupMode.COLD and (
config.get(ATTR_BACKUP_POST) or config.get(ATTR_BACKUP_PRE)
):
_LOGGER.warning(
"Add-on which only support COLD backups trying to use post/pre commands. Please report this to the maintainer of %s",
"An app that only supports COLD backups is trying to use pre/post commands. Please report this to the maintainer of %s",
name,
)

if deprecated_arches := [
arch for arch in config.get(ATTR_ARCH, []) if arch in ARCH_DEPRECATED
]:
_LOGGER.warning(
"Add-on config 'arch' uses deprecated values %s. Please report this to the maintainer of %s",
"App config 'arch' uses deprecated values %s. Please report this to the maintainer of %s",
deprecated_arches,
name,
)
Expand All @@ -235,14 +235,14 @@ def _warn_addon_config(config: dict[str, Any]):
if machine.lstrip("!") in MACHINE_DEPRECATED
]:
_LOGGER.warning(
"Add-on config 'machine' uses deprecated values %s. Please report this to the maintainer of %s",
"App config 'machine' uses deprecated values %s. Please report this to the maintainer of %s",
deprecated_machines,
name,
)

if ATTR_CODENOTARY in config:
_LOGGER.warning(
"Add-on '%s' uses deprecated 'codenotary' field in config. This field is no longer used and will be ignored. Please report this to the maintainer.",
"App '%s' uses deprecated 'codenotary' field in config. This field is no longer used and will be ignored. Please report this to the maintainer.",
name,
)

Expand All @@ -254,17 +254,17 @@ def _migrate_addon_config(protocol=False):

def _migrate(config: dict[str, Any]):
if not isinstance(config, dict):
raise vol.Invalid("Add-on config must be a dictionary!")
raise vol.Invalid("App config must be a dictionary!")
name = config.get(ATTR_NAME)
if not name:
raise vol.Invalid("Invalid Add-on config!")
raise vol.Invalid("Invalid App config!")

# Startup 2018-03-30
if config.get(ATTR_STARTUP) in ("before", "after"):
value = config[ATTR_STARTUP]
if protocol:
_LOGGER.warning(
"Add-on config 'startup' with '%s' is deprecated. Please report this to the maintainer of %s",
"App config 'startup' with '%s' is deprecated. Please report this to the maintainer of %s",
value,
name,
)
Expand All @@ -277,7 +277,7 @@ def _migrate(config: dict[str, Any]):
if "auto_uart" in config:
if protocol:
_LOGGER.warning(
"Add-on config 'auto_uart' is deprecated, use 'uart'. Please report this to the maintainer of %s",
"App config 'auto_uart' is deprecated, use 'uart'. Please report this to the maintainer of %s",
name,
)
config[ATTR_UART] = config.pop("auto_uart")
Expand All @@ -286,7 +286,7 @@ def _migrate(config: dict[str, Any]):
if ATTR_DEVICES in config and any(":" in line for line in config[ATTR_DEVICES]):
if protocol:
_LOGGER.warning(
"Add-on config 'devices' use a deprecated format, the new format uses a list of paths only. Please report this to the maintainer of %s",
"App config 'devices' uses a deprecated format instead of a list of paths only. Please report this to the maintainer of %s",
name,
)
config[ATTR_DEVICES] = [line.split(":")[0] for line in config[ATTR_DEVICES]]
Expand All @@ -295,7 +295,7 @@ def _migrate(config: dict[str, Any]):
if ATTR_TMPFS in config and not isinstance(config[ATTR_TMPFS], bool):
if protocol:
_LOGGER.warning(
"Add-on config 'tmpfs' use a deprecated format, new it's only a boolean. Please report this to the maintainer of %s",
"App config 'tmpfs' uses a deprecated format instead of just a boolean. Please report this to the maintainer of %s",
name,
)
config[ATTR_TMPFS] = True
Expand All @@ -311,7 +311,7 @@ def _migrate(config: dict[str, Any]):
new_entry = entry.replace("snapshot", "backup")
config[new_entry] = config.pop(entry)
_LOGGER.warning(
"Add-on config '%s' is deprecated, '%s' should be used instead. Please report this to the maintainer of %s",
"App config '%s' is deprecated, '%s' should be used instead. Please report this to the maintainer of %s",
entry,
new_entry,
name,
Expand All @@ -324,7 +324,7 @@ def _migrate(config: dict[str, Any]):
# Validate that dict entries have required 'type' field
if ATTR_TYPE not in entry:
_LOGGER.warning(
"Add-on config has invalid map entry missing 'type' field: %s. Skipping invalid entry for %s",
"App config has invalid map entry missing 'type' field: %s. Skipping invalid entry for %s",
entry,
name,
)
Expand All @@ -334,7 +334,7 @@ def _migrate(config: dict[str, Any]):
result = RE_VOLUME.match(entry)
if not result:
_LOGGER.warning(
"Add-on config has invalid map entry: %s. Skipping invalid entry for %s",
"App config has invalid map entry: %s. Skipping invalid entry for %s",
entry,
name,
)
Expand All @@ -358,15 +358,15 @@ def _migrate(config: dict[str, Any]):
for volume in volumes
):
_LOGGER.warning(
"Add-on config using incompatible map options, '%s' and '%s' are ignored if '%s' is included. Please report this to the maintainer of %s",
"App config using incompatible map options, '%s' and '%s' are ignored if '%s' is included. Please report this to the maintainer of %s",
MappingType.ADDON_CONFIG,
MappingType.HOMEASSISTANT_CONFIG,
MappingType.CONFIG,
name,
)
else:
_LOGGER.debug(
"Add-on config using deprecated map option '%s' instead of '%s'. Please report this to the maintainer of %s",
"App config using deprecated map option '%s' instead of '%s'. Please report this to the maintainer of %s",
MappingType.CONFIG,
MappingType.HOMEASSISTANT_CONFIG,
name,
Expand Down
Loading
Loading