[master 1/1] Enforce sane disk selections.

dwlehman installerbot-noreply at redhat.com
Tue Mar 31 19:03:28 UTC 2015


From: David Lehman <dlehman at redhat.com>

There is no value (and a great deal of trouble) in allowing users to split
up an existing md array, lvm vg, or btrfs volume by selecting a subset of
the disks it uses.
---
 pyanaconda/ui/gui/spokes/storage.py | 13 ++++++++++++-
 pyanaconda/ui/lib/disks.py          | 30 ++++++++++++++++++++++++++++++
 pyanaconda/ui/tui/spokes/storage.py | 14 ++++++++++++--
 3 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index abca0c4..7c9ae70 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -42,7 +42,7 @@
 from gi.repository import Gdk, GLib, AnacondaWidgets
 
 from pyanaconda.ui.communication import hubQ
-from pyanaconda.ui.lib.disks import getDisks, isLocalDisk, applyDiskSelection
+from pyanaconda.ui.lib.disks import getDisks, isLocalDisk, applyDiskSelection, checkDiskSelection
 from pyanaconda.ui.gui import GUIObject
 from pyanaconda.ui.gui.spokes import NormalSpoke
 from pyanaconda.ui.gui.spokes.lib.cart import SelectedDisksDialog
@@ -754,6 +754,17 @@ def on_back_clicked(self, button):
                    partition in self.storage.partitions:
                     self.storage.recursiveRemove(partition)
 
+        # make sure no containers were split up by the user's disk selection
+        self.clear_info()
+        self.errors = checkDiskSelection(self.storage,
+                                         self.disks, self.selected_disks)
+        if self.errors:
+            # The disk selection has to make sense before we can proceed.
+            self.set_error(_("There was a problem with your disk selection. "
+                             "Click here for details."))
+            self.back_clicked = False
+            return
+
         # hide/unhide disks as requested
         for disk in self.disks:
             if disk.name not in self.selected_disks and \
diff --git a/pyanaconda/ui/lib/disks.py b/pyanaconda/ui/lib/disks.py
index 9d4607f..3146dab 100644
--- a/pyanaconda/ui/lib/disks.py
+++ b/pyanaconda/ui/lib/disks.py
@@ -92,3 +92,33 @@ def applyDiskSelection(storage, data, use_names):
 
     data.ignoredisk.onlyuse = onlyuse
     data.clearpart.drives = use_names[:]
+
+def getRelatedDisks(storage, disk):
+    """ Return a list of disks related to disk by way of container devices. """
+    return set(d for dep in storage.deviceDeps(disk) for d in dep.disks)
+
+def checkDiskSelection(storage, all_disks, selected_disks):
+    """ Return a list of errors related to a proposed disk selection.
+
+        :param :class:`blivet.Blivet` storage: storage data
+        :param all_disks: all known disks
+        :type all_disks: list of :class:`blivet.devices.StorageDevice`
+        :param selected_disks: proposed selected disks
+        :type selected_disks: list of :class:`blivet.devices.StorageDevice`
+        :returns: a list of error messages
+        :rtype: list of str
+    """
+    errors = []
+    for selected in all_disks:
+        if selected.name not in selected_disks:
+            continue
+
+        related = getRelatedDisks(storage, selected)
+        missing = [r.name for r in related if r.name not in selected_disks]
+        if missing:
+            errors.append("You selected disk %s, which contains devices that "
+                          "also use disk(s) %s. You must select or de-select "
+                          "these disks as a set." %
+                          (selected.name, ",".join(missing)))
+
+    return errors
diff --git a/pyanaconda/ui/tui/spokes/storage.py b/pyanaconda/ui/tui/spokes/storage.py
index 1bb0d11..43ad373 100644
--- a/pyanaconda/ui/tui/spokes/storage.py
+++ b/pyanaconda/ui/tui/spokes/storage.py
@@ -22,7 +22,7 @@
 # which has the same license and authored by David Lehman <dlehman at redhat.com>
 #
 
-from pyanaconda.ui.lib.disks import getDisks, applyDiskSelection
+from pyanaconda.ui.lib.disks import getDisks, applyDiskSelection, checkDiskSelection
 from pyanaconda.ui.categories.system import SystemCategory
 from pyanaconda.ui.tui.spokes import NormalTUISpoke
 from pyanaconda.ui.tui.simpleline import TextWidget, CheckboxWidget
@@ -260,7 +260,7 @@ def _format_disk_info(self, disk):
 
     def input(self, args, key):
         """Grab the disk choice and update things"""
-
+        self.errors = []
         try:
             keyid = int(key) - 1
             self.selection = keyid
@@ -281,6 +281,16 @@ def input(self, args, key):
                             self.run_dasdfmt(to_format)
                             return None
 
+                    # make sure no containers were split up by the user's disk
+                    # selection
+                    self.errors.extend(checkDiskSelection(self.storage,
+                                                          self.disks,
+                                                          self.selected_disks))
+                    if self.errors:
+                        # The disk selection has to make sense before we can
+                        # proceed.
+                        return None
+
                     newspoke = AutoPartSpoke(self.app, self.data, self.storage,
                                              self.payload, self.instclass)
                     self.app.switch_screen_modal(newspoke)


-- 
To view this commit on github, visit https://github.com/rhinstaller/anaconda/commit/86b21c5547353cc8847d4d13e486d8c3e14d5b32


More information about the anaconda-patches mailing list