Exemplo n.º 1
0
    def mount(self, libvirt=False):
        """
		Mount the specified image to local host as block device.

		:param libvirt: Only mount if needed for libvirt (i.e. if mount not
		supported by libvirt 0.12)

		:return: True if successful, otherwise False
		"""
        # Files can be mounted by libvirt
        if libvirt:
            return True

        out, rc = cziso.run_command("kpartx -a %s" % self.file)
        if rc != 0:
            self.logger.error("Unable to mount %s as a control loop device")
            return False
        out, rc = cziso.run_command("losetup -a")
        for line in out:
            if line.find(self.file) >= 0:
                matcher = re.search("(/dev/loop\d+)", line)
                if matcher:
                    self.loop_device = matcher.group(1)
                    self.logger.info("Mounted image %s as %s" %
                                     (self.file, self.loop_device))
                    return True
        if not self.loop_device:
            self.logger.error("Unable to find loop device for %s" % self.file)
            return False
        return True
Exemplo n.º 2
0
    def promote_cloned_vols(self):
        """
		Find out if there any dependent vols on our vol.  If so promote them so they
		are independent of ours.

		:return: True if no dependent vols or if successfully promoted.  False if
		error.
		"""
        out, rc = cziso.run_command("ssh %s zfs list -o name,origin" %
                                    self.nas)
        children_re = re.compile("(\S+)\s+%s/%s@\S+" % (self.pool, self.vol))
        child_vols = []
        for line in out:
            matcher = children_re.match(line)
            if matcher is not None:
                child_vols.append(matcher.group(1))
        for vol in child_vols:
            self.logger.info(
                "Promoting depending volume %s (dependent on %s)" %
                (vol, self.vol))
            out, rc = cziso.run_command("ssh %s zfs promote %s" %
                                        (self.nas, vol))
            if rc != 0:
                self.logger.error("Error promoting volume %s" % vol)
                return False
            self.logger.info("Volume %s successfully promoted" % vol)
        return True
Exemplo n.º 3
0
    def _get_disk_info(self):
        """
		Find the provided image partitions on local host and disk size

		:return: A tuple containing the disk size and string array containing
		location of image partitions
		"""
        mount = self.get_mount()
        if self.get_mount() is None:
            self.logger.error("Disk is not mounted")
            return None, None
        out, rc = cziso.run_command("fdisk -l %s" % mount)
        if rc != 0:
            cziso.abort("Unable to run fdisk command")

        for line in out:
            if self.size_gb == 0:
                matcher = re.search("^Disk \S+: ([\d\.]+) GB", line)
                if matcher is not None:
                    size_gb_float = float(matcher.group(1))
                    self.size_gb = int(math.ceil(size_gb_float))
                    self.logger.info("Disk size is %i GB" % self.size_gb)
            matcher = re.match("^(%s\S+).*\s+(\S+)$" % mount, line)
            if matcher:
                if matcher.group(2) == "Linux":
                    self.partitions.append(matcher.group(1))
        if self.size_gb == 0:
            cziso.abort("Unable to find disk size of %s" % self)
        return self.size_gb, self.partitions
Exemplo n.º 4
0
    def exists(self):
        """
		Verifies specified VM image zvol exists on NAS device

		:return: True if image exists; otherwise False
		"""
        out, rc = cziso.run_command("ssh %s zfs list %s/%s" %
                                    (self.nas, self.pool, self.vol))
        return rc == 0
Exemplo n.º 5
0
    def unmount(self):
        """
		Unmount the specified image from localhost

		:return: True if successful; otherwise False
		"""
        out, rc = cziso.run_command("rocks remove host storagemap %s %s" %
                                    (self.nas, self.vol))
        if rc != 0:
            self.logger.error("Unable to unmount zvol at %s" % self.mount)
            return False
        self.mountpoint = None
        return True
Exemplo n.º 6
0
 def is_mapped(self):
     out, rc = cziso.run_command("rocks list host storagemap %s" % self.nas)
     if rc != 0:
         cziso.abort("Unable to list current storagemap")
     mapped_pattern = "^%s\s+%s.*\s+(\S*mapped)\s+.*" % (self.vol,
                                                         self.pool)
     self.logger.debug("Looking for pattern '%s'" % mapped_pattern)
     for line in out:
         matcher = re.search(mapped_pattern, line)
         if matcher is not None:
             mapped_status = matcher.group(1)
             self.logger.debug("Status of vol %s is %s" %
                               (self.vol, mapped_status))
             return mapped_status == "mapped"
     return False
Exemplo n.º 7
0
    def create(self, size):
        """
		Create the image file

		:param size An integer containing the file size in GB

		:return: True if image created; otherwise False
		"""
        out, rc = cziso.run_command("qemu-img create -f %s %s %iG" %
                                    (self.qemu_type, self.file, size))
        if rc != 0:
            self.logger.error("Unable to create image: %s" % "\n".join(out))
            return False
        self.logger.info("Created image file %s (%i GB)" % (self.file, size))
        return True
Exemplo n.º 8
0
    def unmount(self):
        """
		Unmount the specified image from localhost

		:return: True if successful; otherwise False
		"""
        if self.loop_device is None:
            self.logger.debug("No loop device needs to be unmounted")
            return True

        out, rc = cziso.run_command("kpartx -d %s" % self.file)
        if rc != 0:
            self.logger.error("Unable to remove loop device %s" %
                              self.loop_device)
            return False
        self.loop_device = None
        return True
Exemplo n.º 9
0
    def fsck(self):
        """
		Runs fsck on disk to repair any issues

		:return:  True if successful; otherwise False
		"""
        self.logger.info("Running fsck on disk partitions")
        self._get_disk_info()
        if not self.partitions:
            cziso.abort("Unable to find any partitions on disk")
        for partition in self.partitions:
            out, rc = cziso.run_command("fsck -y %s" % partition)
            if rc != 0:
                self.unmount()
                cziso.abort("Problem running fsck -y on partition: %s" %
                            "\n".join(out))
            self.logger.debug("fsck output: %s" % "\n".join(out))
Exemplo n.º 10
0
    def create(self, size):
        """
		Create the image file

		:param size An integer containing the file size in GB

		:return: True if image created; otherwise False
		"""
        out, rc = cziso.run_command(
            "rocks add host storagemap %s %s %s %s %i img_sync=false" %
            (self.nas, self.pool, self.vol, self.hostname, size))
        if rc != 0:
            self.logger.error("Unable to create zvol to %s: %s" %
                              (self.vol, "\n".join(out)))
            return False
        self.logger.info("Created ZFS vol %s (%i GB)" % (self, size))
        self.mountpoint = out[1]
        return True
Exemplo n.º 11
0
    def update(self, zip_path, out_dir=os.getcwd()):
        """
		Generate new Clonezilla Live ISOs for both the custom and regular
		cases.

		:param zip_path: A string containing the path to a Clonezilla zip
		release
		:param out_dir: A string containing a path to where the ISOs should
		be written

		:return: A tuple containing the path to the regular and custom ISOs
		"""
        self.logger.info("Generating custom ISO for %s" % zip_path)
        cz_version = os.path.splitext(os.path.basename(zip_path))[0]

        tmp = self.create_temp_directory()
        self.logger.debug("Created temporary directory %s" % tmp)

        # unpack zip
        zip_dir = os.path.join(tmp, "zip")
        out, rc = cziso.run_command("unzip %s -d %s" % (zip_path, zip_dir))
        if rc != 0:
            cziso.abort("Unable to unzip %s: %s" % (zip_path, "\n".join(out)))

        # generate regular ISO
        regular_iso = os.path.join(out_dir, "%s-regular.iso" % cz_version)
        cziso.generate_iso(self.genisoimage_command, zip_dir, regular_iso)

        # customize file
        isolinux_file = os.path.join(zip_dir, "syslinux", "isolinux.cfg")
        if not os.path.exists(isolinux_file):
            cziso.abort("Unable to find %s" % isolinux_file)
        self.logger.info("Editing %s" % isolinux_file)
        cziso.file_edit(isolinux_file, Clonezilla.CUSTOMIZATIONS)

        # generate custom ISO
        custom_iso = os.path.join(out_dir, "%s-custom.iso" % cz_version)
        cziso.generate_iso(self.genisoimage_command, zip_dir, custom_iso)

        # cleanup
        self.logger.debug("Removing temporary directory %s" % tmp)
        shutil.rmtree(tmp)

        return regular_iso, custom_iso
Exemplo n.º 12
0
    def delete(self):
        """
		Remove the image file

		:return: True if image deleted; otherwise False
		"""
        if self.is_mapped():
            self.unmount()

        if not self.promote_cloned_vols():
            self.logger.error("Volume %s is not removable" % self.vol)
            return False

        out, rc = cziso.run_command("rocks remove host storageimg %s %s %s" %
                                    (self.nas, self.pool, self.vol))
        if rc != 0:
            self.logger.error("Unable to delete image: %s" % "\n".join(out))
            return False
        return True
Exemplo n.º 13
0
    def __init__(self, image):
        """
		Constructor for ZFS vol backed VM image.

		:param image:  The URI of the image of zfs://nas/pool/vol format
		"""
        Image.__init__(self, image, "block", "raw")
        matcher = ZfsVol.match(image)
        self.nas = matcher.group(1)
        self.pool = matcher.group(2)
        self.vol = matcher.group(3)
        self.logger.debug(
            "Creating ZfsVol instance for vol %s in pool %s at %s" %
            (self.vol, self.pool, self.nas))
        out, rc = cziso.run_command(
            "rocks report host attr localhost attr=hostname")
        if rc != 0:
            cziso.abort("Unable to determine physical hostname")
        self.hostname = out[0]
        self.mountpoint = None
Exemplo n.º 14
0
    def mount(self, libvirt=False):
        """
		Mount the specified image to local host as block device.

		:param libvirt: Only mount if needed for libvirt (i.e. if mount not
		supported by libvirt 0.12)

		:return: True if successful, otherwise False
		"""
        # ZFS mounts not supported by our libvirt version so always mount
        # check if already mounted
        if self.mountpoint is not None:
            return True

        out, rc = cziso.run_command(
            "rocks add host storagemap %s %s %s %s 10 img_sync=false" %
            (self.nas, self.pool, self.vol, self.hostname))
        if rc != 0:
            self.logger.error("Unable to mount zvol to %s" % self.hostname)
            return False
        self.mountpoint = out[1]
        self.logger.info("Mounted zvol %s to %s" % (self.vol, self.mountpoint))
        return True