[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH 1/2] Add support for clearpart --list= for removal of specific partitions.



---
 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]