[PATCH rhel7-branch blivet] Introduce a new doReqPartition method that is similar to doAutoPartition.

Chris Lumens clumens at redhat.com
Mon Apr 13 19:51:41 UTC 2015


This method allows automatically creating just platform-specific partitions,
allowing kickstart files to do custom partitioning without having to introduce
lots of machine-specific details.

This also required splitting up platform.setDefaultPartitioning into two more
fined grained methods.  I've left the older method around with its existing
behavior for anyone who may be using it.  The split allows for users to be
even more picky in how much autostuff they want - just things like biosboot,
or also the /boot partition?

Related: rhbz#1164660
---
 blivet/partitioning.py | 46 +++++++++++++++++++++++++++++++++++++---------
 blivet/platform.py     | 44 ++++++++++++++++++++++++++++++--------------
 2 files changed, 67 insertions(+), 23 deletions(-)

diff --git a/blivet/partitioning.py b/blivet/partitioning.py
index f909de2..8051684 100644
--- a/blivet/partitioning.py
+++ b/blivet/partitioning.py
@@ -37,8 +37,8 @@ from .i18n import _
 import logging
 log = logging.getLogger("blivet")
 
-def _getCandidateDisks(storage):
-    """ Return a list of disks to be used for autopart.
+def getCandidateDisks(storage):
+    """ Return a list of disks to be used for autopart/reqpart.
 
         Disks must be partitioned and have a single free region large enough
         for a default-sized (500MiB) partition. They must also be in
@@ -115,8 +115,8 @@ def _scheduleImplicitPartitions(storage, disks, min_luks_entropy=0):
 
     return devs
 
-def _schedulePartitions(storage, disks, implicit_devices, min_luks_entropy=0):
-    """ Schedule creation of autopart partitions.
+def schedulePartitions(storage, disks, implicit_devices, min_luks_entropy=0, requests=None):
+    """ Schedule creation of autopart/reqpart partitions.
 
         This only schedules the requests for actual partitions.
 
@@ -127,9 +127,15 @@ def _schedulePartitions(storage, disks, implicit_devices, min_luks_entropy=0):
         :param min_luks_entropy: minimum entropy in bits required for
                                  luks format creation
         :type min_luks_entropy: int
+        :param requests: list of partitioning requests to operate on,
+                         or `~.storage.autoPartitionRequests` by default
+        :type requests: list of :class:`~.partspec.PartSpec` instances
         :returns: None
         :rtype: None
     """
+    if not requests:
+        requests = storage.autoPartitionRequests
+
     # basis for requests with requiredSpace is the sum of the sizes of the
     # two largest free regions
     all_free = (Size(reg.getLength(unit="B")) for reg in getFreeRegions(disks))
@@ -158,8 +164,8 @@ def _schedulePartitions(storage, disks, implicit_devices, min_luks_entropy=0):
     #
     # First pass is for partitions only. We'll do LVs later.
     #
-    for request in storage.autoPartitionRequests:
-        if ((request.lv and
+    for request in requests:
+        if ((request.lv and storage.doAutoPart and
              storage.autoPartType in (AUTOPART_TYPE_LVM,
                                       AUTOPART_TYPE_LVM_THINP)) or
             (request.btr and storage.autoPartType == AUTOPART_TYPE_BTRFS)):
@@ -236,7 +242,8 @@ def _schedulePartitions(storage, disks, implicit_devices, min_luks_entropy=0):
                                   parents=dev)
             storage.createDevice(luks_dev)
 
-        if storage.autoPartType in (AUTOPART_TYPE_LVM, AUTOPART_TYPE_LVM_THINP,
+        if storage.doAutoPart and \
+           storage.autoPartType in (AUTOPART_TYPE_LVM, AUTOPART_TYPE_LVM_THINP,
                                     AUTOPART_TYPE_BTRFS):
             # doing LVM/BTRFS -- make sure the newly created partition fits in some
             # free space together with one of the implicitly requested partitions
@@ -351,6 +358,27 @@ def _scheduleVolumes(storage, devs):
         # schedule the device for creation
         storage.createDevice(dev)
 
+def doReqPartition(storage, requests):
+    """Perform automatic partitioning of just required platform-specific
+       partitions.  This is incompatible with doAutoPartition.
+
+       :param storage: a :class:`~.Blivet` instance
+       :type storage: :class:`~.Blivet`
+       :param requests: list of partitioning requests to operate on,
+                        or `~.storage.autoPartitionRequests` by default
+       :type requests: list of :class:`~.partspec.PartSpec` instances
+    """
+    if not storage.partitioned:
+        raise NoDisksError(_("No usable disks selected"))
+
+    disks = getCandidateDisks(storage)
+
+    if disks == []:
+        raise NotEnoughFreeSpaceError(_("Not enough free space on disks for "
+                                      "automatic partitioning"))
+
+    schedulePartitions(storage, disks, [], requests=requests)
+
 def doAutoPartition(storage, data, min_luks_entropy=0):
     """ Perform automatic partitioning.
 
@@ -394,7 +422,7 @@ def doAutoPartition(storage, data, min_luks_entropy=0):
     if not storage.partitioned:
         raise NoDisksError(_("No usable disks selected"))
 
-    disks = _getCandidateDisks(storage)
+    disks = getCandidateDisks(storage)
     devs = _scheduleImplicitPartitions(storage, disks, min_luks_entropy)
     log.debug("candidate disks: %s", disks)
     log.debug("devs: %s", devs)
@@ -403,7 +431,7 @@ def doAutoPartition(storage, data, min_luks_entropy=0):
         raise NotEnoughFreeSpaceError(_("Not enough free space on disks for "
                                       "automatic partitioning"))
 
-    devs = _schedulePartitions(storage, disks, devs, min_luks_entropy=min_luks_entropy)
+    devs = schedulePartitions(storage, disks, devs, min_luks_entropy=min_luks_entropy)
 
     # run the autopart function to allocate and grow partitions
     doPartitioning(storage)
diff --git a/blivet/platform.py b/blivet/platform.py
index 310e96a..d08f9b2 100644
--- a/blivet/platform.py
+++ b/blivet/platform.py
@@ -152,11 +152,22 @@ class Platform(object):
             _packages.append('dracut-fips')
         return _packages
 
-    def setDefaultPartitioning(self):
-        """Return the default platform-specific partitioning information."""
+    def setPlatformBootloaderReqs(self):
+        """Return the required platform-specific bootloader partition
+           information.  These are typically partitions that do not get mounted,
+           like biosboot or prepboot, but may also include the /boot/efi
+           partition."""
+        return []
+
+    def setPlatformBootPartition(self):
+        """Return the default /boot partition for this platform."""
         return [PartSpec(mountpoint="/boot", size=Size("500MiB"),
                          weight=self.weight(mountpoint="/boot"))]
 
+    def setDefaultPartitioning(self):
+        """Return the default platform-specific partitioning information."""
+        return self.setPlatformBootloaderReqs() + self.setPlatformBootPartition()
+
     def weight(self, fstype=None, mountpoint=None):
         """ Given an fstype (as a string) or a mountpoint, return an integer
             for the base sorting weight.  This is used to modify the sort
@@ -190,9 +201,9 @@ class X86(Platform):
     def __init__(self):
         super(X86, self).__init__()
 
-    def setDefaultPartitioning(self):
+    def setPlatformBootloaderReqs(self):
         """Return the default platform-specific partitioning information."""
-        ret = Platform.setDefaultPartitioning(self)
+        ret = Platform.setPlatformBootloaderReqs(self)
         ret.append(PartSpec(fstype="biosboot", size=Size("1MiB"),
                             weight=self.weight(fstype="biosboot")))
         return ret
@@ -224,8 +235,8 @@ class EFI(Platform):
                                     "an EFI System Partition on a GPT-formatted "
                                     "disk, mounted at /boot/efi.")
 
-    def setDefaultPartitioning(self):
-        ret = Platform.setDefaultPartitioning(self)
+    def setPlatformBootloaderReqs(self):
+        ret = Platform.setPlatformBootloaderReqs(self)
         ret.append(PartSpec(mountpoint="/boot/efi", fstype="efi",
                             size=Size("20MiB"), maxSize=Size("200MiB"),
                             grow=True, weight=self.weight(fstype="efi")))
@@ -246,8 +257,8 @@ class MacEFI(EFI):
     _non_linux_format_types = ["macefi"]
     _packages = ["mactel-boot"]
 
-    def setDefaultPartitioning(self):
-        ret = Platform.setDefaultPartitioning(self)
+    def setPlatformBootloaderReqs(self):
+        ret = Platform.setPlatformBootloaderReqs(self)
         ret.append(PartSpec(mountpoint="/boot/efi", fstype="macefi",
                             size=Size("20MiB"), maxSize=Size("200MiB"),
                             grow=True, weight=self.weight(mountpoint="/boot/efi")))
@@ -274,8 +285,8 @@ class IPSeriesPPC(PPC):
                                     "within the first 4GiB of an MBR- "
                                     "or GPT-formatted disk.")
 
-    def setDefaultPartitioning(self):
-        ret = PPC.setDefaultPartitioning(self)
+    def setPlatformBootloaderReqs(self):
+        ret = PPC.setPlatformBootloaderReqs(self)
         ret.append(PartSpec(fstype="prepboot", size=Size("4MiB"),
                             weight=self.weight(fstype="prepboot")))
         return ret
@@ -299,8 +310,8 @@ class NewWorldPPC(PPC):
                                     "Partition on an Apple Partition Map-"
                                     "formatted disk.")
 
-    def setDefaultPartitioning(self):
-        ret = Platform.setDefaultPartitioning(self)
+    def setPlatformBootloaderReqs(self):
+        ret = Platform.setPlatformBootloaderReqs(self)
         ret.append(PartSpec(fstype="appleboot", size=Size("1MiB"),
                             weight=self.weight(fstype="appleboot")))
         return ret
@@ -334,10 +345,11 @@ class S390(Platform):
     def __init__(self):
         Platform.__init__(self)
 
-    def setDefaultPartitioning(self):
+    def setPlatformBootPartition(self):
         """Return the default platform-specific partitioning information."""
         return [PartSpec(mountpoint="/boot", size=Size("500MiB"),
                          weight=self.weight(mountpoint="/boot"), lv=False)]
+
     def requiredDiskLabelType(self, device_type):
         """The required disklabel type for the specified device type."""
         if device_type == parted.DEVICE_DASD:
@@ -380,12 +392,16 @@ class omapARM(ARM):
     _boot_stage1_missing_error = N_("You must include a U-Boot Partition on a "
                                     "FAT-formatted disk, mounted at /boot/uboot.")
 
-    def setDefaultPartitioning(self):
+    def setPlatformBootloaderReqs(self):
         """Return the ARM-OMAP platform-specific partitioning information."""
         ret = [PartSpec(mountpoint="/boot/uboot", fstype="vfat",
                         size=Size("20MiB"), maxSize=Size("200MiB"),
                         grow=True,
                         weight=self.weight(fstype="vfat", mountpoint="/boot/uboot"))]
+        return ret
+
+    def setDefaultPartitioning(self):
+        ret = ARM.setDefaultPartitioning(self)
         ret.append(PartSpec(mountpoint="/", fstype="ext4",
                             size=Size("2GiB"), maxSize=Size("3GiB"),
                             weight=self.weight(mountpoint="/")))
-- 
2.2.2



More information about the anaconda-patches mailing list