leapp-repository/SOURCES/0003-feat-lvm_autoactivation-add-lvm-autoactivation.patch
2025-12-01 09:14:24 +00:00

133 lines
5.5 KiB
Diff

From 04a2ec2574da233a41d32f70eab780b6c305ff31 Mon Sep 17 00:00:00 2001
From: Michal Hecko <mhecko@redhat.com>
Date: Thu, 19 Dec 2024 10:33:24 +0100
Subject: [PATCH 03/55] feat(lvm_autoactivation): add lvm autoactivation
Add LVM autoactivation mechanism to the upgrade initramfs. The core
of the mechanism is based on a special udev rule that is triggered
when a new device is detected. The rule then calls two lvm binaries
(which are also included into the upgrade initrams) to activate
the volume groups and logical volumes.
---
.../enable_lvm_autoactivation/actor.py | 21 ++++++++
.../libraries/enable_lvm_autoactivation.py | 21 ++++++++
.../test_lvm_autoactivation_enablement.py | 50 +++++++++++++++++++
3 files changed, 92 insertions(+)
create mode 100644 repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/actor.py
create mode 100644 repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/libraries/enable_lvm_autoactivation.py
create mode 100644 repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/tests/test_lvm_autoactivation_enablement.py
diff --git a/repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/actor.py b/repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/actor.py
new file mode 100644
index 00000000..aba60645
--- /dev/null
+++ b/repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/actor.py
@@ -0,0 +1,21 @@
+from leapp.actors import Actor
+from leapp.libraries.actor import enable_lvm_autoactivation as enable_lvm_autoactivation_lib
+from leapp.models import DistributionSignedRPM, UpgradeInitramfsTasks
+from leapp.tags import FactsPhaseTag, IPUWorkflowTag
+
+
+class EnableLVMAutoactivation(Actor):
+ """
+ Enable LVM autoactivation in upgrade initramfs.
+
+ Produce instructions for upgrade initramfs generation that will result in LVM
+ autoactivation in the initramfs.
+ """
+
+ name = 'enable_lvm_autoactivation'
+ consumes = (DistributionSignedRPM,)
+ produces = (UpgradeInitramfsTasks, )
+ tags = (FactsPhaseTag, IPUWorkflowTag)
+
+ def process(self):
+ enable_lvm_autoactivation_lib.emit_lvm_autoactivation_instructions()
diff --git a/repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/libraries/enable_lvm_autoactivation.py b/repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/libraries/enable_lvm_autoactivation.py
new file mode 100644
index 00000000..e312277b
--- /dev/null
+++ b/repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/libraries/enable_lvm_autoactivation.py
@@ -0,0 +1,21 @@
+from leapp.libraries.common.rpms import has_package
+from leapp.libraries.stdlib import api
+from leapp.models import DistributionSignedRPM, UpgradeInitramfsTasks
+
+
+def emit_lvm_autoactivation_instructions():
+ if not has_package(DistributionSignedRPM, 'lvm2'):
+ api.current_logger().debug(
+ 'Upgrade initramfs will not autoenable LVM devices - `lvm2` RPM is not installed.'
+ )
+ return
+
+ # the 69-dm-lvm.rules trigger pvscan and vgchange when LVM device is detected
+ files_to_include = [
+ '/usr/sbin/pvscan',
+ '/usr/sbin/vgchange',
+ '/usr/lib/udev/rules.d/69-dm-lvm.rules'
+ ]
+ lvm_autoactivation_instructions = UpgradeInitramfsTasks(include_files=files_to_include)
+
+ api.produce(lvm_autoactivation_instructions)
diff --git a/repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/tests/test_lvm_autoactivation_enablement.py b/repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/tests/test_lvm_autoactivation_enablement.py
new file mode 100644
index 00000000..c5150aea
--- /dev/null
+++ b/repos/system_upgrade/common/actors/initramfs/enable_lvm_autoactivation/tests/test_lvm_autoactivation_enablement.py
@@ -0,0 +1,50 @@
+from leapp.libraries.actor import enable_lvm_autoactivation
+from leapp.libraries.common.testutils import CurrentActorMocked, produce_mocked
+from leapp.libraries.stdlib import api
+from leapp.models import DistributionSignedRPM, RPM, UpgradeInitramfsTasks
+
+
+def test_emit_lvm_autoactivation_instructions_produces_correct_message(monkeypatch):
+ """Test that emit_lvm_autoactivation_instructions produces UpgradeInitramfsTasks with correct files."""
+ lvm_package = RPM(
+ name='lvm2',
+ version='2',
+ release='1',
+ epoch='1',
+ packager='',
+ arch='x86_64',
+ pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 199e2f91fd431d51'
+ )
+
+ msgs = [
+ DistributionSignedRPM(items=[lvm_package])
+ ]
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs))
+ monkeypatch.setattr(api, 'produce', produce_mocked())
+
+ enable_lvm_autoactivation.emit_lvm_autoactivation_instructions()
+
+ assert api.produce.called == 1
+
+ produced_msg = api.produce.model_instances[0]
+
+ assert isinstance(produced_msg, UpgradeInitramfsTasks)
+
+ expected_files = [
+ '/usr/sbin/pvscan',
+ '/usr/sbin/vgchange',
+ '/usr/lib/udev/rules.d/69-dm-lvm.rules'
+ ]
+ assert produced_msg.include_files == expected_files
+
+
+def test_no_action_if_lvm_rpm_missing(monkeypatch):
+ msgs = [
+ DistributionSignedRPM(items=[])
+ ]
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs))
+ monkeypatch.setattr(api, 'produce', produce_mocked())
+
+ enable_lvm_autoactivation.emit_lvm_autoactivation_instructions()
+
+ assert api.produce.called == 0
--
2.51.1