daemon: Added method to ensure a daemon is running in component

This will help apps like zoph that need to have database server running to
install or upgrade a package.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2024-03-08 14:57:02 -08:00 committed by James Valleroy
parent 74fc8e08da
commit ec52d9bed9
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
2 changed files with 53 additions and 0 deletions

View File

@ -1,6 +1,7 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Component for managing a background daemon or any systemd unit."""
import contextlib
import socket
import subprocess
@ -86,6 +87,20 @@ class Daemon(app.LeaderComponent):
"""Return whether the daemon/unit is running."""
return action_utils.service_is_running(self.unit)
@contextlib.contextmanager
def ensure_running(self):
"""Ensure a service is running and return to previous state."""
from plinth.privileged import service as service_privileged
starting_state = self.is_running()
if not starting_state:
service_privileged.enable(self.unit)
try:
yield starting_state
finally:
if not starting_state:
service_privileged.disable(self.unit)
def diagnose(self) -> list[DiagnosticCheck]:
"""Check if the daemon is running and listening on expected ports.

View File

@ -138,6 +138,44 @@ def test_is_running(service_is_running, daemon):
assert not daemon.is_running()
@patch('plinth.app.apps_init')
@patch('plinth.action_utils.service_is_running')
@patch('subprocess.run')
@patch('subprocess.call')
def test_ensure_running(subprocess_call, subprocess_run, service_is_running,
apps_init, app_list, mock_privileged, daemon):
"""Test that checking that the daemon is running works."""
service_is_running.return_value = True
with daemon.ensure_running() as starting_state:
assert starting_state
assert not subprocess_call.called
assert not subprocess_run.called
assert not subprocess_call.called
assert not subprocess_run.called
service_is_running.return_value = False
with daemon.ensure_running() as starting_state:
assert not starting_state
assert subprocess_run.mock_calls == [
call(['systemctl', 'start', 'test-unit'],
stdout=subprocess.DEVNULL, check=False)
]
assert subprocess_call.mock_calls == [
call(['systemctl', 'enable', 'test-unit'])
]
subprocess_run.reset_mock()
subprocess_call.reset_mock()
assert subprocess_run.mock_calls == [
call(['systemctl', 'stop', 'test-unit'], stdout=subprocess.DEVNULL,
check=False)
]
assert subprocess_call.mock_calls == [
call(['systemctl', 'disable', 'test-unit'])
]
@patch('plinth.action_utils.service_is_running')
@patch('plinth.daemon.diagnose_port_listening')
def test_diagnose(port_listening, service_is_running, daemon):