diff options
author | David Lehman <dlehman@redhat.com> | 2012-07-03 10:03:23 -0500 |
---|---|---|
committer | David Lehman <dlehman@redhat.com> | 2012-07-10 15:08:11 -0500 |
commit | a969e5087cf90eac44bf0e71841d1cd10d4823e0 (patch) | |
tree | 04aa2a300531e7389bfad890c22f77e959a6d24d /pyanaconda | |
parent | 215585e9fcf9315bc3729034abe6768347e7a4c8 (diff) | |
download | anaconda-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.py | 15 | ||||
-rw-r--r-- | pyanaconda/storage/devicetree.py | 43 | ||||
-rw-r--r-- | pyanaconda/ui/gui/spokes/storage.py | 31 |
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) |