Mount manager reload mounts all failed mounts (#5014)

* Mount manager reload mounts all failed mounts

* Remove invalid part of mount manager reload test
This commit is contained in:
Mike Degatano 2024-04-12 06:02:29 -04:00 committed by GitHub
parent 4857c2e243
commit dfd8fe84e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 59 additions and 20 deletions

View File

@ -150,15 +150,10 @@ class MountManager(FileConfiguration, CoreSysAttributes):
*[mount.update() for mount in mounts], return_exceptions=True
)
# Try to reload any newly failed mounts and report issues if failure persists
new_failures = [
mounts[i]
for i in range(len(mounts))
if results[i] is not True
and mounts[i].failed_issue not in self.sys_resolution.issues
]
# Try to reload failed mounts and report issues if failure persists
failures = [mounts[i] for i in range(len(mounts)) if results[i] is not True]
await self._mount_errors_to_issues(
new_failures, [mount.reload() for mount in new_failures]
failures, [self.reload_mount(mount.name) for mount in failures]
)
async def _mount_errors_to_issues(
@ -170,6 +165,8 @@ class MountManager(FileConfiguration, CoreSysAttributes):
for i in range(len(errors)): # pylint: disable=consider-using-enumerate
if not errors[i]:
continue
if mounts[i].failed_issue in self.sys_resolution.issues:
continue
if not isinstance(errors[i], MountError):
capture_exception(errors[i])

View File

@ -342,20 +342,23 @@ class Mount(CoreSysAttributes, ABC):
"Mount %s is not mounted, mounting instead of reloading", self.name
)
await self.mount()
return
except DBusError as err:
raise MountError(
f"Could not reload mount {self.name} due to: {err!s}", _LOGGER.error
) from err
else:
if await self._update_unit():
await self._update_state_await(not_state=UnitActiveState.ACTIVATING)
if await self._update_unit():
await self._update_state_await(not_state=UnitActiveState.ACTIVATING)
if not await self.is_mounted():
raise MountActivationError(
f"Reloading {self.name} did not succeed. Check host logs for errors from mount or systemd unit {self.unit_name} for details.",
_LOGGER.error,
)
if not await self.is_mounted():
raise MountActivationError(
f"Reloading {self.name} did not succeed. Check host logs for errors from mount or systemd unit {self.unit_name} for details.",
_LOGGER.error,
)
# If it is mounted now, dismiss corresponding issue if present
if self.failed_issue in self.sys_resolution.issues:
self.sys_resolution.dismiss_issue(self.failed_issue)
class NetworkMount(Mount, ABC):

View File

@ -595,10 +595,6 @@ async def test_reload_mounts(
assert len(coresys.resolution.suggestions_for_issue(mount.failed_issue)) == 2
assert len(systemd_service.ReloadOrRestartUnit.calls) == 1
# This shouldn't reload the mount again since this isn't a new failure
await coresys.mounts.reload()
assert len(systemd_service.ReloadOrRestartUnit.calls) == 1
# This should now remove the issue from the list
systemd_unit_service.active_state = "active"
await coresys.mounts.reload()
@ -608,6 +604,49 @@ async def test_reload_mounts(
assert not coresys.resolution.suggestions_for_issue(mount.failed_issue)
async def test_reload_mounts_attempts_initial_mount(
coresys: CoreSys, all_dbus_services: dict[str, DBusServiceMock], mount: Mount
):
"""Test reloading mounts attempts initial mount."""
systemd_service: SystemdService = all_dbus_services["systemd"]
systemd_service.StartTransientUnit.calls.clear()
systemd_service.response_get_unit = [
ERROR_NO_UNIT,
"/org/freedesktop/systemd1/unit/tmp_2dyellow_2emount",
ERROR_NO_UNIT,
ERROR_NO_UNIT,
"/org/freedesktop/systemd1/unit/tmp_2dyellow_2emount",
]
systemd_service.response_reload_or_restart_unit = ERROR_NO_UNIT
coresys.mounts.bound_mounts[0].emergency = True
await coresys.mounts.reload()
assert systemd_service.StartTransientUnit.calls == [
(
"mnt-data-supervisor-mounts-media_test.mount",
"fail",
[
["Options", Variant("s", "soft,timeo=200")],
["Type", Variant("s", "nfs")],
["Description", Variant("s", "Supervisor nfs mount: media_test")],
["What", Variant("s", "media.local:/media")],
],
[],
),
(
"mnt-data-supervisor-media-media_test.mount",
"fail",
[
["Options", Variant("s", "bind")],
["Description", Variant("s", "Supervisor bind mount: bind_media_test")],
["What", Variant("s", "/mnt/data/supervisor/mounts/media_test")],
],
[],
),
]
@pytest.mark.parametrize("os_available", ["9.5"], indirect=True)
async def test_mounting_not_supported(
coresys: CoreSys,