← Back to team overview

curtin-dev team mailing list archive

[Merge] ~dbungert/curtin:zfs-dracut into curtin:master

 

Dan Bungert has proposed merging ~dbungert/curtin:zfs-dracut into curtin:master.

Commit message:
curthooks: install zfs-dracut as needed

When using zfs, installing zfs-initramfs is only correct if the target
is using initramfs-tools.  Handle the dracut case.

LP: #2125164



Requested reviews:
  curtin developers (curtin-dev)
Related bugs:
  Bug #2125164 in curtin (Ubuntu): "zfs+dracut reverts back to initramfs-tools"
  https://bugs.launchpad.net/ubuntu/+source/curtin/+bug/2125164

For more details, see:
https://code.launchpad.net/~dbungert/curtin/+git/curtin/+merge/492869
-- 
Your team curtin developers is requested to review the proposed merge of ~dbungert/curtin:zfs-dracut into curtin:master.
diff --git a/curtin/block/deps.py b/curtin/block/deps.py
index 952ad53..cfb2590 100644
--- a/curtin/block/deps.py
+++ b/curtin/block/deps.py
@@ -84,9 +84,9 @@ def detect_required_packages_mapping(osfamily=DISTROS.debian):
             'raid': ['mdadm'],
             'reiserfs': ['reiserfsprogs'],
             'xfs': ['xfsprogs'],
-            'zfsroot': ['zfsutils-linux', 'zfs-initramfs'],
-            'zfs': ['zfsutils-linux', 'zfs-initramfs'],
-            'zpool': ['zfsutils-linux', 'zfs-initramfs'],
+            'zfsroot': ['zfsutils-linux'],
+            'zfs': ['zfsutils-linux'],
+            'zpool': ['zfsutils-linux'],
         },
         DISTROS.redhat: {
             'bcache': [],
diff --git a/curtin/commands/curthooks.py b/curtin/commands/curthooks.py
index 5032863..a31ef41 100644
--- a/curtin/commands/curthooks.py
+++ b/curtin/commands/curthooks.py
@@ -15,8 +15,7 @@ from typing import List, Tuple
 from curtin import config
 from curtin import block
 from curtin import distro
-from curtin.block import iscsi
-from curtin.block import lvm
+from curtin.block import iscsi, lvm, zfs
 from curtin import net
 from curtin import futil
 from curtin.log import LOG
@@ -1431,6 +1430,20 @@ def install_missing_packages(cfg, target, osfamily=DISTROS.debian):
             if pkg not in needed_packages:
                 needed_packages.add(pkg)
 
+    if bool(zfs.get_zpool_from_config(cfg)):
+        if osfamily == DISTROS.debian:
+            # zfs on ubuntu requires an additional package, varying by the
+            # installed implementation of linux-initramfs-tool
+            if "initramfs-tools" in installed_packages:
+                needed_packages.add("zfs-initramfs")
+            elif "dracut" in installed_packages:
+                needed_packages.add("zfs-dracut")
+            else:
+                raise ValueError(
+                    "need matching zfs root filesystem capabilities package "
+                    "for linux-initramfs-tool"
+                )
+
     arch = distro.get_architecture()
 
     # UEFI requires grub-efi-{arch}. If a signed version of that package
diff --git a/tests/unittests/test_curthooks.py b/tests/unittests/test_curthooks.py
index 3153f0d..a775573 100644
--- a/tests/unittests/test_curthooks.py
+++ b/tests/unittests/test_curthooks.py
@@ -753,6 +753,81 @@ class TestInstallMissingPkgs(CiTestCase):
         self.mock_install_packages.assert_called_with(
                 expected_pkgs, target=target, osfamily=distro.DISTROS.redhat)
 
+    @patch.object(events, 'ReportEventStack')
+    def test_zfs_install_on_unknown_initramfs_tool(self, mock_events):
+        target = "not-a-real-target"
+
+        self.mock_get_installed_packages.return_value = []
+
+        cfg = {
+            'storage': {
+                'version': 1,
+                'config': [{
+                    'id': 'rpool',
+                    'type': 'zpool',
+                    'pool': 'rpool',
+                }]
+            },
+        }
+
+        with self.assertRaises(ValueError) as exc:
+            curthooks.install_missing_packages(
+                cfg, target, osfamily=self.distro_family
+            )
+        self.assertEqual(
+            "need matching zfs root filesystem capabilities package "
+            "for linux-initramfs-tool",
+            str(exc.exception)
+        )
+
+    @patch.object(events, 'ReportEventStack')
+    def test_zfs_install_on_initramfs_tools(self, mock_events):
+        target = "not-a-real-target"
+
+        self.mock_get_installed_packages.return_value = ["initramfs-tools"]
+
+        cfg = {
+            'storage': {
+                'version': 1,
+                'config': [{
+                    'id': 'rpool',
+                    'type': 'zpool',
+                    'pool': 'rpool',
+                }]
+            },
+        }
+
+        curthooks.install_missing_packages(
+            cfg, target, osfamily=self.distro_family
+        )
+        expected_pkgs = ['zfs-initramfs', 'zfsutils-linux']
+        [mock_call] = self.mock_install_packages.mock_calls
+        self.assertEqual(expected_pkgs, sorted(mock_call.args[0]))
+
+    @patch.object(events, 'ReportEventStack')
+    def test_zfs_install_on_dracut(self, mock_events):
+        target = "not-a-real-target"
+
+        self.mock_get_installed_packages.return_value = ["dracut"]
+
+        cfg = {
+            'storage': {
+                'version': 1,
+                'config': [{
+                    'id': 'rpool',
+                    'type': 'zpool',
+                    'pool': 'rpool',
+                }]
+            },
+        }
+
+        curthooks.install_missing_packages(
+            cfg, target, osfamily=self.distro_family
+        )
+        expected_pkgs = ['zfs-dracut', 'zfsutils-linux']
+        [mock_call] = self.mock_install_packages.mock_calls
+        self.assertEqual(expected_pkgs, sorted(mock_call.args[0]))
+
 
 class TestSetupZipl(CiTestCase):
 

Follow ups