1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2026-04-17 23:33:35 +01:00

Wait until mount unit is deactivated on unmount (#4733)

* Wait until mount unit is deactivated on unmount

The current code does not wait until the (bind) mount unit has been
actually deactivated (state "inactive"). This is especially problematic
when restoring a backup, where we deactivate all bind mounts before
restoring the target folder. Before the tarball is actually restored,
we delete all contents of the target folder. This lead to the situation
where the "rm -rf" command got executed before the bind mount actually
got unmounted.

The current code polls the state using an exponentially increasing
delay. Wait up to 30s for the bind mount to actually deactivate.

* Fix function name

* Fix missing await

* Address pytest errors

Change state of systemd unit according to use cases. Note that this
is currently rather fragile, and ideally we should have a smarter
mock service instead.

* Fix pylint

* Fix remaining

* Check transition fo failed as well

* Used alternative mocking mechanism

* Remove state lists in test_manager

---------

Co-authored-by: Mike Degatano <michael.degatano@gmail.com>
This commit is contained in:
Stefan Agner
2023-12-01 00:35:15 +01:00
committed by GitHub
parent df7541e397
commit 11ec6dd9ac
7 changed files with 120 additions and 18 deletions

View File

@@ -4,6 +4,7 @@ from dbus_fast import DBusError
from dbus_fast.service import PropertyAccess, dbus_property
from .base import DBusServiceMock, dbus_method
from .systemd_unit import SystemdUnit
BUS_NAME = "org.freedesktop.systemd1"
@@ -40,6 +41,7 @@ class Systemd(DBusServiceMock):
response_start_transient_unit: str | DBusError = (
"/org/freedesktop/systemd1/job/7623"
)
mock_systemd_unit: SystemdUnit | None = None
@dbus_property(access=PropertyAccess.READ)
def Version(self) -> "s":
@@ -658,6 +660,8 @@ class Systemd(DBusServiceMock):
@dbus_method()
def StartUnit(self, name: "s", mode: "s") -> "o":
"""Start a service unit."""
if self.mock_systemd_unit:
self.mock_systemd_unit.active_state = "active"
return "/org/freedesktop/systemd1/job/7623"
@dbus_method()
@@ -665,6 +669,8 @@ class Systemd(DBusServiceMock):
"""Stop a service unit."""
if isinstance(self.response_stop_unit, DBusError):
raise self.response_stop_unit
if self.mock_systemd_unit:
self.mock_systemd_unit.active_state = "inactive"
return self.response_stop_unit
@dbus_method()
@@ -672,11 +678,15 @@ class Systemd(DBusServiceMock):
"""Reload or restart a service unit."""
if isinstance(self.response_reload_or_restart_unit, DBusError):
raise self.response_reload_or_restart_unit
if self.mock_systemd_unit:
self.mock_systemd_unit.active_state = "active"
return self.response_reload_or_restart_unit
@dbus_method()
def RestartUnit(self, name: "s", mode: "s") -> "o":
"""Restart a service unit."""
if self.mock_systemd_unit:
self.mock_systemd_unit.active_state = "active"
return "/org/freedesktop/systemd1/job/7623"
@dbus_method()
@@ -686,11 +696,15 @@ class Systemd(DBusServiceMock):
"""Start a transient service unit."""
if isinstance(self.response_start_transient_unit, DBusError):
raise self.response_start_transient_unit
if self.mock_systemd_unit:
self.mock_systemd_unit.active_state = "active"
return self.response_start_transient_unit
@dbus_method()
def ResetFailedUnit(self, name: "s") -> None:
"""Reset a failed unit."""
if self.mock_systemd_unit:
self.mock_systemd_unit.active_state = "inactive"
@dbus_method()
def GetUnit(self, name: "s") -> "s":