Просмотр исходного кода

Merge pull request #67 from Dany9966/lvs-fix

Replace `lvs --reportformat` output with `lvdisplay`.
Nashwan Azhari 6 лет назад
Родитель
Сommit
567a6e01dc
1 измененных файлов с 38 добавлено и 25 удалено
  1. 38 25
      coriolis/osmorphing/osmount/base.py

+ 38 - 25
coriolis/osmorphing/osmount/base.py

@@ -4,7 +4,6 @@
 
 import abc
 import base64
-import json
 import os
 import re
 
@@ -125,26 +124,14 @@ class BaseLinuxOSMountTools(BaseSSHOSMountTools):
     def _get_lv_paths(self):
         """ Returns list with paths of available LVM volumes. """
         lvm_paths = []
-        out = json.loads(
-            self._exec_cmd(
-                "sudo lvs -o lv_path,lv_name --report-format json").decode())
-        LOG.debug("Decoded `lvs` output data: %s", out)
-
-        reports = out.get("report", [])
-        if not reports:
-            return []
-
-        if len(reports) > 1:
-            LOG.warn("Multiple LVM reports found: %s", reports)
-        report = reports[0]
-
-        for i, lvm in enumerate(report.get("lv", [])):
-            lvm_name = lvm.get("lv_name", str(i))
-            lvm_path = lvm.get("lv_path")
-            if not lvm_path:
-                LOG.warn("No path for lvm volume '%s'", lvm_name)
-            else:
-                lvm_paths.append(lvm_path)
+        out = self._exec_cmd("sudo lvdisplay -c").decode().strip()
+        if out:
+            LOG.debug("Decoded `lvdisplay` output data: %s", out)
+            out_lines = out.split('\n')
+            for line in out_lines:
+                lvm_vol = line.strip().split(':')
+                if lvm_vol:
+                    lvm_paths.append(lvm_vol[0])
 
         LOG.debug("Found LVM device paths: %s", lvm_paths)
         return lvm_paths
@@ -213,23 +200,27 @@ class BaseLinuxOSMountTools(BaseSSHOSMountTools):
         by_uuid_entry_regex = "^(/dev/disk/by-uuid/%s)$" % fs_uuid_regex
         if not mountable_lvm_devs:
             mountable_lvm_devs = []
+        device_paths = self._get_device_file_paths(mountable_lvm_devs)
         for (mountpoint, details) in mounts.items():
             device = details['device']
             if (re.match(fs_uuid_entry_regex, device) is None and
                     re.match(by_uuid_entry_regex, device) is None):
-                if device not in mountable_lvm_devs:
+                device_file_path = self._get_symlink_target(device)
+                if device not in mountable_lvm_devs and (
+                        device_file_path not in device_paths):
                     LOG.warn(
                         "Found fstab entry for dir %s which references device "
                         "%s. Only LVM volumes or devices referenced by UUID=* "
                         "or /dev/disk/by-uuid/* notation are supported. "
-                        "Skipping mounting directory." % (
+                        "Devicemapper paths for LVM volumes are also "
+                        "supported. Skipping mounting directory." % (
                             mountpoint, device))
                     continue
-            elif mountpoint in skip_mounts:
+            if mountpoint in skip_mounts:
                 LOG.debug(
                     "Skipping undesired mount: %s: %s", mountpoint, details)
                 continue
-            elif details["filesystem"] in skip_filesystems:
+            if details["filesystem"] in skip_filesystems:
                 LOG.debug(
                     "Skipping mounting undesired FS for device %s: %s",
                     device, details)
@@ -258,6 +249,28 @@ class BaseLinuxOSMountTools(BaseSSHOSMountTools):
 
         return new_mountpoints
 
+    def _get_symlink_target(self, symlink):
+        target = None
+        try:
+            target = self._exec_cmd('readlink -en %s' % symlink).decode()
+        except Exception:
+            LOG.warn('Target not found for symlink: %s' % symlink)
+
+        return target
+
+    def _get_device_file_paths(self, symlink_list):
+        """ Reads a list of symlink paths, such as `/dev/GROUP/VOLUME0` or
+        `/dev/mapper/GROUP-VOLUME0` and returns a list of respective links'
+        target device file paths, such as `/dev/dm0`
+        """
+        dev_file_paths = []
+        for link in symlink_list:
+            dev_file = self._get_symlink_target(link)
+            if not dev_file:
+                dev_file = link
+            dev_file_paths.append(dev_file)
+        return dev_file_paths
+
     def _get_mounted_devices(self):
         mounts = self._exec_cmd(
             "cat /proc/mounts").decode().split('\n')[:-1]