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}')