diff --git a/patches/0015-ceph-volume-fix-set_dmcrypt_no_workqueue.patch b/patches/0015-ceph-volume-fix-set_dmcrypt_no_workqueue.patch new file mode 100644 index 000000000..c6d7d0131 --- /dev/null +++ b/patches/0015-ceph-volume-fix-set_dmcrypt_no_workqueue.patch @@ -0,0 +1,91 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Guillaume Abrioux +Date: Fri, 7 Jun 2024 10:46:16 +0200 +Subject: [PATCH] ceph-volume: fix set_dmcrypt_no_workqueue() + +`set_dmcrypt_no_workqueue()` from `ceph_volume.util.encryption` + +The function `set_dmcrypt_no_workqueue` in `encryption.py` now +dynamically retrieves the installed cryptsetup version using `cryptsetup +--version` command. It then parses the version string using a regular +expression to accommodate varying digit counts. If the retrieved version +is greater than or equal to the specified target version, +`conf.dmcrypt_no_workqueue` is set to True, allowing for flexible version +handling. + +Fixes: https://tracker.ceph.com/issues/66393 + +Signed-off-by: Guillaume Abrioux +(cherry picked from commit dc28b77a6ea50b3390663ac02eeb80367650b7ed) +(cherry picked from commit 05ea72c70e06cc70f74b459c399c43f0a8863986) +Signed-off-by: Thomas Lamprecht +--- + .../ceph_volume/util/encryption.py | 44 +++++++++++++++++-- + 1 file changed, 40 insertions(+), 4 deletions(-) + +diff --git a/src/ceph-volume/ceph_volume/util/encryption.py b/src/ceph-volume/ceph_volume/util/encryption.py +index 844a81620d2..09f1cccf384 100644 +--- a/src/ceph-volume/ceph_volume/util/encryption.py ++++ b/src/ceph-volume/ceph_volume/util/encryption.py +@@ -1,6 +1,7 @@ + import base64 + import os + import logging ++import re + from ceph_volume import process, conf, terminal + from ceph_volume.util import constants, system + from ceph_volume.util.device import Device +@@ -12,14 +13,49 @@ logger = logging.getLogger(__name__) + mlogger = terminal.MultiLogger(__name__) + + def set_dmcrypt_no_workqueue(target_version: str = '2.3.4') -> None: +- """ +- set `conf.dmcrypt_no_workqueue` to `True` if the available +- version of `cryptsetup` is greater or equal to `version` ++ """Set `conf.dmcrypt_no_workqueue` to `True` if the installed version ++ of `cryptsetup` is greater than or equal to the specified `target_version`. ++ ++ Depending on the crypsetup version, `cryptsetup --version` output can be different. ++ Eg: ++ ++ CentOS Stream9: ++ $ cryptsetup --version ++ cryptsetup 2.6.0 flags: UDEV BLKID KEYRING FIPS KERNEL_CAPI PWQUALITY ++ ++ CentOS Stream8: ++ $ cryptsetup --version ++ cryptsetup 2.3.7 ++ ++ Args: ++ target_version (str, optional): The minimum version required for setting ++ `conf.dmcrypt_no_workqueue` to `True`. Defaults to '2.3.4'. ++ ++ Raises: ++ RuntimeError: If failed to retrieve the cryptsetup version. ++ RuntimeError: If failed to parse the cryptsetup version. ++ RuntimeError: If failed to compare the cryptsetup version with the target version. + """ + command = ["cryptsetup", "--version"] + out, err, rc = process.call(command) ++ ++ # This regex extracts the version number from ++ # the `cryptsetup --version` output ++ pattern: str = r'\b\d+(\.\d+)*\b' ++ ++ if rc: ++ raise RuntimeError(f"Can't retrieve cryptsetup version: {err}") ++ + try: +- if version.parse(out[0]) >= version.parse(f'cryptsetup {target_version}'): ++ cryptsetup_version = re.match(pattern, out[0]) ++ ++ if cryptsetup_version is None: ++ _output: str = "\n".join(out) ++ raise RuntimeError('Error while checking cryptsetup version.\n', ++ '`cryptsetup --version` output:\n', ++ f'{_output}') ++ ++ if version.parse(cryptsetup_version.group(0)) >= version.parse(target_version): + conf.dmcrypt_no_workqueue = True + except IndexError: + mlogger.debug(f'cryptsetup version check: rc={rc} out={out} err={err}') diff --git a/patches/0016-ceph-volume-fix-regex-usage-in-set_dmcrypt_no_workqu.patch b/patches/0016-ceph-volume-fix-regex-usage-in-set_dmcrypt_no_workqu.patch new file mode 100644 index 000000000..6d90f8d66 --- /dev/null +++ b/patches/0016-ceph-volume-fix-regex-usage-in-set_dmcrypt_no_workqu.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Guillaume Abrioux +Date: Wed, 19 Jun 2024 15:06:52 +0200 +Subject: [PATCH] ceph-volume: fix regex usage in `set_dmcrypt_no_workqueue` + +- Updated the regex pattern to `r'(\d+\.?)+'` to more accurately + capture version numbers. + +- Replaced `re.match` with `re.search` to properly match the cryptsetup + version in the output. + +- `re.match` only checks for a match at the beginning of the string, + while `re.search` looks for a match anywhere in the string. + +This fix ensures that the function correctly retrieves the +cryptsetup version from the output. + +Fixes: https://tracker.ceph.com/issues/66393 + +Signed-off-by: Guillaume Abrioux +(cherry picked from commit 607eb34b2c278566c386efcbf3018629cf08ccfd) +(cherry picked from commit d49b2888486623415a038630da54f5e1c99f1c63) +Signed-off-by: Thomas Lamprecht +--- + .../ceph_volume/tests/util/test_encryption.py | 40 ++++++++++++++++++- + .../ceph_volume/util/encryption.py | 4 +- + 2 files changed, 41 insertions(+), 3 deletions(-) + +diff --git a/src/ceph-volume/ceph_volume/tests/util/test_encryption.py b/src/ceph-volume/ceph_volume/tests/util/test_encryption.py +index cd2ea8f187f..200f1da84d8 100644 +--- a/src/ceph-volume/ceph_volume/tests/util/test_encryption.py ++++ b/src/ceph-volume/ceph_volume/tests/util/test_encryption.py +@@ -1,6 +1,44 @@ + from ceph_volume.util import encryption +-from mock.mock import patch ++from mock.mock import patch, Mock + import base64 ++import pytest ++ ++ ++class TestNoWorkqueue: ++ def setup_method(self): ++ encryption.conf.dmcrypt_no_workqueue = None ++ ++ @patch('ceph_volume.util.encryption.process.call', ++ Mock(return_value=(['cryptsetup 2.7.2 flags: UDEV BLKID KEYRING' \ ++ 'FIPS KERNEL_CAPI PWQUALITY '], [''], 0))) ++ def test_set_dmcrypt_no_workqueue_true(self): ++ encryption.set_dmcrypt_no_workqueue() ++ assert encryption.conf.dmcrypt_no_workqueue ++ ++ @patch('ceph_volume.util.encryption.process.call', ++ Mock(return_value=(['cryptsetup 2.0.0'], [''], 0))) ++ def test_set_dmcrypt_no_workqueue_false(self): ++ encryption.set_dmcrypt_no_workqueue() ++ assert encryption.conf.dmcrypt_no_workqueue is None ++ ++ @patch('ceph_volume.util.encryption.process.call', ++ Mock(return_value=([''], ['fake error'], 1))) ++ def test_set_dmcrypt_no_workqueue_cryptsetup_version_fails(self): ++ with pytest.raises(RuntimeError): ++ encryption.set_dmcrypt_no_workqueue() ++ ++ @patch('ceph_volume.util.encryption.process.call', ++ Mock(return_value=(['unexpected output'], [''], 0))) ++ def test_set_dmcrypt_no_workqueue_pattern_not_found(self): ++ with pytest.raises(RuntimeError): ++ encryption.set_dmcrypt_no_workqueue() ++ ++ @patch('ceph_volume.util.encryption.process.call', ++ Mock(return_value=([], [''], 0))) ++ def test_set_dmcrypt_no_workqueue_index_error(self): ++ with pytest.raises(RuntimeError): ++ encryption.set_dmcrypt_no_workqueue() ++ + + class TestGetKeySize(object): + def test_get_size_from_conf_default(self, conf_ceph_stub): +diff --git a/src/ceph-volume/ceph_volume/util/encryption.py b/src/ceph-volume/ceph_volume/util/encryption.py +index 09f1cccf384..15a31315645 100644 +--- a/src/ceph-volume/ceph_volume/util/encryption.py ++++ b/src/ceph-volume/ceph_volume/util/encryption.py +@@ -41,13 +41,13 @@ def set_dmcrypt_no_workqueue(target_version: str = '2.3.4') -> None: + + # This regex extracts the version number from + # the `cryptsetup --version` output +- pattern: str = r'\b\d+(\.\d+)*\b' ++ pattern: str = r'(\d+\.?)+' + + if rc: + raise RuntimeError(f"Can't retrieve cryptsetup version: {err}") + + try: +- cryptsetup_version = re.match(pattern, out[0]) ++ cryptsetup_version = re.search(pattern, out[0]) + + if cryptsetup_version is None: + _output: str = "\n".join(out) diff --git a/patches/series b/patches/series index a52bc4c67..efde3ed4a 100644 --- a/patches/series +++ b/patches/series @@ -12,3 +12,5 @@ 0012-ceph-osd-postinst-do-not-always-reload-all-sysctl-se.patch 0013-debian-recursively-adjust-permissions-of-var-lib-cep.patch 0014-ceph-crash-change-order-of-client-names.patch +0015-ceph-volume-fix-set_dmcrypt_no_workqueue.patch +0016-ceph-volume-fix-regex-usage-in-set_dmcrypt_no_workqu.patch