--- pyanaconda/kickstart.py | 20 +++++++- pyanaconda/storage/__init__.py | 1 + pyanaconda/storage/devicetree.py | 4 +- pyanaconda/storage/partitioning.py | 85 ++++++++++++++++++++---------------- 4 files changed, 69 insertions(+), 41 deletions(-) diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py index 74ccaea..5167d1f 100644 --- a/pyanaconda/kickstart.py +++ b/pyanaconda/kickstart.py @@ -380,9 +380,9 @@ class BTRFSData(commands.btrfs.F17_BTRFSData): self.anaconda.dispatch.skip_steps("partition", "parttype") -class ClearPart(commands.clearpart.FC3_ClearPart): +class ClearPart(commands.clearpart.F17_ClearPart): def parse(self, args): - retval = commands.clearpart.FC3_ClearPart.parse(self, args) + retval = commands.clearpart.F17_ClearPart.parse(self, args) if self.type is None: self.type = CLEARPART_TYPE_NONE @@ -399,11 +399,24 @@ class ClearPart(commands.clearpart.FC3_ClearPart): self.drives = drives + # Do any glob expansion now, since we need to have the real list of + # devices available before the execute methods run. + devices = [] + for spec in self.devices: + matched = deviceMatches(spec) + if matched: + devices.extend(matched) + else: + raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent device %s in clearpart device list" % spec) + + self.devices = devices + return retval def execute(self): self.anaconda.storage.config.clearPartType = self.type self.anaconda.storage.config.clearPartDisks = self.drives + self.anaconda.storage.config.clearPartDevices = self.devices if self.initAll: self.anaconda.storage.config.reinitializeDisks = self.initAll @@ -913,7 +926,8 @@ class PartitionData(commands.partition.F12_PartData): should_clear = shouldClear(disk, storage.config.clearPartType, - storage.config.clearPartDisks) + storage.config.clearPartDisks, + storage.config.clearPartDevices) if disk and (disk.partitioned or should_clear): kwargs["disks"] = [disk] break diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py index 4f90ca2..c7cc81e 100644 --- a/pyanaconda/storage/__init__.py +++ b/pyanaconda/storage/__init__.py @@ -282,6 +282,7 @@ class StorageDiscoveryConfig(object): self.exclusiveDisks = [] self.clearPartType = None self.clearPartDisks = [] + self.clearPartDevices = [] self.reinitializeDisks = False self.zeroMbr = None self.protectedDevSpecs = [] diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py index 109ddb2..7f10724 100644 --- a/pyanaconda/storage/devicetree.py +++ b/pyanaconda/storage/devicetree.py @@ -168,6 +168,7 @@ class DeviceTree(object): self.exclusiveDisks = getattr(conf, "exclusiveDisks", []) self.clearPartType = getattr(conf, "clearPartType", CLEARPART_TYPE_NONE) self.clearPartDisks = getattr(conf, "clearPartDisks", []) + self.clearPartDevices = getattr(conf, "clearPartDevices", []) self.zeroMbr = getattr(conf, "zeroMbr", False) self.reinitializeDisks = getattr(conf, "reinitializeDisks", False) self.iscsi = iscsi @@ -1698,7 +1699,8 @@ class DeviceTree(object): return if shouldClear(device, self.clearPartType, - clearPartDisks=self.clearPartDisks): + clearPartDisks=self.clearPartDisks, + clearPartDevices=self.clearPartDevices): # if this is a device that will be cleared by clearpart, # don't bother with format-specific processing return diff --git a/pyanaconda/storage/partitioning.py b/pyanaconda/storage/partitioning.py index 49faa78..6d817a7 100644 --- a/pyanaconda/storage/partitioning.py +++ b/pyanaconda/storage/partitioning.py @@ -387,8 +387,8 @@ def doAutoPartition(anaconda): anaconda.storage.reset() return DISPATCH_BACK -def shouldClear(device, clearPartType, clearPartDisks=None): - if clearPartType not in [CLEARPART_TYPE_LINUX, CLEARPART_TYPE_ALL]: +def shouldClear(device, clearPartType, clearPartDisks=None, clearPartDevices=None): + if clearPartType in [CLEARPART_TYPE_NONE, None]: return False if isinstance(device, PartitionDevice): @@ -434,8 +434,31 @@ def shouldClear(device, clearPartType, clearPartDisks=None): if device.protected: return False + if clearPartType == CLEARPART_TYPE_LIST and \ + not clearPartDevices or device.name not in clearPartDevices: + return False + return True +def recursiveRemove(storage, device): + log.debug("clearing %s" % device.name) + + # XXX is there any argument for not removing incomplete devices? + # -- maybe some RAID devices + devices = storage.deviceDeps(device) + while devices: + log.debug("devices to remove: %s" % ([d.name for d in devices],)) + leaves = [d for d in devices if d.isleaf] + log.debug("leaves to remove: %s" % ([d.name for d in leaves],)) + for leaf in leaves: + storage.destroyDevice(leaf) + devices.remove(leaf) + + if device.isDisk: + storage.destroyFormat(device) + else: + storage.destroyDevice(device) + def clearPartitions(storage, bootloader=None): """ Clear partitions and dependent devices from disks. @@ -468,45 +491,33 @@ def clearPartitions(storage, bootloader=None): partitions.sort(key=lambda p: p.partedPartition.number, reverse=True) for part in partitions: log.debug("clearpart: looking at %s" % part.name) - if not shouldClear(part, storage.config.clearPartType, storage.config.clearPartDisks): + if not shouldClear(part, storage.config.clearPartType, storage.config.clearPartDisks, storage.config.clearPartDevices): continue - log.debug("clearing %s" % part.name) + recursiveRemove(storage, part) + log.debug("partitions: %s" % [p.getDeviceNodeName() for p in part.partedPartition.disk.partitions]) + + # now clear devices that are not partitions and were not implicitly cleared + # when clearing partitions + not_visited = [d for d in storage.devices if not d.partitioned] + while not_visited: + for device in [d for d in not_visited if d.isleaf]: + not_visited.remove(device) - # XXX is there any argument for not removing incomplete devices? - # -- maybe some RAID devices - devices = storage.deviceDeps(part) - while devices: - log.debug("devices to remove: %s" % ([d.name for d in devices],)) - leaves = [d for d in devices if d.isleaf] - log.debug("leaves to remove: %s" % ([d.name for d in leaves],)) - for leaf in leaves: - storage.destroyDevice(leaf) - devices.remove(leaf) + if not shouldClear(device, storage.config.clearPartType, storage.config.clearPartDisks, storage.config.clearPartDevices): + continue - log.debug("partitions: %s" % [p.getDeviceNodeName() for p in part.partedPartition.disk.partitions]) - storage.destroyDevice(part) - - for disk in [d for d in storage.disks if d not in storage.partitioned]: - # clear any whole-disk formats that need clearing - if shouldClear(disk, storage.config.clearPartType, storage.config.clearPartDisks): - log.debug("clearing %s" % disk.name) - devices = storage.deviceDeps(disk) - while devices: - log.debug("devices to remove: %s" % ([d.name for d in devices],)) - leaves = [d for d in devices if d.isleaf] - log.debug("leaves to remove: %s" % ([d.name for d in leaves],)) - for leaf in leaves: - storage.destroyDevice(leaf) - devices.remove(leaf) - - destroy_action = ActionDestroyFormat(disk) - labelType = storage.platform.bestDiskLabelType(disk) - newLabel = getFormat("disklabel", device=disk.path, - labelType=labelType) - create_action = ActionCreateFormat(disk, format=newLabel) - storage.devicetree.registerAction(destroy_action) - storage.devicetree.registerAction(create_action) + recursiveRemove(storage, device) + + # put disklabels on unpartitioned disks + if device.isDisk and not d.partitioned: + labelType = storage.platform.bestDiskLabelType(disk) + newLabel = getFormat("disklabel", device=disk.path, + labelType=labelType) + create_action = ActionCreateFormat(disk, format=newLabel) + storage.devicetree.registerAction(create_action) + + not_visited = [d for d in storage.devices if d in not_visited] # now remove any empty extended partitions removeEmptyExtendedPartitions(storage) -- 1.7.7.6 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list