예제 #1
0
    def _get_min_size_limit(self):
        limit = size.Size(0)

        if self.selected_fs:
            limit = self.selected_fs._min_size

        return limit or size.Size("1 MiB")
예제 #2
0
    def get_selection(self):

        if self.device_type in ("lvm", "lvmvg"):
            return {"pesize": size.Size(self.pesize_combo.get_active_text())}

        elif self.device_type == "partition":
            return {"parttype": self.partition_combo.get_active_id()}

        elif self.device_type == "mdraid":
            return {"chunk_size": size.Size(self.chunk_combo.get_active_text())}
예제 #3
0
    def _get_min_size_limit(self):
        limit = size.Size(0)

        if self.selected_fs:
            limit = self.selected_fs._min_size

        parent_limit = self._get_parent_min_size()
        limit = max(limit, parent_limit)

        return limit or size.Size("1 MiB")
예제 #4
0
 def default_unit(self):
     """ Default, preselected unit -- GiB for devices larger that 5 GiB,
         otherwise the biggest available unit
     """
     dev_size = self.max_size - self.min_size
     if dev_size >= size.Size("5 GiB"):
         return size.GiB
     elif dev_size >= size.Size("5 MiB"):
         return size.MiB
     else:
         return self.available_units[-1]
예제 #5
0
    def add_device_chooser(self):

        map_type_devices = {
            "disk" : [(_("Partition"), "partition"), (_("LVM2 Storage"), "lvm"),
            (_("LVM2 Physical Volume"), "lvmpv")],
            "lvmpv" : [(_("LVM2 Volume Group"), "lvmvg")],
            "lvmvg" : [(_("LVM2 Logical Volume"), "lvmlv")],
            "luks/dm-crypt" : [(_("LVM2 Volume Group"), "lvmvg")],
            "mdarray" : [(_("LVM2 Volume Group"), "lvmvg")],
            "btrfs volume" : [(_("Btrfs Subvolume"), "btrfs subvolume")]
            }

        label_devices = Gtk.Label(label=_("Device type:"), xalign=1)
        label_devices.get_style_context().add_class("dim-label")
        self.grid.attach(label_devices, 0, 0, 1, 1)

        if self.device_type == "disk" and self.free_device.isLogical:
            devices = [(_("Partition"), "partition"), (_("LVM2 Storage"), "lvm"),
                       (_("LVM2 Physical Volume"), "lvmpv")]

        elif self.device_type == "disk" and not self.parent_device.format.type \
            and self.free_device.size > size.Size("256 MiB"):
            devices = [(_("Btrfs Volume"), "btrfs volume")]

        else:
            devices = map_type_devices[self.device_type]

            if self.device_type == "disk" and len(self.free_disks_regions) > 1:
                devices.append((_("Software RAID"), "mdraid"))

            if self.device_type == "disk" and self.free_device.size > size.Size("256 MiB"):
                devices.append((_("Btrfs Volume"), "btrfs volume"))

        devices_store = Gtk.ListStore(str, str)

        for device in devices:
            devices_store.append([device[0], device[1]])

        devices_combo = Gtk.ComboBox.new_with_model(devices_store)
        devices_combo.set_entry_text_column(0)

        if len(devices) == 1:
            devices_combo.set_sensitive(False)

        self.grid.attach(devices_combo, 1, 0, 2, 1)
        renderer_text = Gtk.CellRendererText()
        devices_combo.pack_start(renderer_text, True)
        devices_combo.add_attribute(renderer_text, "text", 0)

        return devices_combo
예제 #6
0
    def _scale_precision(self, unit):
        """ Get number of decimal places to be displayed for selected unit
            and step for the scale.
            We should allow one decimal place for GB and bigger (step 0.1)
            and no decimal values for MiB and smaller (step 1).

            :param unit: selected size unit
            :type unit: size unit constant (e.g. blivet.size.KiB)
        """

        if size.Size("1 " + size.unit_str(unit)) >= size.Size("1 GB"):
            return (1, 0.1)
        else:
            return (0, 1)
예제 #7
0
    def selected(self, status):
        self._selected = status

        # mark the button as (not) selected
        if self.checkbutton_use.get_active() != status:
            self.checkbutton_use.set_active(status)

        if status:
            self.size_chooser.set_sensitive(True)
            self.size_chooser.min_size = self.min_size
            self.selected_size = self.max_size
        else:
            self.size_chooser.set_sensitive(False)
            self.size_chooser.min_size = size.Size(0)
            self.selected_size = size.Size(0)
예제 #8
0
    def validate_user_input(self):
        if self.device_type == "mdraid":
            try:
                chunk_size = size.Size(self.chunk_combo.get_active_text())
            except ValueError:
                msg = _("'{0}' is not a valid chunk size specification.").format(self.chunk_combo.get_active_text())
                message_dialogs.ErrorDialog(self.add_dialog, msg,
                                            not self.add_dialog.installer_mode)  # do not show decoration in installer mode
                return False
            if chunk_size % size.Size("4 KiB") != size.Size(0):
                msg = _("Chunk size must be multiple of 4 KiB.")
                message_dialogs.ErrorDialog(self.add_dialog, msg,
                                            not self.add_dialog.installer_mode)  # do not show decoration in installer mode
                return False

        return True
예제 #9
0
    def available_units(self):
        """ Units that should be available to select in this chooser --
            depends on size of the device, e.g. TiB will be available only
            for devices bigger than 2 TiB
        """
        units = []
        dev_size = (self.max_size - self.min_size) or self.max_size

        if dev_size < size.Size("2 B"):
            return [size.B]

        for unit in UNITS.keys():
            if size.Size("2 " + unit) <= dev_size:
                units.append(UNITS[unit])

        return units
예제 #10
0
    def _get_parent_min_size(self):
        """ Get minimal size for parent devices of newly created device.
            This value depends on type of created device.

            - partition: no limit
            - lv, thinpool (including thin): one extent
            - lvm: 2 * lvm.LVM_PE_SIZE
            - btrfs volume: 256 MiB
            - luks: crypto.LUKS_METADATA_SIZE

        """

        device_type = self.selected_type

        if device_type in ("lvmlv", "lvmthinpool"):
            min_size = self.selected_parent.pe_size
        elif device_type == "lvm":
            min_size = lvm.LVM_PE_SIZE * 2
        elif device_type in ("lvmthinlv", "lvm snapshot"):
            min_size = self.selected_parent.vg.pe_size
        elif device_type == "btrfs volume":
            min_size = BTRFS._min_size
        else:
            min_size = size.Size("1 MiB")

        return min_size
예제 #11
0
 def on_encrypt_check(self, _toggle):
     if self.encrypt_check.get_active():
         self.show_widgets(["passphrase"])
         self.update_size_area_limits(reserved_size=crypto.LUKS_METADATA_SIZE)
     else:
         self.hide_widgets(["passphrase"])
         self.update_size_area_limits(reserved_size=size.Size(0))
예제 #12
0
 def on_encrypt_check(self, _toggle):
     if self._encryption_chooser.encrypt:
         self.update_size_area_limits(min_size=self._get_min_size_limit(),
                                      reserved_size=crypto.LUKS_METADATA_SIZE)
     else:
         self.update_size_area_limits(min_size=self._get_min_size_limit(),
                                      reserved_size=size.Size(0))
예제 #13
0
    def _get_parents_allocation(self):
        """ Without advanced area we need to choose how much space to use on
            each parent
        """
        total_size = self.main_chooser.selected_size
        res = []

        unallocated_parents = self.parents[:]
        allocated_size = size.Size(0)
        while allocated_size < total_size:
            smallest_parent = min([p for p in unallocated_parents],
                                  key=lambda x: x.max_size)
            if (smallest_parent.max_size *
                    len(unallocated_parents)) >= (total_size - allocated_size):
                # just put remaining size / number of remaining parents to each parent
                for parent in unallocated_parents:
                    res.append(
                        ParentSelection(
                            parent_device=parent.device,
                            free_space=parent.free_space,
                            selected_size=(total_size - allocated_size) //
                            len(unallocated_parents)))
                    allocated_size += ((total_size - allocated_size) //
                                       len(unallocated_parents))
                    unallocated_parents.remove(parent)
            else:
                # use entire smallest remaining parent
                res.append(
                    ParentSelection(parent_device=smallest_parent.device,
                                    free_space=smallest_parent.free_space,
                                    selected_size=smallest_parent.max_size))
                allocated_size += smallest_parent.max_size
                unallocated_parents.remove(smallest_parent)

        return res
예제 #14
0
    def _on_unit_changed(self, combo):
        """ On-change action for unit combo """

        new_unit = UNITS[combo.get_active_text()]
        old_unit = self.selected_unit
        self.selected_unit = new_unit

        selected_size = size.Size(str(self._scale.get_value()) + " " + size.unit_str(old_unit))

        self._reset_size_widgets(selected_size)

        for handler in self._unit_change_handlers:
            handler.method(self.selected_unit, *handler.args)
예제 #15
0
    def total_size(self):
        """ Total size selected in this area """

        total_size = size.Size(0)

        # for raids, total size must be calculated separately
        if self.raid_type not in (Linear, Single, None):
            total_size = self.raid_type.get_net_array_size(len(self.selected_choosers),
                                                           min([ch.selected_size for ch in self.selected_choosers]))
        else:
            for chooser in self.choosers:
                total_size += chooser.selected_size

        return total_size
예제 #16
0
    def convert_to_size(self, size_num, unit):
        """ Convert floats from scale to Size

            .. note:: Neccesary for floats in form 1e-10

        """

        str_size = str(size_num)

        if "e" in str_size:
            exp = abs(int(str_size.split("e")[-1]))
            dec = len(str_size.split("e")[0].split(".")[-1])
            str_size = format(size, "." + str(exp+dec) + "f")

        return size.Size(str_size + unit)
예제 #17
0
    def _get_parent_max_size(self, parent_device, free_size):
        """ Get maximal size for parent devices of newly created device.
            This value depends on type of created device.
        """

        device_type = self.selected_type

        if device_type in ("partition", "lvm", "btrfs volume", "mdraid"):
            # partition or a device we are going to create partition as a parent
            # --> we need to use disklabel limit
            disklabel_limit = size.Size(parent_device.format.parted_disk.maxPartitionLength * parent_device.format.sector_size)
            max_size = min(disklabel_limit, free_size)
        else:
            max_size = free_size

        return max_size
예제 #18
0
    def _get_parents(self):
        """ Get selected parents for newly created device """

        parents = []

        # for encrypted parents add space for luks metada
        if self.encrypt_check.get_active():
            reserved_size = crypto.LUKS_METADATA_SIZE
        else:
            reserved_size = size.Size(0)

        if self.selected_parent.type == "lvmvg":
            if self.selected_type == "lvmthinpool":
                free = self.selected_free.size * POOL_RESERVED
            else:
                free = self.selected_free.size

            parent = ProxyDataContainer(device=self.selected_parent,
                                        free_space=self.selected_free,
                                        min_size=self._get_parent_min_size(),
                                        max_size=self._get_parent_max_size(
                                            self.selected_parent, free),
                                        reserved_size=reserved_size)
            parents.append(parent)
        else:
            for row in self.parents_store:
                if row[3]:
                    parent = ProxyDataContainer(
                        device=row[0],
                        free_space=row[1],
                        min_size=self._get_parent_min_size(),
                        max_size=self._get_parent_max_size(
                            row[0], row[1].size),
                        reserved_size=reserved_size)
                    parents.append(parent)

        if not parents:  # FIXME
            parent = ProxyDataContainer(device=self.selected_parent,
                                        free_space=self.selected_free,
                                        min_size=self._get_parent_min_size(),
                                        max_size=self._get_parent_max_size(
                                            self.selected_parent,
                                            self.selected_free.size),
                                        reserved_size=reserved_size)
            parents.append(parent)

        return parents
예제 #19
0
    def _get_max_size_limit(self):
        limit = size.Size("16 EiB")

        if self.selected_fs:
            # some filesystems have 0 max size, so use 'our' upper limit for them
            limit = min(self.selected_fs._max_size, limit) or limit

        # XXX: free space for LVs is calculated based on free space on the PVs
        # but newly allocated LVs doesn't decrease this space, so we need some
        # way how to limit maximum size of the new LV
        if self.selected_type == "lvmlv":
            limit = min(self.selected_parent.free_space, limit)
        # same applies to thinpools, but we need to use another hack to limit
        # it's max size and leave some free space in the VG
        elif self.selected_type == "lvmthinpool":
            limit = min(self.selected_parent.free_space * POOL_RESERVED, limit)

        return limit
예제 #20
0
    def lvm_options(self):

        label_pesize = Gtk.Label(label=_("PE Size:"), xalign=1)
        self.grid.attach(label_pesize, 0, 0, 1, 1)

        pesize_combo = Gtk.ComboBoxText()
        pesize_combo.set_entry_text_column(0)
        pesize_combo.set_id_column(0)

        for pesize in SUPPORTED_PESIZE:
            if (2 * size.Size(pesize)) > self.free_device.size:
                # we need at least two free extents in the vg
                break
            pesize_combo.append_text(pesize)

        pesize_combo.connect("changed", self.on_pesize_changed)
        pesize_combo.set_active_id("4 MiB")

        self.grid.attach(pesize_combo, 1, 0, 2, 1)

        self.widgets.extend([label_pesize, pesize_combo])

        return pesize_combo
예제 #21
0
 def selected_size(self):
     return size.Size(
         str(self._scale.get_value()) + " " +
         size.unit_str(self.selected_unit))
예제 #22
0
    def add_size_areas(self):
        device_type = self._get_selected_device_type()

        self.widgets_dict["size"] = []

        if self.size_areas:
            for area in self.size_areas:
                area.destroy()

            self.size_scroll.destroy()
            self.size_grid.destroy()

            self.size_areas = []

        size_scroll = Gtk.ScrolledWindow()
        size_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
        self.grid.attach(size_scroll, 0, 6, 6, 1)
        size_scroll.show()

        size_grid = Gtk.Grid(column_homogeneous=False, row_spacing=10,
            column_spacing=5)

        size_scroll.add(size_grid)
        size_grid.show()

        posititon = 0

        raid, max_size = self.raid_member_max_size()

        min_size = size.Size("1 MiB")
        if device_type in ("lvmpv", "lvm"):
            min_size = size.Size("8 MiB")
        elif device_type == "btrfs volume":
            min_size = size.Size("256 MiB")

        for row in self.parents_store:
            if row[3]:

                if not raid:
                    max_size = row[1].size

                area = SizeChooserArea(dialog=self, parent_device=row[0],
                    free_device=row[1], max_size=max_size, min_size=min_size,
                    dialog_type="add")

                size_grid.attach(area.frame, 0, posititon, 1, 1)

                self.widgets_dict["size"].append(area)
                self.size_areas.append(area)

                posititon += 1

        for area in self.size_areas:
            area.show()

            if device_type in ("lvmvg", "btrfs subvolume"):
                area.set_sensitive(False)

        size_area_height = size_grid.size_request().height
        size_area_width = size_grid.size_request().width
        screen_height = Gdk.Screen.get_default().get_height()
        screen_width = Gdk.Screen.get_default().get_width()
        dialog_height = self.size_request().height

        size_diff = int((screen_height*0.7) - dialog_height)

        if size_diff < 0:
            # dialog is largen than 70 % of screen
            areas_to_display = len(self.size_areas) - (abs(size_diff) / (size_area_height / len(self.size_areas)))

            if areas_to_display < 1:
                size_scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)

            else:
                if size_area_height > screen_width*0.7:
                    size_scroll.set_size_request(screen_width*0.7,
                        int(size_area_height/len(self.size_areas))*areas_to_display)
                    size_scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)

                else:
                    size_scroll.set_size_request(size_area_width,
                        int(size_area_height/len(self.size_areas))*areas_to_display)
                    size_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        else:
            if size_area_width > screen_width*0.7:
                size_scroll.set_size_request(screen_width*0.7, size_area_height)
                size_scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER)

            else:
                size_grid.set_size_request(size_area_width, size_area_height + 20)
                size_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)

        return size_grid, size_scroll
예제 #23
0
    def on_pesize_changed(self, combo):
        pesize = combo.get_active_id()
        min_size = size.Size(pesize) * 2

        self.add_dialog.update_size_area_limits(min_size=min_size)