summaryrefslogtreecommitdiffstats
path: root/pyanaconda
diff options
context:
space:
mode:
authorDavid Lehman <dlehman@redhat.com>2012-07-03 10:03:23 -0500
committerDavid Lehman <dlehman@redhat.com>2012-07-10 15:08:11 -0500
commita969e5087cf90eac44bf0e71841d1cd10d4823e0 (patch)
tree04aa2a300531e7389bfad890c22f77e959a6d24d /pyanaconda
parent215585e9fcf9315bc3729034abe6768347e7a4c8 (diff)
downloadanaconda-a969e5087cf90eac44bf0e71841d1cd10d4823e0.tar.gz
anaconda-a969e5087cf90eac44bf0e71841d1cd10d4823e0.tar.xz
anaconda-a969e5087cf90eac44bf0e71841d1cd10d4823e0.zip
Disk selection determines both ignoredisk.onlyuse and clearpart.drives.
This adds a way to hide devices from the devicetree without removing them. The devicetree is initially populated without filtering because we need to collect information about disks in the system as well as free space in disks and filesystems. Disk selection in the storage spoke establishes the set of disks to be used during install. We don't want to re-populate the tree every time a disk is selected or deselected. Instead, we just hide/unhide the disk and all devices it contains.
Diffstat (limited to 'pyanaconda')
-rw-r--r--pyanaconda/storage/devicelibs/lvm.py15
-rw-r--r--pyanaconda/storage/devicetree.py43
-rw-r--r--pyanaconda/ui/gui/spokes/storage.py31
3 files changed, 77 insertions, 12 deletions
diff --git a/pyanaconda/storage/devicelibs/lvm.py b/pyanaconda/storage/devicelibs/lvm.py
index 36fd9802a..136168b91 100644
--- a/pyanaconda/storage/devicelibs/lvm.py
+++ b/pyanaconda/storage/devicelibs/lvm.py
@@ -83,7 +83,20 @@ def lvm_cc_addFilterRejectRegexp(regexp):
log.debug("lvm filter: adding %s to the reject list" % regexp)
config_args_data["filterRejects"].append(regexp)
- # compoes config once more.
+ # compose config once more.
+ _composeConfig()
+
+def lvm_cc_removeFilterRejectRegexp(regexp):
+ """ Remove a regular expression from the --config string."""
+ global config_args_data
+ log.debug("lvm filter: removing %s from the reject list" % regexp)
+ try:
+ config_args_data["filterRejects"].remove(regexp)
+ except ValueError:
+ log.debug("%s wasn't in the reject list" % regexp)
+ return
+
+ # compose config once more.
_composeConfig()
def lvm_cc_resetFilter():
diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py
index 2c36f8376..ae69be2b8 100644
--- a/pyanaconda/storage/devicetree.py
+++ b/pyanaconda/storage/devicetree.py
@@ -166,6 +166,8 @@ class DeviceTree(object):
# a list of all device names we encounter
self.names = []
+ self._hidden = []
+
# indicates whether or not the tree has been fully populated
self.populated = False
@@ -1686,12 +1688,45 @@ class DeviceTree(object):
self._removeDevice(md)
- def _recursiveRemove(self, device):
+ def hide(self, device):
for d in self.getChildren(device):
- self._recursiveRemove(d)
+ self.hide(d)
+
+ log.info("hiding device %s %s (id %d)" % (device.type,
+ device.name,
+ device.id))
- device.teardown()
- self._removeDevice(device)
+ for action in reversed(self._actions):
+ if not action.device.dependsOn(device) and action.device != device:
+ continue
+
+ log.debug("cancelling action: %s" % action)
+ try:
+ action.cancel()
+ except Exception:
+ log.warning("failed to cancel action while hiding %s: %s"
+ % (device.name, action))
+ finally:
+ self._actions.remove(action)
+
+ # XXX modifications that do not require actions, like setting a
+ # mountpoint, will not be reversed here
+
+ # we're intentionally not modifying self.names here
+ self._devices.remove(device)
+ self._hidden.append(device)
+ lvm.lvm_cc_addFilterRejectRegexp(device.name)
+
+ def unhide(self, device):
+ # the hidden list should be in leaves-first order
+ for hidden in reversed(self._hidden):
+ if hidden == device or hidden.dependsOn(device):
+ log.info("unhiding device %s %s (id %d)" % (hidden.type,
+ hidden.name,
+ hidden.id))
+ self._hidden.remove(hidden)
+ self._devices.append(hidden)
+ lvm.lvm_cc_removeFilterRejectRegexp(device.name)
def _setupLvs(self):
ret = False
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 4cf3f5e35..0e3ececac 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -240,7 +240,12 @@ class StorageSpoke(NormalSpoke):
def __init__(self, *args, **kwargs):
NormalSpoke.__init__(self, *args, **kwargs)
self._ready = False
- self.selected_disks = self.data.clearpart.drives[:]
+ self.selected_disks = self.data.ignoredisk.onlyuse[:]
+
+ # This list gets set up once in initialize and should not be modified
+ # except perhaps to add advanced devices. It will remain the full list
+ # of disks that can be included in the install.
+ self.disks = []
if not flags.automatedInstall:
# default to using autopart for interactive installs
@@ -252,6 +257,7 @@ class StorageSpoke(NormalSpoke):
self.clearPartType = CLEARPART_TYPE_LINUX
def apply(self):
+ self.data.ignoredisk.onlyuse = self.selected_disks[:]
self.data.clearpart.drives = self.selected_disks[:]
self.data.autopart.autopart = self.autopart
@@ -263,6 +269,14 @@ class StorageSpoke(NormalSpoke):
else:
self.clearPartType = CLEARPART_TYPE_NONE
+ for disk in self.disks:
+ if disk.name not in self.selected_disks and \
+ disk in self.storage.devices:
+ self.storage.devicetree.hide(disk)
+ elif disk.name in self.selected_disks and \
+ disk not in self.storage.devices:
+ self.storage.devicetree.unhide(disk)
+
self.data.bootloader.location = "mbr"
self.data.clearpart.initAll = True
@@ -301,10 +315,10 @@ class StorageSpoke(NormalSpoke):
def status(self):
""" A short string describing the current status of storage setup. """
msg = _("No disks selected")
- if self.data.clearpart.drives:
+ if self.data.ignoredisk.onlyuse:
msg = P_(("%d disk selected"),
("%d disks selected"),
- len(self.data.clearpart.drives)) % len(self.data.clearpart.drives)
+ len(self.data.ignoredisk.onlyuse)) % len(self.data.ignoredisk.onlyuse)
if self.data.autopart.autopart:
msg = _("Automatic partitioning selected")
@@ -330,7 +344,7 @@ class StorageSpoke(NormalSpoke):
def refresh(self):
# synchronize our local data store with the global ksdata
- self.selected_disks = self.data.clearpart.drives[:]
+ self.selected_disks = self.data.ignoredisk.onlyuse[:]
self.autopart = self.data.autopart.autopart
# update the selections in the ui
@@ -367,7 +381,7 @@ class StorageSpoke(NormalSpoke):
if storageThread:
storageThread.join()
- print self.data.clearpart.drives
+ print self.data.ignoredisk.onlyuse
self.disks = getDisks(self.storage.devicetree)
@@ -408,7 +422,9 @@ class StorageSpoke(NormalSpoke):
capacity = 0
free = Size(bytes=0)
- free_space = self.storage.getFreeSpace(clearPartType=self.clearPartType)
+ # pass in our disk list so hidden disks' free space is available
+ free_space = self.storage.getFreeSpace(disks=self.disks,
+ clearPartType=self.clearPartType)
selected = [d for d in self.disks if d.name in self.selected_disks]
for disk in selected:
@@ -448,7 +464,8 @@ class StorageSpoke(NormalSpoke):
# signal handlers
def on_summary_clicked(self, button):
# show the selected disks dialog
- free_space = self.storage.getFreeSpace()
+ # pass in our disk list so hidden disks' free space is available
+ free_space = self.storage.getFreeSpace(disks=self.disks)
dialog = SelectedDisksDialog(self.data,)
dialog.refresh([d for d in self.disks if d.name in self.selected_disks],
free_space)