Also fixes various bugs and things I noticed during testing, &c.
There's more that I'd like to clean up around this stuff, but I have to push on so I can get the custom spoke feature-complete.
We don't prompt for passphrases for encrypted devices, so this can only improve the quality of our device clearing. --- pyanaconda/storage/__init__.py | 6 ++---- pyanaconda/storage/devicetree.py | 13 +++---------- 2 files changed, 5 insertions(+), 14 deletions(-)
diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py index 680bc27..7fbc1bd 100644 --- a/pyanaconda/storage/__init__.py +++ b/pyanaconda/storage/__init__.py @@ -348,8 +348,7 @@ class Storage(object): passphrase=self.encryptionPassphrase, luksDict=self.__luksDevs, iscsi=self.iscsi, - dasd=self.dasd, - shouldClear=self.shouldClear) + dasd=self.dasd) self.fsset = FSSet(self.devicetree) self.roots = {} self.services = set() @@ -459,8 +458,7 @@ class Storage(object): passphrase=self.encryptionPassphrase, luksDict=self.__luksDevs, iscsi=self.iscsi, - dasd=self.dasd, - shouldClear=self.shouldClear) + dasd=self.dasd) self.devicetree.populate(cleanupOnly=cleanupOnly) self.config.clearPartType = clearPartType # set it back self.fsset = FSSet(self.devicetree) diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py index 2d30ae4..13ce493 100644 --- a/pyanaconda/storage/devicetree.py +++ b/pyanaconda/storage/devicetree.py @@ -155,11 +155,11 @@ class DeviceTree(object): """
def __init__(self, conf=None, passphrase=None, luksDict=None, - iscsi=None, dasd=None, shouldClear=None): - self.reset(conf, passphrase, luksDict, iscsi, dasd, shouldClear) + iscsi=None, dasd=None): + self.reset(conf, passphrase, luksDict, iscsi, dasd)
def reset(self, conf=None, passphrase=None, luksDict=None, - iscsi=None, dasd=None, shouldClear=None): + iscsi=None, dasd=None): # internal data members self._devices = [] self._actions = [] @@ -173,7 +173,6 @@ class DeviceTree(object): self.populated = False
self.exclusiveDisks = getattr(conf, "exclusiveDisks", []) - self.shouldClear = shouldClear or (lambda d: False) self.iscsi = iscsi self.dasd = dasd self.mpathFriendlyNames = getattr(conf, "mpathFriendlyNames", True) @@ -1647,12 +1646,6 @@ class DeviceTree(object): device.format = formats.DeviceFormat() return
- if self.shouldClear(device): - # if this is a device that will be cleared by clearpart, - # don't bother with format-specific processing - log.debug("skipping further processing due to clearpart") - return - # # now do any special handling required for the device's format #
This also expands the set of exceptions handled when testing the passphrase, which catches the case of an empty passphrase. --- pyanaconda/ui/gui/spokes/custom.py | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index b390f9a..c798aed 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -1975,9 +1975,11 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): passphrase = entry.get_text() device.format.passphrase = passphrase try: + device.setup() device.format.setup() - except CryptoError as e: + except StorageError as e: log.error("failed to unlock %s: %s" % (device.name, e)) + device.teardown(recursive=True) self._error = e device.format.passphrase = None entry.set_text("")
There is a filesystem type combo for this purpose. --- pyanaconda/ui/gui/spokes/custom.py | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index c798aed..f15f6d0 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -166,13 +166,18 @@ def populate_mountpoint_store(store, used_mountpoints): if path not in used_mountpoints: store.append([path])
-def validate_mountpoint(mountpoint, used_mountpoints): +def validate_mountpoint(mountpoint, used_mountpoints, strict=True): + if strict: + fake_mountpoints = [] + else: + fake_mountpoints = ["swap", "biosboot", "prepboot"] + valid = MOUNTPOINT_OK if mountpoint in used_mountpoints: valid = MOUNTPOINT_IN_USE elif not mountpoint: valid = MOUNTPOINT_EMPTY - elif (mountpoint.lower() not in ("swap", "biosboot", "prepboot") and + elif (mountpoint.lower() not in fake_mountpoints and ((len(mountpoint) > 1 and mountpoint.endswith("/")) or not mountpoint.startswith("/") or " " in mountpoint or @@ -208,7 +213,8 @@ class AddDialog(GUIObject):
def on_add_confirm_clicked(self, button, *args): self.mountpoint = self.builder.get_object("addMountPointEntry").get_text() - self._error = validate_mountpoint(self.mountpoint, self.mountpoints) + self._error = validate_mountpoint(self.mountpoint, self.mountpoints, + strict=False) self._warningLabel.set_text(mountpoint_validation_msgs[self._error]) self.window.show_all() if self._error:
--- pyanaconda/ui/gui/spokes/custom.py | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index f15f6d0..ebbca81 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -1665,7 +1665,8 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): container = device.volume device_type = AUTOPART_TYPE_BTRFS
- if container and not container.exists: + if container and not container.exists and \ + self.__storage.devicetree.getChildren(container): # adjust container to size of remaining devices with ui_storage_logger(): # TODO: raid
--- pyanaconda/ui/gui/spokes/custom.py | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index ebbca81..a26b22e 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -1074,6 +1074,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): self._update_btrfs_selectors()
self._updateSpaceDisplay() + self._populate_right_side(selector) return
## @@ -1128,6 +1129,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): self._update_btrfs_selectors()
self._updateSpaceDisplay() + self._populate_right_side(selector)
## ## ENCRYPTION
It is important not to base device type on the position of the currently selected item in the deviceTypeCombo since its contents vary. --- pyanaconda/ui/gui/spokes/custom.py | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index a26b22e..ebda87b 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -1246,7 +1246,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
def _get_raid_level(self): """ Return the raid level string based on the current ui selections. """ - device_type = self.builder.get_object("deviceTypeCombo").get_active() + device_type = self._get_current_device_type() widget_dict = self._get_raid_widget_dict(device_type) if not widget_dict: return None @@ -1298,7 +1298,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
def _update_disabled_raid_features(self, raid_level): """ Update disabled feature widgets based on raid level. """ - device_type = self.builder.get_object("deviceTypeCombo").get_active() + device_type = self._get_current_device_type() widget_dict = self._get_raid_widget_dict(device_type) disabled = self._get_raid_disabled_features(raid_level) for feature in raid_features:
Adds logic to treat a partitioned disk with no partitions as empty if storage.config.initializeDisks is True.
Removes some logic that doesn't belong related to clearing of non-existent devices.
Consolidates logic for determining whether a disk is "empty" into a nested function. --- pyanaconda/storage/__init__.py | 42 +++++++++++++++++++++------------------ 1 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py index 7fbc1bd..92dafee 100644 --- a/pyanaconda/storage/__init__.py +++ b/pyanaconda/storage/__init__.py @@ -699,6 +699,16 @@ class Storage(object): clearPartDevices = kwargs.get("clearPartDevices", self.config.clearPartDevices)
+ def empty_disk(device): + empty = True + if device.partitioned: + partitions = self.devicetree.getChildren(device) + empty = all([p.isMagic for p in partitions]) + else: + empty = (device.format.type is None) + + return empty + for disk in device.disks: # this will not include disks with hidden formats like multipath # and firmware raid member disks @@ -706,25 +716,20 @@ class Storage(object): return False
if not self.config.clearNonExistent: - if not device.exists: + if (device.isDisk and not device.format.exists) or \ + (not device.isDisk and not device.exists): return False
- if device.isDisk: - if not device.format.exists: - return False - - if device.partitioned: - for partition in self.devicetree.getChildren(device): - if not (partition.isMagic or self.shouldClear(partition)): - return False - # the only devices we want to clear when clearPartType is - # CLEARPART_TYPE_NONE are uninitialized disks in clearPartDisks, and - # then only when we have been asked to initialize disks as needed - if clearPartType in [CLEARPART_TYPE_NONE, None] and \ - not (device.isDisk and device.format.type is None and - self.config.initializeDisks): - return False + # CLEARPART_TYPE_NONE are uninitialized disks, or disks with no + # partitions, in clearPartDisks, and then only when we have been asked + # to initialize disks as needed + if clearPartType in [CLEARPART_TYPE_NONE, None]: + if not self.config.initializeDisks or not device.isDisk: + return False + + if not empty_disk(device): + return False
if isinstance(device, PartitionDevice): # Never clear the special first partition on a Mac disk label, as @@ -748,9 +753,8 @@ class Storage(object): # if clearPartType is not CLEARPART_TYPE_ALL but we'll still be # removing every partition from the disk, return True since we # will want to be able to create a new disklabel on this disk - for partition in self.devicetree.getChildren(device): - if not (partition.isMagic or self.shouldClear(partition)): - return False + if not empty_disk(device): + return False
# Never clear disks with hidden formats if device.format.hidden:
Only reinitialize them if the disklabel is preexisting and there are no partitions. --- pyanaconda/ui/gui/spokes/custom.py | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index ebda87b..39056fd 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -331,7 +331,13 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): args.append(ui_device.targetSize)
if ui_action.isCreate and ui_action.isFormat: - args.append(ui_device.format) + if ui_device.format.type == "disklabel": + # A DiskLabel instance will have partitions already in it. + args.append(getFormat("disklabel", + device=ui_device.path, + labelType=ui_device.format.labelType)) + else: + args.append(ui_device.format)
if ui_action.isCreate and ui_action.isDevice: # We're going to just move the already-defined device into the @@ -1654,6 +1660,13 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): if is_logical_partition: self.__storage.removeEmptyExtendedPartitions()
+ # If we've just removed the last partition and the disklabel is pre- + # existing, reinitialize the disk. + if device.type == "partition" and device.disk.format.exists: + with ui_storage_logger(): + if self.__storage.shouldClear(device.disk): + self.__storage.initializeDisk(device.disk) + self._devices = self.__storage.devices
# should this be in DeviceTree._removeDevice?
The base/min size is basically the format's min size and the max size is the requested size. --- pyanaconda/storage/__init__.py | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py index 92dafee..67979eb 100644 --- a/pyanaconda/storage/__init__.py +++ b/pyanaconda/storage/__init__.py @@ -3243,11 +3243,13 @@ class PartitionFactory(DeviceFactory): log.info("adjusting device size from %.2f to %.2f" % (device.size, size))
- size = min(PartitionFactory.default_size, size) - device.req_base_size = max(size, device.format.minSize) - device.req_size = device.req_base_size + base_size = max(PartitionFactory.default_size, + device.format.minSize) + size = max(base_size, size) + device.req_base_size = base_size + device.req_size = base_size device.req_max_size = size - device.req_grow = size > device.req_base_size + device.req_grow = size > base_size
return size
Related: rhbz#867593 --- pyanaconda/storage/devicetree.py | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py index 13ce493..9450ee0 100644 --- a/pyanaconda/storage/devicetree.py +++ b/pyanaconda/storage/devicetree.py @@ -832,11 +832,12 @@ class DeviceTree(object): major=udev_device_get_major(info), minor=udev_device_get_minor(info), exists=True, parents=[disk]) - except DeviceError: + except DeviceError as e: # corner case sometime the kernel accepts a partition table # which gets rejected by parted, in this case we will # prompt to re-initialize the disk, so simply skip the # faulty partitions. + log.error("Failed to instantiate PartitionDevice: %s" % e) return
self._addDevice(device)
--- pyanaconda/ui/gui/spokes/custom.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index 39056fd..049d484 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -1762,8 +1762,8 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): # refreshing the display will have the effect of making them disappear. # It's like they never existed. self._unused_devices = None # why do we cache this? - self._do_refresh() self._updateSpaceDisplay() + self._do_refresh()
def on_summary_clicked(self, button): dialog = SelectedDisksDialog(self.data)
Without this, newly selected disks will not be part of the space check. --- pyanaconda/ui/gui/spokes/storage.py | 21 ++++++++++++++------- 1 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py index 611f4ab..5804b00 100644 --- a/pyanaconda/ui/gui/spokes/storage.py +++ b/pyanaconda/ui/gui/spokes/storage.py @@ -340,13 +340,11 @@ class StorageSpoke(NormalSpoke, StorageChecker):
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) + if self.data.bootloader.bootDrive and \ + self.data.bootloader.bootDrive not in self.selected_disks: + self.data.bootloader.bootDrive = None + self.storage.bootloader.stage1_disk = None + self.storage.bootloader.stage1_device = None
self.data.bootloader.location = "mbr"
@@ -620,6 +618,15 @@ class StorageSpoke(NormalSpoke, StorageChecker): return rc
def on_continue_clicked(self, button): + # hide/unhide disks as requested + 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) + # show the installation options dialog disks = [d for d in self.disks if d.name in self.selected_disks] disks_size = sum(Size(spec="%f MB" % d.size) for d in disks)
We remove autopart because it's easy to put back. We don't remove custom layouts because they can take some time to set up. They can be removed using the reclaim dialog. --- pyanaconda/ui/gui/spokes/storage.py | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py index 5804b00..11b79ae 100644 --- a/pyanaconda/ui/gui/spokes/storage.py +++ b/pyanaconda/ui/gui/spokes/storage.py @@ -328,6 +328,8 @@ class StorageSpoke(NormalSpoke, StorageChecker): self.autopart = self.data.autopart.autopart self.clearPartType = CLEARPART_TYPE_NONE
+ self._previous_autopart = False + def apply(self): self.data.ignoredisk.onlyuse = self.selected_disks[:] self.data.clearpart.drives = self.selected_disks[:] @@ -468,6 +470,8 @@ class StorageSpoke(NormalSpoke, StorageChecker): self.encrypted = self.data.autopart.encrypted self.passphrase = self.data.autopart.passphrase
+ self._previous_autopart = self.autopart + encrypt_checkbutton = self.builder.get_object("encryption_checkbutton") encrypt_checkbutton.set_active(self.encrypted)
@@ -618,6 +622,14 @@ class StorageSpoke(NormalSpoke, StorageChecker): return rc
def on_continue_clicked(self, button): + # Remove all non-existing devices if autopart was active when we last + # refreshed. + if self._previous_autopart: + self._previous_autopart = False + actions = self.storage.devicetree.findActions(type="create") + for action in reversed(actions): + self.storage.devicetree.cancelAction(action) + # hide/unhide disks as requested for disk in self.disks: if disk.name not in self.selected_disks and \
Since we're not doing any implicit clearpart we can't do this anymore. --- pyanaconda/ui/gui/spokes/storage.py | 19 ++++--------------- 1 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py index 11b79ae..4492dce 100644 --- a/pyanaconda/ui/gui/spokes/storage.py +++ b/pyanaconda/ui/gui/spokes/storage.py @@ -648,22 +648,11 @@ class StorageSpoke(NormalSpoke, StorageChecker): disk_free = sum([f[0] for f in free_space.itervalues()]) fs_free = sum([f[1] for f in free_space.itervalues()])
- # add in total size of new filesystems - new_free_mb = 0 - for mountpoint, device in self.storage.mountpoints.items(): - if mountpoint != "/" and not mountpoint.startswith("/usr") and \ - not mountpoint.startswith("/var"): - # only count system mounts - continue - - if device.format.exists: - new_free_mb += getattr(device.format, "free", 0) - else: - new_free_mb += device.size - new_free = Size(spec="%f MB" % new_free_mb) - required_space = self.payload.spaceRequired - if disk_free + new_free >= required_space: + log.debug("disk free: %s fs free: %s sw needs: %s" % (disk_free, + fs_free, + required_space)) + if disk_free >= required_space: dialog = InstallOptions1Dialog(self.data) elif disks_size >= required_space: dialog = InstallOptions2Dialog(self.data, payload=self.payload)
--- pyanaconda/storage/__init__.py | 7 +++++++ pyanaconda/storage/devicetree.py | 2 +- pyanaconda/ui/gui/spokes/custom.py | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py index 67979eb..0726a1c 100644 --- a/pyanaconda/storage/__init__.py +++ b/pyanaconda/storage/__init__.py @@ -1400,6 +1400,13 @@ class Storage(object):
return name
+ def savePassphrase(self, device): + """ Save a device's LUKS passphrase in case of reset. """ + passphrase = device.format._LUKS__passphrase + self.__luksDevs[device.format.uuid] = passphrase + self.devicetree._DeviceTree__luksDevs[device.format.uuid] = passphrase + self.devicetree._DeviceTree__passphrases.append(passphrase) + def doEncryptionPassphraseRetrofits(self): """ Add the global passphrase to all preexisting LUKS devices.
diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py index 9450ee0..85d5c61 100644 --- a/pyanaconda/storage/devicetree.py +++ b/pyanaconda/storage/devicetree.py @@ -1165,7 +1165,7 @@ class DeviceTree(object): device.format.passphrase = 'yabbadabbadoo' else: # Try each known passphrase. - for passphrase in self.__luksDevs.values(): + for passphrase in self.__passphrases: device.format.passphrase = passphrase try: device.format.setup() diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index 049d484..55dd4c3 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -393,6 +393,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): parents=[slave], exists=True) luks_device.setup() + self.storage.savePassphrase(slave) self.storage.devicetree._addDevice(luks_device)
# XXX What if the user has changed storage config in the shell? @@ -2018,8 +2019,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): exists=True) self.__storage.devicetree._addDevice(luks_dev) # save the passphrase for possible reset and to try for other devs - self.__storage._Storage__luksDevs[device.format.uuid] = passphrase - self.__storage.devicetree._DeviceTree__luksDevs[device.format.uuid] = passphrase + self.__storage.savePassphrase(device) # XXX What if the user has changed things using the shell? self.__storage.devicetree.populate() # look for new roots
--- pyanaconda/ui/gui/spokes/storage.py | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py index 4492dce..4ec3d4e 100644 --- a/pyanaconda/ui/gui/spokes/storage.py +++ b/pyanaconda/ui/gui/spokes/storage.py @@ -413,6 +413,7 @@ class StorageSpoke(NormalSpoke, StorageChecker):
self.disks = getDisks(self.storage.devicetree) else: + self.errors = [] if self.autopart: # this was already run as part of doAutoPartition. dumb. self.run()
This is a different path than that originally reported, but the same fundamental cause. --- pyanaconda/packaging/yumpayload.py | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/pyanaconda/packaging/yumpayload.py b/pyanaconda/packaging/yumpayload.py index d8bff7e..e42d443 100644 --- a/pyanaconda/packaging/yumpayload.py +++ b/pyanaconda/packaging/yumpayload.py @@ -237,11 +237,12 @@ reposdir=%s # install root. We do this so we don't have to re-gather repo meta- # data after we change the install root to ROOT_PATH, which can only # happen after we've enabled the new storage configuration. - if not self._yum.conf.cachedir.startswith(self._yum.conf.installroot): - return + with _yum_lock: + if not self._yum.conf.cachedir.startswith(self._yum.conf.installroot): + return
- root = self._yum.conf.installroot - self._yum.conf.cachedir = self._yum.conf.cachedir[len(root):] + root = self._yum.conf.installroot + self._yum.conf.cachedir = self._yum.conf.cachedir[len(root):]
def _writeInstallConfig(self): """ Write out the yum config that will be used to install packages. @@ -606,7 +607,8 @@ reposdir=%s if method.method: with _yum_lock: self._yum.preconf.releasever = self._getReleaseVersion(url) - self._yumCacheDirHack() + + self._yumCacheDirHack() try: self._addYumRepo(BASE_REPO_NAME, url, proxyurl=method.proxy, sslverify=sslverify)
Previously, if an existing device had a mountpoint but was not scheduled for reformat when you scheduled a reformat, a new selector would be added without removing the old one(s). --- pyanaconda/ui/gui/spokes/custom.py | 34 +++++++++++++++++++--------------- 1 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index 55dd4c3..0683a3f 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -1190,22 +1190,26 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): "Click for details.")) self.window.show_all() else: - if old_mountpoint: - selector.props.mountpoint = (mountpoint or - selector._device.format.name) - selector.props.name = (self._mountpointName(mountpoint) - or selector._device.format.name) + # first, remove this selector from any old install page(s) + new_selector = None + for page in self._accordion.allPages: + for _selector in getattr(page, "_members", []): + if _selector._device in (device, old_device): + if page.pageTitle == new_install_name: + new_selector = _selector + continue + + page.removeSelector(_selector) + if not page._members: + log.debug("removing empty page %s" % page.pageTitle) + self._accordion.removePage(page.pageTitle) + + # either update the existing selector or add a new one + if new_selector: + new_selector.props.mountpoint = mountpoint or "" + new_selector.props.name = (self._mountpointName(mountpoint) + or device.format.name) else: - # first, remove this selector from any page(s) and add - # it to the new page - for page in self._accordion.allPages: - for _selector in getattr(page, "_members", []): - if _selector._device in (device, old_device): - page.removeSelector(_selector) - if not page._members: - log.debug("removing empty page %s" % page.pageTitle) - self._accordion.removePage(page.pageTitle) - self.add_new_selector(device)
return
--- pyanaconda/ui/gui/spokes/custom.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py index 0683a3f..f64d416 100644 --- a/pyanaconda/ui/gui/spokes/custom.py +++ b/pyanaconda/ui/gui/spokes/custom.py @@ -1499,7 +1499,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker): include_md = (use_dev.type == "mdarray" or len(self._clearpartDevices) > 1) if include_md and not md_included: - typeCombo.append_text(DEVICE_TEXT_RAID) + typeCombo.append_text(DEVICE_TEXT_MD) elif md_included and not include_md: typeCombo.remove(md_pos)
On 10/18/2012 02:49 PM, David Lehman wrote:
Also fixes various bugs and things I noticed during testing, &c.
There's more that I'd like to clean up around this stuff, but I have to push on so I can get the custom spoke feature-complete.
ACK
anaconda-patches@lists.fedorahosted.org