def vgs(*volume_groups): """Report information about volume groups :param volume_groups: volume groups to report on :returns: list of dicts of vgs parameters """ vgs_args = [ "vgs", "--unbuffered", "--noheadings", "--nosuffix", "--units=b", "--separator=;", "--options=%s" % ",".join(VGS_ATTR), ] vgs_args.extend(list(volume_groups)) process = Popen(vgs_args, stdout=PIPE, stderr=PIPE, preexec_fn=os.setsid, close_fds=True) stdout, stderr = process.communicate() if process.returncode != 0: raise LVMCommandError("vgs", process.returncode, stderr.decode("utf-8")) return parse_lvm_format(VGS_ATTR, stdout)
def lvs(*volume_groups): """Report information about logical volumes `volume_groups` may refer to either an actual volume-group name or to a logical volume path to refer to a single logical volume :param volume_groups: volumes to report on :returns: list of dicts of lvs parameters """ lvs_args = [ "lvs", "--unbuffered", "--noheadings", "--nosuffix", "--units=b", "--separator=;", "--options=%s" % ",".join(LVS_ATTR), ] lvs_args.extend(list(volume_groups)) process = Popen(lvs_args, stdout=PIPE, stderr=PIPE, preexec_fn=os.setsid, close_fds=True) stdout, stderr = process.communicate() if process.returncode != 0: raise LVMCommandError("lvs", process.returncode, stderr.decode("utf-8")) return parse_lvm_format(LVS_ATTR, stdout.decode("utf-8"))
def lvremove(lv_path): """Remove a logical volume :param lv_path: logical volume to remove :raises: LVMCommandError if lvremove returns with non-zero status """ lvremove_args = [ 'lvremove', '--force', lv_path, ] process = Popen(lvremove_args, stdout=PIPE, stderr=PIPE, preexec_fn=os.setsid, close_fds=True) stdout, stderr = process.communicate() for line in stdout.decode('utf-8').splitlines(): if not line: continue LOG.debug("%s : %s", list2cmdline(lvremove_args), line) if process.returncode != 0: raise LVMCommandError(list2cmdline(lvremove_args), process.returncode, stderr.decode('utf-8').strip())
def mount(device, path, options=None, vfstype=None): """Mount a filesystem :raises: LVMCommandError """ mount_args = ["mount"] if options: mount_args.extend(["-o", options]) if vfstype: mount_args.extend(["-t", vfstype]) mount_args.extend([device, path]) process = Popen(mount_args, stdout=PIPE, stderr=PIPE, preexec_fn=os.setsid, close_fds=True) stdout, stderr = process.communicate() if process.returncode != 0: cmd_str = list2cmdline(mount_args) raise LVMCommandError(cmd_str, process.returncode, stderr.decode("utf-8")) return stdout
def pvs(*physical_volumes): """Report information about physical volumes :param volume_groups: volume groups to report on :returns: list of dicts of pvs parameters """ pvs_args = [ 'pvs', '--unbuffered', '--noheadings', '--nosuffix', '--units=b', '--separator=;', '--options=%s' % ','.join(PVS_ATTR), ] pvs_args.extend(list(physical_volumes)) process = Popen(pvs_args, stdout=PIPE, stderr=PIPE, preexec_fn=os.setsid, close_fds=True) stdout, stderr = process.communicate() if process.returncode != 0: raise LVMCommandError('pvs', process.returncode, stderr.decode('utf-8')) return parse_lvm_format(PVS_ATTR, stdout)
def umount(*path): """Unmount a file system :raises: LVMCommandError """ process = Popen(['umount'] + list(path), stdout=PIPE, stderr=PIPE, preexec_fn=os.setsid, close_fds=True) stdout, stderr = process.communicate() if process.returncode != 0: cmd_str = list2cmdline(['umount'] + list(path)) raise LVMCommandError(cmd_str, process.returncode, stderr) return stdout
def blkid(*devices): """Locate/print block device attributes :param devices: devices to run blkid against :returns: iterable of dicts of blkid data """ blkid_args = ["blkid", "-c", "/dev/null"] blkid_args.extend([os.path.realpath(dev) for dev in devices]) process = Popen(blkid_args, stdout=PIPE, stderr=PIPE, close_fds=True) stdout, stderr = process.communicate() if process.returncode != 0: cmd_str = list2cmdline(blkid_args) raise LVMCommandError(cmd_str, process.returncode, stderr.decode("utf-8")) return parse_blkid_format(stdout.decode("utf-8"))
def lvsnapshot(orig_lv_path, snapshot_name, snapshot_extents, chunksize=None): """Create a snapshot of an existing logical volume :param snapshot_lv_name: name of the snapshot :param orig_lv_path: path to the logical volume being snapshotted :param snapshot_extents: size to allocate to snapshot volume in extents :param chunksize: (optional) chunksize of the snapshot volume """ lvcreate_args = [ "lvcreate", "--snapshot", "--name", str(snapshot_name), "--extents", "%d" % snapshot_extents, str(orig_lv_path), ] if chunksize: lvcreate_args.insert(-1, "--chunksize") lvcreate_args.insert(-1, chunksize) LOG.debug("%s", list2cmdline(lvcreate_args)) process = Popen(lvcreate_args, stdout=PIPE, stderr=PIPE, preexec_fn=os.setsid, close_fds=True) stdout, stderr = process.communicate() for line in stdout.decode("utf-8").splitlines(): if not line: continue LOG.debug("lvcreate: %s", line) if process.returncode != 0: raise LVMCommandError(list2cmdline(lvcreate_args), process.returncode, stderr.decode("utf-8").strip())
def test_errors(self): """ Test LVM errors""" exc = LVMCommandError("cmd", -1, "error message") self.assertEqual(exc.cmd, "cmd") self.assertEqual(exc.status, -1) self.assertEqual(exc.error, "error message")