mirror of
https://github.com/home-assistant/supervisor.git
synced 2026-02-15 07:27:13 +00:00
Reload ingress tokens on addon update and rebuild (#6556)
When an addon updates from having no ingress to having ingress, the ingress token map was never rebuilt. Both update() and rebuild() called _check_ingress_port() to assign a dynamic port but skipped the sys_ingress.reload() call that registers the token. This caused Ingress.get() to return None, resulting in a 503 error. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -926,6 +926,10 @@ class Addon(AddonModel):
|
||||
await self.sys_addons.data.update(store)
|
||||
await self._check_ingress_port()
|
||||
|
||||
# Reload ingress tokens in case addon gained ingress support
|
||||
if self.with_ingress:
|
||||
await self.sys_ingress.reload()
|
||||
|
||||
# Cleanup
|
||||
with suppress(DockerError):
|
||||
await self.instance.cleanup(
|
||||
@@ -979,6 +983,11 @@ class Addon(AddonModel):
|
||||
await self.sys_addons.data.update(self.addon_store)
|
||||
|
||||
await self._check_ingress_port()
|
||||
|
||||
# Reload ingress tokens in case addon gained ingress support
|
||||
if self.with_ingress:
|
||||
await self.sys_ingress.reload()
|
||||
|
||||
_LOGGER.info("Add-on '%s' successfully rebuilt", self.slug)
|
||||
|
||||
finally:
|
||||
|
||||
@@ -13,7 +13,7 @@ import pytest
|
||||
from supervisor.addons.addon import Addon
|
||||
from supervisor.arch import CpuArchManager
|
||||
from supervisor.config import CoreConfig
|
||||
from supervisor.const import AddonBoot, AddonStartup, AddonState, BusEvent
|
||||
from supervisor.const import ATTR_INGRESS, AddonBoot, AddonStartup, AddonState, BusEvent
|
||||
from supervisor.coresys import CoreSys
|
||||
from supervisor.docker.addon import DockerAddon
|
||||
from supervisor.docker.const import ContainerState
|
||||
@@ -528,6 +528,75 @@ async def test_shared_image_kept_on_uninstall(
|
||||
assert not coresys.addons.get("local_example", local_only=True)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("tmp_supervisor_data", "path_extern")
|
||||
async def test_update_reloads_ingress_tokens(
|
||||
coresys: CoreSys,
|
||||
install_addon_ssh: Addon,
|
||||
container: DockerContainer,
|
||||
):
|
||||
"""Test ingress tokens are reloaded when addon gains ingress on update."""
|
||||
container.show.return_value["State"]["Status"] = "stopped"
|
||||
container.show.return_value["State"]["Running"] = False
|
||||
install_addon_ssh.path_data.mkdir()
|
||||
|
||||
# Simulate addon was installed without ingress
|
||||
coresys.addons.data.system[install_addon_ssh.slug][ATTR_INGRESS] = False
|
||||
await install_addon_ssh.load()
|
||||
await coresys.ingress.reload()
|
||||
assert install_addon_ssh.ingress_token not in coresys.ingress.tokens
|
||||
|
||||
# Update store to version with ingress enabled
|
||||
with patch(
|
||||
"supervisor.store.data.read_json_or_yaml_file",
|
||||
return_value=load_json_fixture("addon-config-add-image.json"),
|
||||
):
|
||||
await coresys.store.data.update()
|
||||
|
||||
assert install_addon_ssh.need_update is True
|
||||
|
||||
with (
|
||||
patch.object(DockerInterface, "install"),
|
||||
patch.object(DockerAddon, "is_running", return_value=False),
|
||||
):
|
||||
await coresys.addons.update(TEST_ADDON_SLUG)
|
||||
|
||||
# Ingress token should now be registered
|
||||
assert install_addon_ssh.with_ingress is True
|
||||
assert install_addon_ssh.ingress_token in coresys.ingress.tokens
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("tmp_supervisor_data", "path_extern")
|
||||
async def test_rebuild_reloads_ingress_tokens(
|
||||
coresys: CoreSys,
|
||||
install_addon_ssh: Addon,
|
||||
container: DockerContainer,
|
||||
):
|
||||
"""Test ingress tokens are reloaded when addon gains ingress on rebuild."""
|
||||
container.show.return_value["State"]["Status"] = "stopped"
|
||||
container.show.return_value["State"]["Running"] = False
|
||||
install_addon_ssh.path_data.mkdir()
|
||||
|
||||
# Simulate addon was installed without ingress
|
||||
coresys.addons.data.system[install_addon_ssh.slug][ATTR_INGRESS] = False
|
||||
await install_addon_ssh.load()
|
||||
await coresys.ingress.reload()
|
||||
assert install_addon_ssh.ingress_token not in coresys.ingress.tokens
|
||||
|
||||
# Re-enable ingress in system data (rebuild pulls fresh store data)
|
||||
coresys.addons.data.system[install_addon_ssh.slug][ATTR_INGRESS] = True
|
||||
|
||||
with (
|
||||
patch.object(DockerAddon, "_build"),
|
||||
patch.object(DockerAddon, "is_running", return_value=False),
|
||||
patch.object(Addon, "need_build", new=PropertyMock(return_value=True)),
|
||||
):
|
||||
await coresys.addons.rebuild(TEST_ADDON_SLUG)
|
||||
|
||||
# Ingress token should now be registered
|
||||
assert install_addon_ssh.with_ingress is True
|
||||
assert install_addon_ssh.ingress_token in coresys.ingress.tokens
|
||||
|
||||
|
||||
async def test_shared_image_kept_on_update(
|
||||
coresys: CoreSys, install_addon_example_image: Addon, docker: DockerAPI
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user