leapp-repository/SOURCES/0026-systemd-Move-enable-di...

228 lines
8.5 KiB
Diff

From dc43277d4cab1f218a2b5d7e7743a1d2423c8c77 Mon Sep 17 00:00:00 2001
From: Matej Matuska <mmatuska@redhat.com>
Date: Wed, 16 Nov 2022 14:01:45 +0100
Subject: [PATCH 26/32] systemd: Move (enable|disable|reenable)_unit functions
to the shared library
The functions are used to enable, disable, or re-enable the given
systemd unit. Originaly they were part of setsystemdservicesstate
actor, however we have realized they are needed in other actors too
in rare cases.
---
.../libraries/setsystemdservicesstate.py | 25 +++++-----
.../tests/test_setsystemdservicesstate.py | 48 +++++++++++-------
.../common/libraries/systemd.py | 50 +++++++++++++++++++
3 files changed, 93 insertions(+), 30 deletions(-)
diff --git a/repos/system_upgrade/common/actors/systemd/setsystemdservicesstates/libraries/setsystemdservicesstate.py b/repos/system_upgrade/common/actors/systemd/setsystemdservicesstates/libraries/setsystemdservicesstate.py
index 01272438..641605db 100644
--- a/repos/system_upgrade/common/actors/systemd/setsystemdservicesstates/libraries/setsystemdservicesstate.py
+++ b/repos/system_upgrade/common/actors/systemd/setsystemdservicesstates/libraries/setsystemdservicesstate.py
@@ -1,17 +1,8 @@
-from leapp.libraries.stdlib import api, CalledProcessError, run
+from leapp.libraries.common import systemd
+from leapp.libraries.stdlib import api, CalledProcessError
from leapp.models import SystemdServicesTasks
-def _try_set_service_state(command, service):
- try:
- # it is possible to call this on multiple units at once,
- # but failing to enable one service would cause others to not enable as well
- run(['systemctl', command, service])
- except CalledProcessError as err:
- api.current_logger().error('Failed to {} systemd unit "{}". Message: {}'.format(command, service, str(err)))
- # TODO(mmatuska) produce post-upgrade report
-
-
def process():
services_to_enable = set()
services_to_disable = set()
@@ -25,7 +16,15 @@ def process():
api.current_logger().error(msg)
for service in services_to_enable:
- _try_set_service_state('enable', service)
+ try:
+ systemd.enable_unit(service)
+ except CalledProcessError:
+ # TODO(mmatuska) produce post-upgrade report
+ pass
for service in services_to_disable:
- _try_set_service_state('disable', service)
+ try:
+ systemd.disable_unit(service)
+ except CalledProcessError:
+ # TODO(mmatuska) produce post-upgrade report
+ pass
diff --git a/repos/system_upgrade/common/actors/systemd/setsystemdservicesstates/tests/test_setsystemdservicesstate.py b/repos/system_upgrade/common/actors/systemd/setsystemdservicesstates/tests/test_setsystemdservicesstate.py
index dd153329..14d07537 100644
--- a/repos/system_upgrade/common/actors/systemd/setsystemdservicesstates/tests/test_setsystemdservicesstate.py
+++ b/repos/system_upgrade/common/actors/systemd/setsystemdservicesstates/tests/test_setsystemdservicesstate.py
@@ -2,50 +2,60 @@ import pytest
from leapp.libraries import stdlib
from leapp.libraries.actor import setsystemdservicesstate
+from leapp.libraries.common import systemd
from leapp.libraries.common.testutils import CurrentActorMocked, logger_mocked
from leapp.libraries.stdlib import api, CalledProcessError
from leapp.models import SystemdServicesTasks
-class MockedRun(object):
+class MockedSystemdCmd(object):
def __init__(self):
- self.commands = []
+ self.units = []
- def __call__(self, cmd, *args, **kwargs):
- self.commands.append(cmd)
+ def __call__(self, unit, *args, **kwargs):
+ self.units.append(unit)
return {}
@pytest.mark.parametrize(
- ('msgs', 'expected_calls'),
+ ('msgs', 'expect_enable_units', 'expect_disable_units'),
[
(
[SystemdServicesTasks(to_enable=['hello.service'],
to_disable=['getty.service'])],
- [['systemctl', 'enable', 'hello.service'], ['systemctl', 'disable', 'getty.service']]
+ ['hello.service'],
+ ['getty.service']
),
(
[SystemdServicesTasks(to_disable=['getty.service'])],
- [['systemctl', 'disable', 'getty.service']]
+ [],
+ ['getty.service']
),
(
[SystemdServicesTasks(to_enable=['hello.service'])],
- [['systemctl', 'enable', 'hello.service']]
+ ['hello.service'],
+ []
),
(
[SystemdServicesTasks()],
+ [],
[]
),
]
)
-def test_process(monkeypatch, msgs, expected_calls):
- mocked_run = MockedRun()
- monkeypatch.setattr(setsystemdservicesstate, 'run', mocked_run)
+def test_process(monkeypatch, msgs, expect_enable_units, expect_disable_units):
+ mocked_enable = MockedSystemdCmd()
+ monkeypatch.setattr(systemd, 'enable_unit', mocked_enable)
+
+ mocked_disable = MockedSystemdCmd()
+ monkeypatch.setattr(systemd, 'disable_unit', mocked_disable)
+
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs))
setsystemdservicesstate.process()
- assert mocked_run.commands == expected_calls
+ assert mocked_enable.units == expect_enable_units
+ assert mocked_disable.units == expect_disable_units
def test_process_invalid(monkeypatch):
@@ -57,7 +67,7 @@ def test_process_invalid(monkeypatch):
msgs = [SystemdServicesTasks(to_enable=['invalid.service'])]
- monkeypatch.setattr(setsystemdservicesstate, 'run', mocked_run)
+ monkeypatch.setattr(systemd, 'run', mocked_run)
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs))
monkeypatch.setattr(api, 'current_logger', logger_mocked())
@@ -69,10 +79,14 @@ def test_process_invalid(monkeypatch):
def test_enable_disable_conflict_logged(monkeypatch):
- msgs = [SystemdServicesTasks(to_enable=['hello.service'],
- to_disable=['hello.service'])]
- mocked_run = MockedRun()
- monkeypatch.setattr(setsystemdservicesstate, 'run', mocked_run)
+ msgs = [SystemdServicesTasks(to_enable=['hello.service'], to_disable=['hello.service'])]
+
+ mocked_enable = MockedSystemdCmd()
+ monkeypatch.setattr(systemd, 'enable_unit', mocked_enable)
+
+ mocked_disable = MockedSystemdCmd()
+ monkeypatch.setattr(systemd, 'disable_unit', mocked_disable)
+
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs))
monkeypatch.setattr(api, 'current_logger', logger_mocked())
diff --git a/repos/system_upgrade/common/libraries/systemd.py b/repos/system_upgrade/common/libraries/systemd.py
index bbf71af7..c709f233 100644
--- a/repos/system_upgrade/common/libraries/systemd.py
+++ b/repos/system_upgrade/common/libraries/systemd.py
@@ -32,6 +32,56 @@ def get_broken_symlinks():
raise
+def _try_call_unit_command(command, unit):
+ try:
+ # it is possible to call this on multiple units at once,
+ # but failing to enable one service would cause others to not enable as well
+ run(['systemctl', command, unit])
+ except CalledProcessError as err:
+ msg = 'Failed to {} systemd unit "{}". Message: {}'.format(command, unit, str(err))
+ api.current_logger().error(msg)
+ raise err
+
+
+def enable_unit(unit):
+ """
+ Enable a systemd unit
+
+ It is strongly recommended to produce SystemdServicesTasks message instead,
+ unless it is absolutely necessary to handle failure yourself.
+
+ :param unit: The systemd unit to enable
+ :raises CalledProcessError: In case of failure
+ """
+ _try_call_unit_command('enable', unit)
+
+
+def disable_unit(unit):
+ """
+ Disable a systemd unit
+
+ It is strongly recommended to produce SystemdServicesTasks message instead,
+ unless it is absolutely necessary to handle failure yourself.
+
+ :param unit: The systemd unit to disable
+ :raises CalledProcessError: In case of failure
+ """
+ _try_call_unit_command('disable', unit)
+
+
+def reenable_unit(unit):
+ """
+ Re-enable a systemd unit
+
+ It is strongly recommended to produce SystemdServicesTasks message, unless it
+ is absolutely necessary to handle failure yourself.
+
+ :param unit: The systemd unit to re-enable
+ :raises CalledProcessError: In case of failure
+ """
+ _try_call_unit_command('reenable', unit)
+
+
def get_service_files():
"""
Get list of unit files of systemd services on the system
--
2.38.1