diff --git a/plinth/daemon.py b/plinth/daemon.py index 08a03ca9a..5d1935e83 100644 --- a/plinth/daemon.py +++ b/plinth/daemon.py @@ -107,6 +107,33 @@ class Daemon(app.LeaderComponent): return [testname, result] +class RelatedDaemon(app.FollowerComponent): + """Component to hold information about additional systemd units handled. + + Unlike a daemon described by the Daemon component which is enabled/disabled + when the app is enabled/disabled, the daemon described by this component is + unaffected by the app's enabled/disabled status. The app only has an + indirect interest in this daemon. + + This component primarily holds information about such daemon and does + nothing else. This information is used to check if the app is allowed to + perform operations on the daemon. + """ + + def __init__(self, component_id, unit): + """Initialize a new related daemon component. + + 'component_id' must be a unique string across all apps and components + of a app. Conventionally starts with 'related-daemon-'. + + 'unit' must the name of systemd unit. + + """ + super().__init__(component_id) + + self.unit = unit + + def app_is_running(app_): """Return whether all the daemons in the app are running.""" for component in app_.components.values(): diff --git a/plinth/tests/test_daemon.py b/plinth/tests/test_daemon.py index 8fc1018eb..c28d73db2 100644 --- a/plinth/tests/test_daemon.py +++ b/plinth/tests/test_daemon.py @@ -9,8 +9,8 @@ from unittest.mock import Mock, call, patch import pytest from plinth.app import App, FollowerComponent -from plinth.daemon import (Daemon, app_is_running, diagnose_netcat, - diagnose_port_listening) +from plinth.daemon import (Daemon, RelatedDaemon, app_is_running, + diagnose_netcat, diagnose_port_listening) @pytest.fixture(name='daemon') @@ -228,3 +228,13 @@ def test_diagnose_netcat(popen): result = diagnose_netcat('test-host', 3300, input='test-input', negate=True) assert result == ['Cannot connect to test-host:3300', 'passed'] + + +def test_related_daemon_initialization(): + """Test that initializing related daemon works.""" + component = RelatedDaemon('test-component', 'test-daemon') + assert component.component_id == 'test-component' + assert component.unit == 'test-daemon' + + with pytest.raises(ValueError): + RelatedDaemon(None, 'test-daemon')