+ @classmethod
+ def GetVGInfo(cls, vg_names, filter_readonly=True):
+ """Get the free space info for specific VGs.
+
+ @param vg_names: list of volume group names, if empty all will be returned
+ @param filter_readonly: whether to skip over readonly VGs
+
+ @rtype: list
+ @return: list of tuples (free_space, total_size, name) with free_space in
+ MiB
+
+ """
+ try:
+ info = cls._GetVolumeInfo("vgs", ["vg_name", "vg_free", "vg_attr",
+ "vg_size"])
+ except errors.GenericError, err:
+ logging.error("Can't get VG information: %s", err)
+ return None
+
+ data = []
+ for vg_name, vg_free, vg_attr, vg_size in info:
+ # (possibly) skip over vgs which are not writable
+ if filter_readonly and vg_attr[0] == "r":
+ continue
+ # (possibly) skip over vgs which are not in the right volume group(s)
+ if vg_names and vg_name not in vg_names:
+ continue
+ data.append((float(vg_free), float(vg_size), vg_name))
+
+ return data
+
+ @classmethod
+ def _ValidateName(cls, name):
+ """Validates that a given name is valid as VG or LV name.
+
+ The list of valid characters and restricted names is taken out of
+ the lvm(8) manpage, with the simplification that we enforce both
+ VG and LV restrictions on the names.
+
+ """
+ if (not cls._VALID_NAME_RE.match(name) or
+ name in cls._INVALID_NAMES or
+ compat.any(substring in name for substring in cls._INVALID_SUBSTRINGS)):
+ _ThrowError("Invalid LVM name '%s'", name)
+