示例#1
0
    def blkid(self):
        """Return the blkid output of each device in devices
        {"<device>": {"UUID": "<UUID">", "TYPE": "<TYPE>"}

        blkid is used to get the filesystem and UUID of a block device
        """
        if self._blkid:
            return self._blkid
        self.debug_action(action="GET BLKID DATA")
        _blkid = {}
        blkid_lines = run("blkid")

        def blkid_val(line, prop):
            """ Return the blkid property value if present else none """
            word = next(
                (elem for elem in line.split(" ") if f"{prop}=" in elem), None)
            if word:
                return word.split("=")[1].replace('"', "")
            return None

        for line in blkid_lines:
            split = line.split(" ")
            if not split[0]:
                continue
            path = split[0].replace(":", "")
            uuid = blkid_val(line, "UUID")
            type_ = blkid_val(line, "TYPE")
            _blkid[path] = {"UUID": uuid, "TYPE": type_}
        self._blkid = _blkid
        for device in _blkid:
            debug(f"{device}: {_blkid[device]}")
        self.debug_action(end=True)
        return _blkid
示例#2
0
 def lvm_lvs(self):
     """Return a dict of of LVM logical volumes on the given devices
     {"<device mapper path>": { name: "<name>", devices: [<partitions/PVs>] }}
     """
     if self._lvm_lvs:
         return self._lvm_lvs
     self.debug_action(action="FIND LVM LV's")
     lvs = {}
     for lvm_pv in self.lvm_pvs:
         pv_lv_lines = grep(f"pvdisplay -m {lvm_pv}", "Logical volume")
         # pv_lv_lines looks like this: ['    Logical volume\t/dev/vg_rhel610/lv_root']
         for pv_lv in pv_lv_lines:
             # example's name is /dev/vg_rhel610/lv_root
             name = pv_lv.strip().split("\t")[1]
             dm_path = run(f"lvdisplay -C -o lv_dm_path {name}")[1].strip()
             if dm_path not in lvs:
                 # First time encountering this LV
                 lvs[dm_path] = {"name": name, "devices": [lvm_pv]}
             else:
                 # This LV was in a prior device, just add this device to it
                 lvs[dm_path]["devices"].append(lvm_pv)
     self._lvm_lvs = lvs
     debug(f"lvs: {list(lvs)}")
     self.debug_action(end=True)
     return lvs
示例#3
0
def get_vmdk_thick_size(file_path):
    """ Return the 'thick' size of a VMDK file in bytes as an integer - requires qemu-utils """
    qemu_img_lines = run(f"qemu-img info {file_path}")
    vsize_line = next(line for line in qemu_img_lines
                      if "virtual size" in line)
    size_bytes = int(vsize_line.split(" ")[-2].replace("(", ""))
    return size_bytes
示例#4
0
 def repair_partitions(self):
     """ Repair a given partition using the appropriate tool"""
     if is_mounted(self.ROOT_MOUNT):
         error("ERROR: Cannot repair partitions when they are mounted",
               exit=True)
     for partition in self.data_volumes:
         filesystem = self.blkid[partition]["TYPE"]
         if filesystem == "xfs":
             print(f" > Repairing XFS partition {partition}")
             run(f"xfs_repair {partition}")
         elif "ext" in filesystem:
             print(f" > Repairing {filesystem} partition {partition}")
             repair_cmd = f"fsck.{filesystem} -y {partition}"
             run(repair_cmd)
         else:
             print(
                 f" ! Cannot repair {partition} - unsupported filesystem: {filesystem}"
             )
示例#5
0
 def lvm_pvs(self):
     """ Return a list of physical volumes (partitions) from LVM that match given devices """
     if self._lvm_pvs:
         return self._lvm_pvs
     self.debug_action(action="FIND LVM PV's")
     pvs = []
     pvs_lines = run("pvs")
     for line in pvs_lines:
         partition = line.strip().split(" ")[0]
         if "/dev/" not in partition:
             continue
         if partition in self.fdisk_partitions:
             pvs.append(partition)
             self._lvm_pvs = pvs
     self.debug_action(end=True)
     return pvs
示例#6
0
 def fdisk_partitions(self):
     """ return list of partitions on devices """
     if self._fdisk_partitions:
         return self._fdisk_partitions
     self.debug_action(action="FIND FDISK PARTITIONS")
     partitions = []
     if not self.devices:
         error(
             "ERROR: Cannot list partitions when devices are not specified",
             exit=True)
     for device in self.devices:
         fdisk = run(f"fdisk -l {device}")
         partition_lines = (line for line in fdisk
                            if line.startswith(device))
         for partition_line in partition_lines:
             partitions.append(partition_line.split(" ")[0])
     self._fdisk_partitions = partitions
     debug(f"fdisk_partitions: {partitions}")
     self.debug_action(end=True)
     return partitions
示例#7
0
 def boot_mode(self):
     """ Return either "UEFI" or "BIOS" - Determine how this device boots """
     if self._boot_mode:
         return self._boot_mode
     self.debug_action(action="FIND BOOT MODE")
     # Get the disk of the boot partition, ex /dev/vdb for /dev/vdb1
     drive = "".join(
         [char for char in self.boot_volume if not char.isdigit()])
     # Read fdisk's Disklabel for the disk
     fdisk = run(f"fdisk -l {drive}")
     disk_type_line = next(
         (line for line in fdisk if "Disklabel type" in line), None)
     if disk_type_line is None:
         error(
             f"Error: Failed to determine boot mode of {self.boot_volume}",
             exit=True)
     disk_type = disk_type_line.split(" ")[-1]
     _boot_mode = "UEFI" if (disk_type == "gpt") else "BIOS"
     self._boot_mode = _boot_mode
     self.debug_action(end=True)
     return _boot_mode
示例#8
0
 def add_virtio_drivers(self, force=False):
     """ Install VirtIO drivers to mounted system """
     if not self.was_root_mounted:
         error("ERROR: You must mount the volumes before you can add virtio drivers", exit=True)
     self.debug_action(action="ADD VIRTIO DRIVERS")
     ls_boot_lines = run(f"ls {self.ROOT_MOUNT}/boot")
     initram_lines = [
         line
         for line in ls_boot_lines
         if line.startswith("initramfs-") and line.endswith(".img") and "dump" not in line
     ]
     for filename in initram_lines:
         if "rescue" in filename or "kdump" in filename:
             debug(f"Skipping rescue/kdump file: {filename}")
             continue
         kernel_version = filename.replace("initramfs-", "").replace(".img", "")
         debug("Running lsinitrd to check for virtio drivers")
         lsinitrd = self.chroot_run(f"lsinitrd /boot/{filename}")
         virtio_line = next((line for line in lsinitrd if "virtio" in line.lower()), None)
         if virtio_line is not None:
             print(f"{filename} already has virtio drivers")
             if force:
                 print("force=true, reinstalling")
             else:
                 continue
         print(f"Adding virtio drivers to {filename}")
         drivers = "virtio_blk virtio_net virtio_scsi virtio_balloon"
         cmd = f'dracut --add-drivers "{drivers}" -f /boot/{filename} {kernel_version}'
         # Python+chroot causes dracut space delimiter to break - use a script file
         script_file = f"{self.ROOT_MOUNT}/virtio.sh"
         debug(f"writing script file: {script_file}")
         debug(f"script file contents: {cmd}")
         set_file_contents(script_file, cmd)
         self.chroot_run("bash /virtio.sh")
         debug(f"deleting script file: {script_file}")
         os.remove(script_file)
     self.debug_action(end=True)
示例#9
0
def download_thread(url, file_path):
    """ Start a thread to download the file """
    run(f"wget --quiet --no-check-certificate {url} -O {file_path}")
示例#10
0
 def chroot_run(self, cmd):
     """ Run a command in the chroot """
     if not is_mounted(self.ROOT_MOUNT):
         error("ERROR: Root volume not mounted", exit=True)
     return run(f"chroot {self.ROOT_MOUNT} {cmd}")