Example #1
0
    def run(self):
        if self.dialog is None:
            return None

        while 1:
            rc = self.dialog.exec_()

            if not rc:
                if self.isNew:
                    if self.parent.parent.lvs.has_key(self.origrequest.lvname):
                        del self.parent.parent.lvs[self.origrequest.lvname]
                self.destroy()
                return None

            format = None
            widget = self.dialog.content

            format = self.origrequest.format

            mountpoint = unicode(widget.mountpointMenu.currentText())
            if mountpoint and widget.mountpointMenu.isEditable():
                msg = sanityCheckMountPoint(mountpoint)
                if msg:
                    self.intf.messageWindow(_("Mount Point Error"), msg,
                                            type="error")
                    continue

            if not self.origrequest.exists:
                format_type = str(widget.filesystemMenu.currentText())
            else:
                format_type = str(widget.formatCombo.currentText())

            format_class = formats.getFormat(format_type)
            if mountpoint and format_class.mountable:
                used = False

                current_mountpoint = getattr(format, "mountpoint", None)

                for lv in self.parent.parent.lvs.values():
                    format = lv["format"]
                    if not format.mountable or current_mountpoint and \
                        format.mountpoint == current_mountpoint:
                        continue

                    if format.mountpoint == mountpoint:
                        used = True
                        break

                for (mp, dev) in self.parent.parent.storage.mountpoints.iteritems():
                    if (dev.type != "lvmlv" or dev.vg.id != self.origrequest.vg.id) and mp == mountpoint:
                        used = True
                        break

                if used:
                    self.intf.messageWindow(_("Mount point in use"),
                                            _("The mount point \"%s\" is in "
                                              "use. Please pick another.") %
                                            (mountpoint,),
                                            type="warning")
                    continue


            name = str(widget.name.text())
            if not self.origrequest.exists:
                msg = sanityCheckLogicalVolumeName(name)
                if msg:
                    self.intf.messageWindow(_("Illegal Logical Volume Name"),
                                            msg, type="warning")
                    continue

            # check that the name is not already in use
            used = 0
            for lv in self.parent.parent.lvs.values():
                if self.origrequest.lvname != name and lv['name'] == name:
                    used = 1
                    break

            if used:
                self.intf.messageWindow(_("Illegal logical volume name"),
                                        _("The logical volume name \"%s\" is "
                                          "already in use. Please pick another.")
                                        % (name,), type="warning")
                continue


            if not self.origrequest.exists:
                badsize = 0
                try:
                    size = long(widget.sizeSpin.value())
                except:
                    size = 1

                if badsize or size <= 0:
                    self.intf.messageWindow(_("Illegal size"),
                                            _("The requested size as entered is "
                                              "not a valid number greater than 0."),
                                            type="warning")
                    continue
            else:
                size = self.origrequest.size

            # check that size specification is within limits
            peSize = int(self.parent.physicalExtends.itemData(self.parent.physicalExtends.currentIndex())) / 1024
            size = lvm.clampSize(size, peSize, roundup=True)
            maximumVolumeSize = lvm.getMaxLVSize()
            if size > maximumVolumeSize:
                self.intf.messageWindow(_("Not enough space"),
                                        _("The current requested size "
                                          "(%(size)10.2f MB) is larger than "
                                          "the maximum logical volume size "
                                          "(%(maxlv)10.2f MB). "
                                          "To increase this limit you can "
                                          "create more Physical Volumes from "
                                          "unpartitioned disk space and "
                                          "add them to this Volume Group.")
                                          % {'size': size, 'maxlv': maximumVolumeSize},
                                        type="warning")
                continue

            # Get format
            origname = self.origrequest.lvname
            if not self.origrequest.exists:
                formatType = str(widget.filesystemMenu.currentText())
                format = formats.getFormat(formatType, mountpoint=mountpoint)
                self.origrequest._name = name
                try:
                    self.origrequest.size = size
                except ValueError, msg:
                    self.intf.messageWindow(_("Not enough space"),
                                            _("The size entered for this "
                                              "logical volume (%(size)d MB) "
                                              "combined with the size of the "
                                              "other logical volume(s) "
                                              "exceeds the size of the "
                                              "volume group (%(tmpvgsize)d "
                                              "MB). Please make the volume "
                                              "group larger or make the "
                                              "logical volume smaller.")
                                              % {'size': size, 'tmpvgsize': self.origrequest.vg.size},
                                            type="warning")
                    continue
                else:
                    self.origrequest.format = format
            else:
                if widget.formatRadio.isChecked():
                    formatType = str(widget.formatCombo.currentText())
                    format = formats.getFormat(formatType, mountpoint=mountpoint, device=self.origrequest.path)
                    self.origrequest.format = format
                else:
                    self.origrequest.format = self.origrequest.originalFormat

                if widget.migrateRadio.isChecked():
                    self.origrequest.format.migrate = True

                if widget.resizeRadio.isChecked():
                    self.origrequest.targetSize = widget.resizeSpin.value()

                if self.origrequest.format.mountable:
                    self.origrequest.format.mountpoint = mountpoint

                if self.origrequest.format.exists and \
                    self.origrequest.format.mountable and \
                    self.origrequest.format.mountpoint:
                    if self.storage.formatByDefault(self.origrequest) and \
                       not queryNoFormatPreExisting(self.intf):
                        continue

            # everything ok
            break
Example #2
0
    def __init__(self, parent, request, isNew=0):
        QWidget.__init__(self, parent.parent)
        self.setupUi(self)
        self.parent = parent
        self.origrequest = request
        self.isNew = isNew

        if not self.origrequest.exists:
            if self.origrequest.name:
                self.name.setText(self.origrequest.lvname)
            else:
                self.name.setText(self.parent.storage.createSuggestedVolumeGroupName(self.origrequest.vg))
        else:
            self.name.setText(self.origrequest.lvname)

        storageGuiHelpers.fillMountpointMenu(self.mountpointMenu, self.origrequest, excludes=["/boot"])
        self.mountpointMenu.currentIndexChanged[int].connect(self.mountPointChanged)

        # This empty radioButton is hack about enabling autoExclusive formatRadio according to mountpoint.(#16446)
        self.radioButton.hide()

        # Partition Type
        if not self.origrequest.exists:
            storageGuiHelpers.fillFilesystemMenu(self.filesystemMenu, self.origrequest.format,
                                                 ignores=["mdmember", "efi", "lvmpv"])
            self.filesystemMenu.currentIndexChanged[int].connect(self.formatTypeChanged)
            default_format = self.filesystemMenu.findText("ext4")
            self.filesystemMenu.setCurrentIndex(default_format)
            self.resizeRadio.hide()
            self.resizeSlider.hide()
            self.resizeSpin.hide()
            self.formatRadio.hide()
            self.formatCombo.hide()
            self.migrateRadio.hide()
            self.migrateCombo.hide()
        else:
            self.filesystemLabel.hide()
            self.filesystemMenu.hide()
            if self.origrequest.format.formattable or not self.origrequest.format.type:
                storageGuiHelpers.fillFilesystemMenu(self.formatCombo, self.origrequest.format,
                                                     ignores= ["mdmember", "lvmpv", "vfat"])
                self.formatRadio.setChecked(self.origrequest.format.formattable and not self.origrequest.format.exists)
                self.formatRadio.toggled[bool].connect(self.formatRadioToggled)
                self.formatCombo.currentIndexChanged[int].connect(self.formatTypeChanged)
            else:
                self.formatRadio.hide()
                self.formatCombo.hide()

            if self.origrequest.format.migratable and self.origrequest.format.exists:
                storageGuiHelpers.fillFilesystemMenu(self.migrateCombo, self.origrequest.format,
                                                     availables=[self.origrequest.format.migrationTarget])
                self.migrateRadio.setChecked(self.origrequest.format.migrate and not self.formatRadio.isChecked())
                self.migrateCombo.currentIndexChanged[int].connect(self.formatTypeChanged)
            else:
                self.migrateRadio.hide()
                self.migrateCombo.hide()

            if self.origrequest.resizable and self.origrequest.format.exists:
                if self.origrequest.targetSize is not None:
                    value = self.origrequest.targetSize
                else:
                    value = self.origrequest.size

                reqlower = 1
                requpper = self.origrequest.maxSize
                if self.origrequest.format.exists:
                    reqlower = self.origrequest.minSize

                    if self.origrequest.type == "partition":
                        geomsize = self.origrequest.partedPartition.geometry.getSize(unit="MB")
                        if (geomsize != 0) and (requpper > geomsize):
                            requpper = geomsize

                self.resizeSpin.setMinimum(reqlower)
                self.resizeSpin.setMaximum(requpper)
                self.resizeSpin.setValue(value)
                self.resizeSlider.setMinimum(reqlower)
                self.resizeSlider.setMaximum(requpper)
                self.resizeSlider.setValue(value)
            else:
                self.resizeRadio.hide()
                self.resizeSpin.hide()
                self.resizeSlider.hide()

        #Size and maximum size
        if not self.origrequest.exists:
             maximumGrow = self.origrequest.vg.freeSpace / self.origrequest.stripes
             self.sizeSpin.setMaximum(min(lvm.getMaxLVSize(), self.origrequest.size + maximumGrow))
             self.sizeSpin.setValue(self.origrequest.size)
             self.sizeSlider.setMaximum(min(lvm.getMaxLVSize(), self.origrequest.size + maximumGrow))
             self.sizeSlider.setValue(self.origrequest.size)
        else:
            self.sizeLabel.hide()
            self.sizeSlider.hide()
            self.sizeSpin.hide()


        self.buttonBox.accepted.connect(self.parent.dialog.accept)
        self.buttonBox.rejected.connect(self.parent.dialog.reject)
Example #3
0
    def physicalExtendsChanged(self, index):
        """ handle changes in the Physical Extent Option Menu """

        def getPhysicalVolumeWastedRatio(physicalextend):
            """ Given a new physicalExtend value, return percentage of smallest 
                Physical Volume wasted

                new - (int) new value of PE, in KB
            """
            pvs = self.selectedPhysicalVolumes

            waste = 0.0
            for pv in pvs:
                waste = max(waste, (long(pv.size*1024) % physicalextend)/(pv.size*1024.0))

            return waste

        def computeVolumeGroupSize(pvs, curpe):
            availSpace = 0L
            for pv in pvs:
                # have to clamp pvsize to multiple of PE
                # XXX why the suboperation? fudging metadata?
                size = lvm.clampSize(pv.size, curpe) - (curpe/1024)

                availSpace = availSpace + size

            ctx.logger.info("computeVolumeGroupSize: size is %s" % (availSpace,))
            return availSpace

        def reclampLogicalVolume(physicalextend):
            """ given a new physical extend value, set logical volume sizes accordingly

                physicalextend - (int) new value of Physical Extend, in MB
            """

            pvs = self.selectedPhysicalVolumes
            availableSpace = computeVolumeGroupSize(pvs, physicalextend)

            # see if total space is enough
            used = 0
            resize = False
            for lv in self.parent.lvs.values():
                # total space required by an lv may be greater than lv size.
                vgSpace = lv['size'] * lv['stripes'] + lv['logSize'] + lv['snapshotSpace']
                clampedVGSpace = lvm.clampSize(vgSpace, physicalextend, roundup=1)
                used += clampedVGSpace
                if lv['size'] != lvm.clampSize(lv['size'], physicalextend, roundup=1):
                    resize = True

            if used > availableSpace:
                self.parent.intf.messageWindow(_("Not enough space"),
                                               _("The physical extent size cannot be changed because\n"
                                                 "otherwise the space required by the currently defined\n"
                                                 "logical volumes will be increased to more than the\n"
                                                 "available space."),
                                               type="warning")
                return  0

            if resize:
                rc = self.parent.intf.messageWindow(_("Confirm Physical Extent Change"),
                                                   _("This change in the value of the physical extent will\n"
                                                     "require the sizes of the current logical volume requests\n"
                                                     "to be rounded up in size to an integer multiple of\n"
                                                     "the physical extent.\n\nThis change will take effect\n"
                                                     "immediately."),
                                                   type="custom", customIcon="question",
                                                   customButtons=[_("Cancel"), _("Continue")])
                if not rc:
                    return 0

            for lv in self.parent.lvs.values():
                lv['size'] = lvm.clampSize(lv['size'], physicalextend, roundup=1)

            return 1

        curpe = float(self.physicalExtends.itemData(index)) / 1024.0
        currentValue = curpe
        lastValue = self.origrequest.peSize
        maximumPhysicalSize = self.smallestPhysicalVolumeSize
        if curpe > maximumPhysicalSize:
            self.parent.intf.messageWindow(_("Not enough space"),
                                           _("The physical extent size cannot be "
                                             "changed because\nthe value selected "
                                             "(%(curpe)10.2f MB) is larger than the\n"
                                             "smallest physical volume "
                                             "(%(maxpvsize)10.2f MB) in the volume "
                                             "group.") %
                                           {'curpe': curpe, 'maxpvsize': maximumPhysicalSize},
                                           type="warning")
            return 0

        # see if new PE will make any PV useless due to overhead
        if lvm.clampSize(maximumPhysicalSize, curpe) < curpe:
            self.parent.intf.messageWindow(_("Not enough space"),
                                           _("The physical extent size cannot be "
                                             "changed because the value selected "
                                             "(%(curpe)10.2f MB) is too large "
                                             "compared to the size of the "
                                             "smallest physical volume "
                                             "(%(maxpvsize)10.2f MB) in the "
                                             "volume group.")
                                           % {'curpe': curpe, 'maxpvsize': maximumPhysicalSize},
                                           type="warning")
            return 0

        if getPhysicalVolumeWastedRatio(curpe) > 0.10:
            rc = self.parent.intf.messageWindow(_("Too small"),
                                                _("This change in the value of the "
                                                  "physical extent will waste "
                                                  "substantial space on one or more "
                                                  "of the physical volumes in the "
                                                  "volume group."),
                                                 type="custom", customIcon="warning",
                                                 customButtons=[_("Cancel"), _("Continue")])
            if not rc:
                return 0

        # now see if we need to fixup effect PV and LV sizes based on PE
        if currentValue > lastValue:
            rc = reclampLogicalVolume(curpe)
            if not rc:
                return 0
            else:
                self.updateLogicalVolumeTree()
        else:
            maxlv = lvm.getMaxLVSize()
            for lv in self.parent.lvs.values():
                if lv['size'] > maxlv:
                    self.parent.intf.messageWindow(_("Not enough space"),
                                                   _("The physical extent size "
                                                     "cannot be changed because the "
                                                     "resulting maximum logical "
                                                     "volume size (%10.2f MB) is "
                                                     "smaller than one or more of their "
                                                     "currently defined logical "
                                                     "volumes.") % (maxlv,),
                                                   type="warning")
                    return 0

        # now actually set the VG's extent size
        self.peSize = curpe
        self.updateAllowedPhysicals()
        self.updateSpaces()
Example #4
0
    def __init__(self, parent, request, isNew=0):
        QWidget.__init__(self, parent.parent)
        self.setupUi(self)
        self.parent = parent
        self.origrequest = request
        self.isNew = isNew

        if not self.origrequest.exists:
            if self.origrequest.name:
                self.name.setText(self.origrequest.lvname)
            else:
                self.name.setText(self.parent.storage.createSuggestedVolumeGroupName(self.origrequest.vg))
        else:
            self.name.setText(self.origrequest.lvname)

        storageGuiHelpers.fillMountpointMenu(self.mountpointMenu, self.origrequest, excludes=["/boot"])
        QObject.connect(self.mountpointMenu, SIGNAL("currentIndexChanged(int)"), self.mountPointChanged)

        # This empty radioButton is hack about enabling autoExclusive formatRadio according to mountpoint.(#16446)
        self.radioButton.hide()

        # Partition Type
        if not self.origrequest.exists:
            storageGuiHelpers.fillFilesystemMenu(self.filesystemMenu, self.origrequest.format,
                                                 ignores=["mdmember", "efi", "lvmpv"])
            QObject.connect(self.filesystemMenu, SIGNAL("currentIndexChanged(int)"), self.formatTypeChanged)
            default_format = self.filesystemMenu.findText("ext4")
            self.filesystemMenu.setCurrentIndex(default_format)
            self.resizeRadio.hide()
            self.resizeSlider.hide()
            self.resizeSpin.hide()
            self.formatRadio.hide()
            self.formatCombo.hide()
            self.migrateRadio.hide()
            self.migrateCombo.hide()
        else:
            self.filesystemLabel.hide()
            self.filesystemMenu.hide()
            if self.origrequest.format.formattable or not self.origrequest.format.type:
                storageGuiHelpers.fillFilesystemMenu(self.formatCombo, self.origrequest.format,
                                                     ignores= ["mdmember", "lvmpv", "vfat"])
                self.formatRadio.setChecked(self.origrequest.format.formattable and not self.origrequest.format.exists)
                QObject.connect(self.formatRadio, SIGNAL("toggled(bool)"), self.formatRadioToggled)
                QObject.connect(self.formatCombo, SIGNAL("currentIndexChanged(int)"), self.formatTypeChanged)
            else:
                self.formatRadio.hide()
                self.formatCombo.hide()

            if self.origrequest.format.migratable and self.origrequest.format.exists:
                storageGuiHelpers.fillFilesystemMenu(self.migrateCombo, self.origrequest.format,
                                                     availables=[self.origrequest.format.migrationTarget])
                self.migrateRadio.setChecked(self.origrequest.format.migrate and not self.formatRadio.isChecked())
                QObject.connect(self.migrateCombo, SIGNAL("currentIndexChanged(int)"), self.formatTypeChanged)
            else:
                self.migrateRadio.hide()
                self.migrateCombo.hide()

            if self.origrequest.resizable and self.origrequest.format.exists:
                if self.origrequest.targetSize is not None:
                    value = self.origrequest.targetSize
                else:
                    value = self.origrequest.size

                reqlower = 1
                requpper = self.origrequest.maxSize
                if self.origrequest.format.exists:
                    reqlower = self.origrequest.minSize

                    if self.origrequest.type == "partition":
                        geomsize = self.origrequest.partedPartition.geometry.getSize(unit="MB")
                        if (geomsize != 0) and (requpper > geomsize):
                            requpper = geomsize

                self.resizeSpin.setMinimum(reqlower)
                self.resizeSpin.setMaximum(requpper)
                self.resizeSpin.setValue(value)
                self.resizeSlider.setMinimum(reqlower)
                self.resizeSlider.setMaximum(requpper)
                self.resizeSlider.setValue(value)
            else:
                self.resizeRadio.hide()
                self.resizeSpin.hide()
                self.resizeSlider.hide()

        #Size and maximum size
        if not self.origrequest.exists:
             maximumGrow = self.origrequest.vg.freeSpace / self.origrequest.stripes
             self.sizeSpin.setMaximum(min(lvm.getMaxLVSize(), self.origrequest.size + maximumGrow))
             self.sizeSpin.setValue(self.origrequest.size)
             self.sizeSlider.setMaximum(min(lvm.getMaxLVSize(), self.origrequest.size + maximumGrow))
             self.sizeSlider.setValue(self.origrequest.size)
        else:
            self.sizeLabel.hide()
            self.sizeSlider.hide()
            self.sizeSpin.hide()


        self.connect(self.buttonBox, SIGNAL("accepted()"), self.parent.dialog.accept)
        self.connect(self.buttonBox, SIGNAL("rejected()"), self.parent.dialog.reject)
Example #5
0
    def run(self):
        if self.dialog is None:
            return None

        while 1:
            rc = self.dialog.exec_()

            if not rc:
                if self.isNew:
                    if self.parent.parent.lvs.has_key(self.origrequest.lvname):
                        del self.parent.parent.lvs[self.origrequest.lvname]
                self.destroy()
                return None

            format = None
            widget = self.dialog.content

            format = self.origrequest.format

            mountpoint = unicode(widget.mountpointMenu.currentText())
            if mountpoint and widget.mountpointMenu.isEditable():
                msg = sanityCheckMountPoint(mountpoint)
                if msg:
                    self.intf.messageWindow(_("Mount Point Error"), msg,
                                            type="error")
                    continue

            if not self.origrequest.exists:
                format_type = str(widget.filesystemMenu.currentText())
            else:
                format_type = str(widget.formatCombo.currentText())

            format_class = formats.getFormat(format_type)
            if mountpoint and format_class.mountable:
                used = False

                current_mountpoint = getattr(format, "mountpoint", None)

                for lv in self.parent.parent.lvs.values():
                    format = lv["format"]
                    if not format.mountable or current_mountpoint and \
                        format.mountpoint == current_mountpoint:
                        continue

                    if format.mountpoint == mountpoint:
                        used = True
                        break

                for (mp, dev) in self.parent.parent.storage.mountpoints.iteritems():
                    if (dev.type != "lvmlv" or dev.vg.id != self.origrequest.vg.id) and mp == mountpoint:
                        used = True
                        break

                if used:
                    self.intf.messageWindow(_("Mount point in use"),
                                            _("The mount point \"%s\" is in "
                                              "use. Please pick another.") %
                                            (mountpoint,),
                                            type="warning")
                    continue


            name = str(widget.name.text())
            if not self.origrequest.exists:
                msg = sanityCheckLogicalVolumeName(name)
                if msg:
                    self.intf.messageWindow(_("Illegal Logical Volume Name"),
                                            msg, type="warning")
                    continue

            # check that the name is not already in use
            used = 0
            for lv in self.parent.parent.lvs.values():
                if self.origrequest.lvname != name and lv['name'] == name:
                    used = 1
                    break

            if used:
                self.intf.messageWindow(_("Illegal logical volume name"),
                                        _("The logical volume name \"%s\" is "
                                          "already in use. Please pick another.")
                                        % (name,), type="warning")
                continue


            if not self.origrequest.exists:
                badsize = 0
                try:
                    size = long(widget.sizeSpin.value())
                except:
                    size = 1

                if badsize or size <= 0:
                    self.intf.messageWindow(_("Illegal size"),
                                            _("The requested size as entered is "
                                              "not a valid number greater than 0."),
                                            type="warning")
                    continue
            else:
                size = self.origrequest.size

            # check that size specification is within limits
            peSize = self.parent.physicalExtends.itemData(self.parent.physicalExtends.currentIndex()).toInt()[0] / 1024
            size = lvm.clampSize(size, peSize, roundup=True)
            maximumVolumeSize = lvm.getMaxLVSize()
            if size > maximumVolumeSize:
                self.intf.messageWindow(_("Not enough space"),
                                        _("The current requested size "
                                          "(%(size)10.2f MB) is larger than "
                                          "the maximum logical volume size "
                                          "(%(maxlv)10.2f MB). "
                                          "To increase this limit you can "
                                          "create more Physical Volumes from "
                                          "unpartitioned disk space and "
                                          "add them to this Volume Group.")
                                          % {'size': size, 'maxlv': maximumVolumeSize},
                                        type="warning")
                continue

            # Get format
            origname = self.origrequest.lvname
            if not self.origrequest.exists:
                formatType = str(widget.filesystemMenu.currentText())
                format = formats.getFormat(formatType, mountpoint=mountpoint)
                self.origrequest._name = name
                try:
                    self.origrequest.size = size
                except ValueError, msg:
                    self.intf.messageWindow(_("Not enough space"),
                                            _("The size entered for this "
                                              "logical volume (%(size)d MB) "
                                              "combined with the size of the "
                                              "other logical volume(s) "
                                              "exceeds the size of the "
                                              "volume group (%(tmpvgsize)d "
                                              "MB). Please make the volume "
                                              "group larger or make the "
                                              "logical volume smaller.")
                                              % {'size': size, 'tmpvgsize': self.origrequest.vg.size},
                                            type="warning")
                    continue
                else:
                    self.origrequest.format = format
            else:
                if widget.formatRadio.isChecked():
                    formatType = str(widget.formatCombo.currentText())
                    format = formats.getFormat(formatType, mountpoint=mountpoint, device=self.origrequest.path)
                    self.origrequest.format = format
                else:
                    self.origrequest.format = self.origrequest.originalFormat

                if widget.migrateRadio.isChecked():
                    self.origrequest.format.migrate = True

                if widget.resizeRadio.isChecked():
                    self.origrequest.targetSize = widget.resizeSpin.value()

                if self.origrequest.format.mountable:
                    self.origrequest.format.mountpoint = mountpoint

                if self.origrequest.format.exists and \
                    self.origrequest.format.mountable and \
                    self.origrequest.format.mountpoint:
                    if self.storage.formatByDefault(self.origrequest) and \
                       not queryNoFormatPreExisting(self.intf):
                        continue

            # everything ok
            break
Example #6
0
    def physicalExtendsChanged(self, index):
        """ handle changes in the Physical Extent Option Menu """

        def getPhysicalVolumeWastedRatio(physicalextend):
            """ Given a new physicalExtend value, return percentage of smallest 
                Physical Volume wasted

                new - (int) new value of PE, in KB
            """
            pvs = self.selectedPhysicalVolumes

            waste = 0.0
            for pv in pvs:
                waste = max(waste, (long(pv.size*1024) % physicalextend)/(pv.size*1024.0))

            return waste

        def computeVolumeGroupSize(pvs, curpe):
            availSpace = 0L
            for pv in pvs:
                # have to clamp pvsize to multiple of PE
                # XXX why the suboperation? fudging metadata?
                size = lvm.clampSize(pv.size, curpe) - (curpe/1024)

                availSpace = availSpace + size

            ctx.logger.info("computeVolumeGroupSize: size is %s" % (availSpace,))
            return availSpace

        def reclampLogicalVolume(physicalextend):
            """ given a new physical extend value, set logical volume sizes accordingly

                physicalextend - (int) new value of Physical Extend, in MB
            """

            pvs = self.selectedPhysicalVolumes
            availableSpace = computeVolumeGroupSize(pvs, physicalextend)

            # see if total space is enough
            used = 0
            resize = False
            for lv in self.parent.lvs.values():
                # total space required by an lv may be greater than lv size.
                vgSpace = lv['size'] * lv['stripes'] + lv['logSize'] + lv['snapshotSpace']
                clampedVGSpace = lvm.clampSize(vgSpace, physicalextend, roundup=1)
                used += clampedVGSpace
                if lv['size'] != lvm.clampSize(lv['size'], physicalextend, roundup=1):
                    resize = True

            if used > availableSpace:
                self.parent.intf.messageWindow(_("Not enough space"),
                                               _("The physical extent size cannot be changed because\n"
                                                 "otherwise the space required by the currently defined\n"
                                                 "logical volumes will be increased to more than the\n"
                                                 "available space."),
                                               type="warning")
                return  0

            if resize:
                rc = self.parent.intf.messageWindow(_("Confirm Physical Extent Change"),
                                                   _("This change in the value of the physical extent will\n"
                                                     "require the sizes of the current logical volume requests\n"
                                                     "to be rounded up in size to an integer multiple of\n"
                                                     "the physical extent.\n\nThis change will take effect\n"
                                                     "immediately."),
                                                   type="custom", customIcon="question",
                                                   customButtons=[_("Cancel"), _("Continue")])
                if not rc:
                    return 0

            for lv in self.parent.lvs.values():
                lv['size'] = lvm.clampSize(lv['size'], physicalextend, roundup=1)

            return 1

        curpe = self.physicalExtends.itemData(index).toFloat()[0] / 1024.0
        currentValue = curpe
        lastValue = self.origrequest.peSize
        maximumPhysicalSize = self.smallestPhysicalVolumeSize
        if curpe > maximumPhysicalSize:
            self.parent.intf.messageWindow(_("Not enough space"),
                                           _("The physical extent size cannot be "
                                             "changed because\nthe value selected "
                                             "(%(curpe)10.2f MB) is larger than the\n"
                                             "smallest physical volume "
                                             "(%(maxpvsize)10.2f MB) in the volume "
                                             "group.") %
                                           {'curpe': curpe, 'maxpvsize': maximumPhysicalSize},
                                           type="warning")
            return 0

        # see if new PE will make any PV useless due to overhead
        if lvm.clampSize(maximumPhysicalSize, curpe) < curpe:
            self.parent.intf.messageWindow(_("Not enough space"),
                                           _("The physical extent size cannot be "
                                             "changed because the value selected "
                                             "(%(curpe)10.2f MB) is too large "
                                             "compared to the size of the "
                                             "smallest physical volume "
                                             "(%(maxpvsize)10.2f MB) in the "
                                             "volume group.")
                                           % {'curpe': curpe, 'maxpvsize': maximumPhysicalSize},
                                           type="warning")
            return 0

        if getPhysicalVolumeWastedRatio(curpe) > 0.10:
            rc = self.parent.intf.messageWindow(_("Too small"),
                                                _("This change in the value of the "
                                                  "physical extent will waste "
                                                  "substantial space on one or more "
                                                  "of the physical volumes in the "
                                                  "volume group."),
                                                 type="custom", customIcon="warning",
                                                 customButtons=[_("Cancel"), _("Continue")])
            if not rc:
                return 0

        # now see if we need to fixup effect PV and LV sizes based on PE
        if currentValue > lastValue:
            rc = reclampLogicalVolume(curpe)
            if not rc:
                return 0
            else:
                self.updateLogicalVolumeTree()
        else:
            maxlv = lvm.getMaxLVSize()
            for lv in self.parent.lvs.values():
                if lv['size'] > maxlv:
                    self.parent.intf.messageWindow(_("Not enough space"),
                                                   _("The physical extent size "
                                                     "cannot be changed because the "
                                                     "resulting maximum logical "
                                                     "volume size (%10.2f MB) is "
                                                     "smaller than one or more of their "
                                                     "currently defined logical "
                                                     "volumes.") % (maxlv,),
                                                   type="warning")
                    return 0

        # now actually set the VG's extent size
        self.peSize = curpe
        self.updateAllowedPhysicals()
        self.updateSpaces()
Example #7
0
    def __init__(self, parent, request, isNew=0):
        QtGui.QWidget.__init__(self, parent.parent)
        self.setupUi(self)
        self.parent = parent
        self.origrequest = request
        self.isNew = isNew

        if not self.origrequest.exists:
            if self.origrequest.name:
                self.name.setText(self.origrequest.lvname)
            else:
                self.name.setText(self.parent.storage.createSuggestedVolumeGroupName(self.origrequest.vg))
        else:
            self.name.setText(self.origrequest.lvname)
        storageGuiHelpers.fillMountpointMenu(self.mountpointMenu, self.origrequest, excludes=["/boot"])

        # Partition Type
        if not self.origrequest.exists:
            storageGuiHelpers.fillFilesystemMenu(self.filesystemMenu, self.origrequest.format,
                                                 ignores=["mdmember", "efi", "lvmpv"])
            QObject.connect(self.filesystemMenu, SIGNAL("currentIndexChanged(int)"), self.formatTypeChanged)
            self.resizeRadio.hide()
            self.resizeSlider.hide()
            self.resizeSpin.hide()
            self.formatRadio.hide()
            self.formatCombo.hide()
            self.migrateRadio.hide()
            self.migrateCombo.hide()
        else:
            self.filesystemLabel.hide()
            self.filesystemMenu.hide()
            if self.origrequest.format.formattable or not self.origrequest.format.type:
                storageGuiHelpers.fillFilesystemMenu(self.formatCombo, self.origrequest.format,
                                                     ignores= ["software RAID", "physical volume (LVM)","vfat"])
                self.formatRadio.setChecked(self.origrequest.format.formattable and not self.origrequest.format.exists)
                QObject.connect(self.formatCombo, SIGNAL("currentIndexChanged(int)"), self.formatTypeChanged)
            else:
                self.formatRadio.hide()
                self.formatCombo.hide()

            if self.origrequest.format.migratable and self.origrequest.format.exists:
                storageGuiHelpers.fillFilesystemMenu(self.migrateCombo, self.origrequest.format,
                                                     availables=[self.origrequest.format.migrationTarget])
                self.migrateRadio.setChecked(self.origrequest.format.migrate and not self.formatRadio.isChecked())
                QObject.connect(self.migrateCombo, SIGNAL("currentIndexChanged(int)"), self.formatTypeChanged)
            else:
                self.migrateRadio.hide()
                self.migrateCombo.hide()

            if self.origrequest.resizable and self.origrequest.format.exists:
                if self.origrequest.targetSize is not None:
                    value = self.origrequest.targetSize
                else:
                    value = self.origrequest.size

                reqlower = 1
                requpper = self.origrequest.maxSize
                if self.origrequest.format.exists:
                    reqlower = self.origrequest.minSize

                    if self.origrequest.type == "partition":
                        geomsize = self.origrequest.partedPartition.geometry.getSize(unit="MB")
                        if (geomsize != 0) and (requpper > geomsize):
                            requpper = geomsize

                self.resizeSpin.setMinimum(reqlower)
                self.resizeSpin.setMaximum(requpper)
                self.resizeSpin.setValue(value)
                self.resizeSlider.setMinimum(reqlower)
                self.resizeSlider.setMaximum(requpper)
                self.resizeSlider.setValue(value)
            else:
                self.resizeRadio.hide()
                self.resizeSpin.hide()
                self.resizeSlider.hide()

        #Size and maximum size
        if not self.origrequest.exists:
             maximumGrow = self.origrequest.vg.freeSpace / self.origrequest.stripes
             self.sizeSpin.setMaximum(min(lvm.getMaxLVSize(), self.origrequest.size + maximumGrow))
             self.sizeSpin.setValue(self.origrequest.size)
             self.sizeSlider.setMaximum(min(lvm.getMaxLVSize(), self.origrequest.size + maximumGrow))
             self.sizeSlider.setValue(self.origrequest.size)
        else:
            self.sizeLabel.hide()
            self.sizeSlider.hide()
            self.sizeSpin.hide()


        self.connect(self.buttonBox, SIGNAL("accepted()"), self.parent.dialog.accept)
        self.connect(self.buttonBox, SIGNAL("rejected()"), self.parent.dialog.reject)