def _set_size(self):
        self._size = get_size_from_entry(
            self.builder.get_object("addSizeEntry"),
            lower_bound=self.MIN_SIZE_ENTRY,
            units=SIZE_UNITS_DEFAULT)

        if self._size is None or self._size < Size("1 MB"):
            self._size = Size(0)
 def _populate_disks(self):
     for device_name in self._disks:
         device_data = DeviceData.from_structure(
             self._device_tree.GetDeviceData(device_name))
         device_free_space = self._device_tree.GetDiskFreeSpace(
             [device_name])
         self._store.append([
             "{} ({})".format(device_data.description,
                              device_data.attrs.get("serial", "")),
             str(Size(device_data.size)),
             str(Size(device_free_space)), device_name
         ])
    def _set_size(self):
        if self._request.container_size_policy == SIZE_POLICY_AUTO:
            self._sizeCombo.set_active(0)
            self._sizeEntry.set_text("")
        elif self._request.container_size_policy == SIZE_POLICY_MAX:
            self._sizeCombo.set_active(1)
            self._sizeEntry.set_text("")
        else:
            self._sizeCombo.set_active(2)
            size = Size(self._request.container_size_policy)
            self._sizeEntry.set_text(size.human_readable(max_places=2))

        if not self._permissions.container_size_policy:
            fancy_set_sensitive(self._sizeCombo, False)
            self._sizeEntry.set_sensitive(False)
Пример #4
0
 def __init__(self, data, device_tree):
     super().__init__(data)
     self._device_tree = device_tree
     self._size = Size(0)
     self._mount_point = ""
     self._error = ""
     self._warning_label = self.builder.get_object("mountPointWarningLabel")
     self._populate_mount_points()
Пример #5
0
    def _convert_partition_sizes(self, value):
        """Convert the given value into a dictionary of partition sizes."""
        lines = value.split("\n")
        sizes = {}

        for line in lines:
            if line:
                mount_point, size = line.split(maxsplit=1)
                sizes[mount_point] = Size(size)

        return sizes
    def _get_size_policy(self):
        idx = self._sizeCombo.get_active()

        if idx == 0:
            return SIZE_POLICY_AUTO

        if idx == 1:
            return SIZE_POLICY_MAX

        original_size = Size(self._request.container_size_policy)
        original_entry = original_size.human_readable(max_places=2)

        if self._sizeEntry.get_text() == original_entry:
            return self._request.container_size_policy

        size = get_size_from_entry(self._sizeEntry, upper_bound=MAX_SIZE_POLICY_ENTRY)

        if size is None:
            return SIZE_POLICY_MAX

        return size.get_bytes()
    def __init__(self, data, device_tree):
        super().__init__(data)
        self._device_tree = device_tree
        self._size = Size(0)
        self._mount_point = ""
        self._error = ""

        self._warning_label = self.builder.get_object("mountPointWarningLabel")

        self._size_entry = self.builder.get_object("addSizeEntry")
        self._size_entry.set_tooltip_text(DESIRED_CAPACITY_HINT)

        self._populate_mount_points()
class ContainerDialog(GUIObject, GUIDialogInputCheckHandler):
    builderObjects = [
        "container_dialog", "disk_store", "container_disk_view",
        "containerRaidStoreFiltered", "containerRaidLevelLabel",
        "containerRaidLevelCombo", "raidLevelStore", "containerSizeCombo",
        "containerSizeEntry", "containerSizeLabel",
        "containerEncryptedCheckbox", "luksVersionCombo", "luksVersionStore",
        "luksVersionLabel"
    ]
    mainWidgetName = "container_dialog"
    uiFile = "spokes/lib/custom_storage_helpers.glade"

    # If the user enters a smaller size, the GUI changes it to this value
    MIN_SIZE_ENTRY = Size("1 MiB")

    def __init__(self, data, device_tree, request: DeviceFactoryRequest,
                 permissions: DeviceFactoryPermissions, disks, names):
        GUIObject.__init__(self, data)
        self._device_tree = device_tree
        self._disks = disks
        self._request = request
        self._permissions = permissions
        self._original_name = request.container_name
        self._container_names = names
        self._original_luks_version = request.luks_version
        self._error = ""

        self._title_label = self.builder.get_object(
            "container_dialog_title_label")
        self._dialog_label = self.builder.get_object("container_dialog_label")
        self._error_label = self.builder.get_object("containerErrorLabel")
        self._name_entry = self.builder.get_object("container_name_entry")
        self._encryptCheckbutton = self.builder.get_object(
            "containerEncryptedCheckbox")
        self._luks_combo = self.builder.get_object("luksVersionCombo")
        self._luks_store = self.builder.get_object("luksVersionStore")
        self._luks_label = self.builder.get_object("luksVersionLabel")
        self._raidStoreFilter = self.builder.get_object(
            "containerRaidStoreFiltered")
        self._store = self.builder.get_object("disk_store")
        self._treeview = self.builder.get_object("container_disk_view")
        self._sizeCombo = self.builder.get_object("containerSizeCombo")
        self._sizeEntry = self.builder.get_object("containerSizeEntry")
        self._raidLevelCombo = self.builder.get_object(
            "containerRaidLevelCombo")
        self._raidLevelLabel = self.builder.get_object(
            "containerRaidLevelLabel")
        self._save_button = self.builder.get_object("container_save_button")

        GUIDialogInputCheckHandler.__init__(self, self._save_button)

        self._supported_raid_levels = get_supported_container_raid_levels(
            self._device_tree, self._request.device_type)

        self._set_labels()
        self._populate_disks()
        self._select_disks()
        self._populate_raid()
        self._set_name()
        self._set_size()
        self._set_encryption()
        self._populate_luks()

    def _set_labels(self):
        container_type = get_container_type(self._request.device_type)
        title_text = _(CONTAINER_DIALOG_TITLE) % {
            "container_type": _(container_type.name).upper()
        }
        self._title_label.set_text(title_text)

        dialog_text = _(CONTAINER_DIALOG_TEXT) % {
            "container_type": _(container_type.name).lower()
        }
        self._dialog_label.set_text(dialog_text)

    def _populate_disks(self):
        for device_name in self._disks:
            device_data = DeviceData.from_structure(
                self._device_tree.GetDeviceData(device_name))
            device_free_space = self._device_tree.GetDiskFreeSpace(
                [device_name])
            self._store.append([
                "{} ({})".format(device_data.description,
                                 device_data.attrs.get("serial", "")),
                str(Size(device_data.size)),
                str(Size(device_free_space)), device_name
            ])

    def _select_disks(self):
        model = self._treeview.get_model()
        itr = model.get_iter_first()
        selection = self._treeview.get_selection()

        while itr:
            device_name = model.get_value(itr, 3)
            if device_name in self._request.disks:
                selection.select_iter(itr)

            itr = model.iter_next(itr)

        if not self._permissions.can_modify_container():
            self._treeview.set_sensitive(False)

    def _populate_raid(self):
        """Set up the raid-specific portion of the device details.

        Hide the RAID level menu if this device type does not support RAID.
        Choose a default RAID level.
        """
        self._raidStoreFilter.set_visible_func(self._raid_level_visible)
        self._raidStoreFilter.refilter()

        if not self._supported_raid_levels:
            for widget in [self._raidLevelLabel, self._raidLevelCombo]:
                really_hide(widget)
            return

        raid_level = self._request.container_raid_level

        for (i, row) in enumerate(self._raidLevelCombo.get_model()):
            if row[1] == raid_level:
                self._raidLevelCombo.set_active(i)
                break

        for widget in [self._raidLevelLabel, self._raidLevelCombo]:
            really_show(widget)

        fancy_set_sensitive(self._raidLevelCombo,
                            self._permissions.container_raid_level)

    def _raid_level_visible(self, model, itr, user_data):
        raid_level = model[itr][1]
        return raid_level in self._supported_raid_levels

    def _set_name(self):
        self._name_entry.set_text(self._request.container_name)
        self.add_check(self._name_entry, self._check_name_entry)

        if not self._permissions.container_name:
            fancy_set_sensitive(self._name_entry, False)

    def _check_name_entry(self, inputcheck):
        container_name = self.get_input(inputcheck.input_obj).strip()

        if container_name == self._original_name:
            return InputCheck.CHECK_OK

        if container_name in self._container_names:
            return _("Name is already in use.")

        report = ValidationReport.from_structure(
            self._device_tree.ValidateContainerName(container_name))

        if not report.is_valid():
            return " ".join(report.get_messages())

        return InputCheck.CHECK_OK

    def _set_size(self):
        if self._request.container_size_policy == SIZE_POLICY_AUTO:
            self._sizeCombo.set_active(0)
            self._sizeEntry.set_text("")
        elif self._request.container_size_policy == SIZE_POLICY_MAX:
            self._sizeCombo.set_active(1)
            self._sizeEntry.set_text("")
        else:
            self._sizeCombo.set_active(2)
            size = Size(self._request.container_size_policy)
            self._sizeEntry.set_text(size.human_readable(max_places=2))

        if not self._permissions.container_size_policy:
            fancy_set_sensitive(self._sizeCombo, False)
            self._sizeEntry.set_sensitive(False)

    def _set_encryption(self):
        self._encryptCheckbutton.set_active(self._request.container_encrypted)

        if not self._permissions.container_encrypted:
            fancy_set_sensitive(self._encryptCheckbutton, False)

    def _populate_luks(self):
        """Set up the LUKS version combo box."""
        # Add the values.
        self._luks_store.clear()
        for version in ["luks1", "luks2"]:
            self._luks_store.append([version])

        # Get the selected value.
        luks_version = self._request.luks_version or self._device_tree.GetDefaultLUKSVersion(
        )

        # Set the selected value.
        idx = next(i for i, data in enumerate(self._luks_combo.get_model())
                   if data[0] == luks_version)
        self._luks_combo.set_active(idx)
        self._update_luks_combo()

    def _update_luks_combo(self):
        if self._encryptCheckbutton.get_active():
            really_show(self._luks_label)
            really_show(self._luks_combo)
        else:
            really_hide(self._luks_label)
            really_hide(self._luks_combo)

    def run(self):
        while True:
            self._error = ""
            rc = self.window.run()
            if rc == 1:
                # Save clicked and input validation passed, try saving it
                if self.on_ok_clicked():
                    self._save_clicked()

                    # If that failed, try again
                    if self._error:
                        continue
                    else:
                        break
                # Save clicked with invalid input, try again
                else:
                    continue
            else:
                # Cancel or something similar, just exit
                break

        self.window.destroy()
        return rc

    def _save_clicked(self):
        if not self._permissions.can_modify_container():
            return

        if not self._validate_disks():
            return

        if not self._validate_raid_level():
            return

        self._request.disks = self._get_disks()
        self._request.container_name = self._name_entry.get_text().strip()
        self._request.container_encrypted = self._encryptCheckbutton.get_active(
        )
        self._request.luks_version = self._get_luks_version()
        self._request.container_size_policy = self._get_size_policy()
        self._request.container_raid_level = get_selected_raid_level(
            self._raidLevelCombo)
        self._error_label.set_text("")

    def _validate_disks(self):
        if not self._get_disks():
            self._error = _("No disks selected.")
            self._error_label.set_text(self._error)
            self.window.show_all()
            return False

        return True

    def _validate_raid_level(self):
        raid_level = get_selected_raid_level(self._raidLevelCombo)
        self._error = ""

        if raid_level:
            paths = self._treeview.get_selection().get_selected_rows()[1]
            report = ValidationReport.from_structure(
                self._device_tree.ValidateRaidLevel(raid_level, len(paths)))

            if not report.is_valid():
                self._error = " ".join(report.get_messages())
                self._error_label.set_text(self._error)
                self.window.show_all()
                return False

        return True

    def _get_disks(self):
        model, paths = self._treeview.get_selection().get_selected_rows()
        disks = []

        for path in paths:
            itr = model.get_iter(path)
            device_name = model.get_value(itr, 3)
            disks.append(device_name)

        return disks

    def _get_size_policy(self):
        idx = self._sizeCombo.get_active()

        if idx == 0:
            return SIZE_POLICY_AUTO

        if idx == 1:
            return SIZE_POLICY_MAX

        original_size = Size(self._request.container_size_policy)
        original_entry = original_size.human_readable(max_places=2)

        if self._sizeEntry.get_text() == original_entry:
            return self._request.container_size_policy

        size = get_size_from_entry(self._sizeEntry,
                                   lower_bound=self.MIN_SIZE_ENTRY,
                                   units=SIZE_UNITS_DEFAULT)

        if size is None:
            return SIZE_POLICY_MAX

        return size.get_bytes()

    def _get_luks_version(self):
        if self._encryptCheckbutton.get_active():
            active_index = self._luks_combo.get_active()

            if active_index != -1:
                return self._luks_combo.get_model()[active_index][0]

        return self._original_luks_version

    def on_size_changed(self, combo):
        active_index = combo.get_active()
        if active_index == 0:
            self._sizeEntry.set_sensitive(False)
        elif active_index == 1:
            self._sizeEntry.set_sensitive(False)
        else:
            self._sizeEntry.set_sensitive(True)

    def on_encrypt_toggled(self, widget):
        self._update_luks_combo()
class AddDialog(GUIObject):
    builderObjects = [
        "addDialog", "mountPointStore", "mountPointCompletion",
        "mountPointEntryBuffer"
    ]
    mainWidgetName = "addDialog"
    uiFile = "spokes/lib/custom_storage_helpers.glade"

    # If the user enters a smaller size, the GUI changes it to this value
    MIN_SIZE_ENTRY = Size("1 MiB")

    def __init__(self, data, device_tree):
        super().__init__(data)
        self._device_tree = device_tree
        self._size = Size(0)
        self._mount_point = ""
        self._error = ""

        self._warning_label = self.builder.get_object("mountPointWarningLabel")

        self._size_entry = self.builder.get_object("addSizeEntry")
        self._size_entry.set_tooltip_text(DESIRED_CAPACITY_HINT)

        self._populate_mount_points()

    @property
    def mount_point(self):
        """The requested mount point."""
        return self._mount_point

    @property
    def size(self):
        """The requested size."""
        return self._size

    def _populate_mount_points(self):
        mount_points = self._device_tree.CollectUnusedMountPoints()
        mount_point_store = self.builder.get_object("mountPointStore")

        for path in mount_points:
            mount_point_store.append([path])

        entry = self.builder.get_object("addMountPointEntry")
        entry.set_model(mount_point_store)

        completion = self.builder.get_object("mountPointCompletion")
        completion.set_text_column(0)
        completion.set_popup_completion(True)

    def on_add_confirm_clicked(self, button, *args):
        self._error = ""
        self._set_mount_point()
        self._set_size()

        self._warning_label.set_text(self._error)
        self.window.show_all()

        if not self._error:
            self.window.destroy()

    def _set_mount_point(self):
        self._mount_point = self.builder.get_object(
            "addMountPointEntry").get_active_text()

        if lowerASCII(self._mount_point) in ("swap", "biosboot", "prepboot"):
            return

        report = ValidationReport.from_structure(
            self._device_tree.ValidateMountPoint(self._mount_point))
        self._error = " ".join(report.get_messages())

    def _set_size(self):
        self._size = get_size_from_entry(
            self.builder.get_object("addSizeEntry"),
            lower_bound=self.MIN_SIZE_ENTRY,
            units=SIZE_UNITS_DEFAULT)

        if self._size is None or self._size < Size("1 MB"):
            self._size = Size(0)

    def refresh(self):
        super().refresh()
        self._warning_label.set_text("")

    def run(self):
        while True:
            self._error = ""
            rc = self.window.run()
            if not self._error:
                return rc
Пример #10
0
 def _set_size(self):
     self._size = get_size_from_entry(self._size_entry) or Size(0)
Пример #11
0
    DeviceFactoryPermissions
from pyanaconda.modules.common.structures.storage import DeviceFormatData, DeviceData
from pyanaconda.modules.common.structures.validation import ValidationReport
from pyanaconda.ui.lib.storage import size_from_input
from pyanaconda.ui.helpers import InputCheck
from pyanaconda.ui.gui import GUIObject
from pyanaconda.ui.gui.helpers import GUIDialogInputCheckHandler
from pyanaconda.ui.gui.utils import fancy_set_sensitive, really_hide, really_show

log = get_module_logger(__name__)

# Default to these units when reading user input when no units given
SIZE_UNITS_DEFAULT = "MiB"

# If the user enters a smaller size, the UI changes it to this value.
MIN_SIZE_ENTRY = Size("1 MiB")

# If the user enters a larger size, the UI changes it to this value.
MAX_SIZE_ENTRY = Size(2**64 - 1)

# If the user enters a larger size, the UI changes it to this value.
MAX_SIZE_POLICY_ENTRY = Size(2**63 - 1)

NOTEBOOK_LABEL_PAGE = 0
NOTEBOOK_DETAILS_PAGE = 1
NOTEBOOK_LUKS_PAGE = 2
NOTEBOOK_UNEDITABLE_PAGE = 3
NOTEBOOK_INCOMPLETE_PAGE = 4

NEW_CONTAINER_TEXT = N_("Create a new %(container_type)s ...")
CONTAINER_TOOLTIP = N_("Create or select %(container_type)s")