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

[PATCH] Allow autopart without lvm.



---
 data/ui/autopart.glade             |   49 +++++++++++++++++++++++---
 pyanaconda/installclass.py         |    7 ++--
 pyanaconda/iw/autopart_type.py     |    8 ++++
 pyanaconda/storage/__init__.py     |    1 +
 pyanaconda/storage/partitioning.py |   67 ++++++++++++++++++++++++++++++------
 pyanaconda/storage/partspec.py     |   10 ++++--
 6 files changed, 120 insertions(+), 22 deletions(-)

diff --git a/data/ui/autopart.glade b/data/ui/autopart.glade
index ce41778..b1346f6 100644
--- a/data/ui/autopart.glade
+++ b/data/ui/autopart.glade
@@ -24,7 +24,7 @@
   <child>
     <widget class="GtkTable" id="parttypeTable">
       <property name="visible">True</property>
-      <property name="n_rows">4</property>
+      <property name="n_rows">5</property>
       <property name="n_columns">1</property>
       <property name="homogeneous">False</property>
       <property name="row_spacing">0</property>
@@ -59,6 +59,45 @@
       </child>
 
       <child>
+	<widget class="GtkHBox" id="hbox3">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkCheckButton" id="lvmButton">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">Use _LVM</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <placeholder/>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">1</property>
+	  <property name="top_attach">2</property>
+	  <property name="bottom_attach">3</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options">fill</property>
+	</packing>
+      </child>
+
+      <child>
 	<widget class="GtkHBox" id="hbox5">
 	  <property name="visible">True</property>
 	  <property name="homogeneous">False</property>
@@ -90,8 +129,8 @@
 	<packing>
 	  <property name="left_attach">0</property>
 	  <property name="right_attach">1</property>
-	  <property name="top_attach">2</property>
-	  <property name="bottom_attach">3</property>
+	  <property name="top_attach">3</property>
+	  <property name="bottom_attach">4</property>
 	  <property name="x_options">fill</property>
 	  <property name="y_options">fill</property>
 	</packing>
@@ -127,8 +166,8 @@
 	<packing>
 	  <property name="left_attach">0</property>
 	  <property name="right_attach">1</property>
-	  <property name="top_attach">3</property>
-	  <property name="bottom_attach">4</property>
+	  <property name="top_attach">4</property>
+	  <property name="bottom_attach">5</property>
 	  <property name="x_options">fill</property>
 	  <property name="y_options">fill</property>
 	</packing>
diff --git a/pyanaconda/installclass.py b/pyanaconda/installclass.py
index 0819b6b..440b97c 100644
--- a/pyanaconda/installclass.py
+++ b/pyanaconda/installclass.py
@@ -175,9 +175,10 @@ class BaseInstallClass(object):
     def setDefaultPartitioning(self, storage, platform):
         autorequests = [PartSpec(mountpoint="/", fstype=storage.defaultFSType,
                                  size=1024, maxSize=50*1024, grow=True,
-                                 asVol=True),
+                                 asVol=True, encrypted=True),
                         PartSpec(mountpoint="/home", fstype=storage.defaultFSType,
-                                 size=100, grow=True, asVol=True, requiredSpace=50*1024)]
+                                 size=100, grow=True, requiredSpace=50*1024,
+                                 asVol=True, encrypted=True)]
 
         bootreq = platform.setDefaultPartitioning()
         if bootreq:
@@ -185,7 +186,7 @@ class BaseInstallClass(object):
 
         (minswap, maxswap) = iutil.swapSuggestion()
         autorequests.append(PartSpec(fstype="swap", size=minswap, maxSize=maxswap,
-                                     grow=True, asVol=True))
+                                     grow=True, asVol=True, encrypted=True))
 
         storage.autoPartitionRequests = autorequests
 
diff --git a/pyanaconda/iw/autopart_type.py b/pyanaconda/iw/autopart_type.py
index 6eef3ac..c50ba49 100644
--- a/pyanaconda/iw/autopart_type.py
+++ b/pyanaconda/iw/autopart_type.py
@@ -186,6 +186,11 @@ class PartitionTypeWindow(InstallWindow):
 
             self.dispatch.request_steps("autopartitionexecute", "cleardiskssel")
 
+            if self.lvmButton.get_active():
+                self.storage.lvmAutoPart = True
+            else:
+                self.storage.lvmAutoPart = False
+
             if self.encryptButton.get_active():
                 self.storage.encryptedAutoPart = True
             else:
@@ -241,11 +246,13 @@ class PartitionTypeWindow(InstallWindow):
         (self.xml, vbox) = gui.getGladeWidget("autopart.glade", "parttypeTable")
         self.encryptButton = self.xml.get_widget("encryptButton")
         self.reviewButton = self.xml.get_widget("reviewButton")
+        self.lvmButton = self.xml.get_widget("lvmButton")
         self.table = self.xml.get_widget("parttypeTable")
 
         self.prevrev = None
         self.reviewButton.set_active(self.dispatch.step_enabled("partition"))
         self.encryptButton.set_active(self.storage.encryptedAutoPart)
+        self.lvmButton.set_active(self.storage.lvmAutoPart)
 
         self.buttonGroup = pixmapRadioButtonGroup()
         self.buttonGroup.addEntry("all", _("Use _All Space"),
@@ -306,5 +313,6 @@ class PartitionTypeWindow(InstallWindow):
             self.reviewButton.set_active(True)
             self.reviewButton.set_sensitive(False)
             self.encryptButton.set_sensitive(False)
+            self.lvmButton.set_sensitive(False)
 
         return vbox
diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py
index a2bfc12..74bcfb1 100644
--- a/pyanaconda/storage/__init__.py
+++ b/pyanaconda/storage/__init__.py
@@ -349,6 +349,7 @@ class Storage(object):
         self.doAutoPart = False
         self.clearPartChoice = None
         self.encryptedAutoPart = False
+        self.lvmAutoPart = False
         self.encryptionPassphrase = None
         self.escrowCertificates = {}
         self.autoPartEscrowCert = None
diff --git a/pyanaconda/storage/partitioning.py b/pyanaconda/storage/partitioning.py
index 25aa169..6cb9c92 100644
--- a/pyanaconda/storage/partitioning.py
+++ b/pyanaconda/storage/partitioning.py
@@ -40,9 +40,8 @@ _ = lambda x: gettext.ldgettext("anaconda", x)
 import logging
 log = logging.getLogger("storage")
 
-def _createFreeSpacePartitions(storage):
-    # get a list of disks that have at least one free space region of at
-    # least the default size for new partitions
+def _getCandidateDisks(storage):
+    """ Return a list of disks with space for a default-sized partition. """
     disks = []
     for disk in storage.partitioned:
         if storage.config.clearPartDisks and \
@@ -61,8 +60,17 @@ def _createFreeSpacePartitions(storage):
 
             part = part.nextPartition()
 
+    return disks
+
+def _schedulePVs(storage, disks):
+    """ Schedule creation of an lvm pv partition on each disk in disks. """
     # create a separate pv partition for each disk with free space
     devs = []
+
+    # only schedule PVs if there are LV autopart reqs
+    if not storage.lvmAutoPart:
+        return devs
+
     for disk in disks:
         if storage.encryptedAutoPart:
             fmt_type = "luks"
@@ -78,17 +86,32 @@ def _createFreeSpacePartitions(storage):
         storage.createDevice(part)
         devs.append(part)
 
-    return (disks, devs)
+    return devs
 
 def _schedulePartitions(storage, disks):
-    #
-    # Convert storage.autoPartitionRequests into Device instances and
-    # schedule them for creation
+    """ Schedule creation of autopart partitions. """
+    # basis for requests with requiredSpace is the sum of the sizes of the
+    # two largest free regions
+    all_free = getFreeRegions(disks)
+    all_free.sort(key=lambda f: f.length, reverse=True)
+    if not all_free:
+        # this should never happen since we've already filtered the disks
+        # to those with at least 500MB free
+        log.error("no free space on disks %s" % ([d.name for d in disks],))
+        return
+
+    free = all_free[0].getSize()
+    if len(all_free) > 1:
+        free += all_free[1].getSize()
+
     #
     # First pass is for partitions only. We'll do LVs later.
     #
     for request in storage.autoPartitionRequests:
-        if request.asVol:
+        if request.asVol and storage.lvmAutoPart:
+            continue
+
+        if request.requiredSpace and request.requiredSpace > free:
             continue
 
         if request.fstype is None:
@@ -119,7 +142,12 @@ def _schedulePartitions(storage, disks):
         if request.mountpoint == "/" and storage.liveImage:
             request.fstype = storage.liveImage.format.type
 
-        dev = storage.newPartition(fmt_type=request.fstype,
+        if request.encrypted and storage.encryptedAutoPart:
+            fstype = "luks"
+        else:
+            fstype = request.fstype
+
+        dev = storage.newPartition(fmt_type=fstype,
                                             size=request.size,
                                             grow=request.grow,
                                             maxsize=request.maxSize,
@@ -130,10 +158,24 @@ def _schedulePartitions(storage, disks):
         # schedule the device for creation
         storage.createDevice(dev)
 
+        if request.encrypted and storage.encryptedAutoPart:
+            luks_fmt = getFormat(request.fstype,
+                                 device=dev.path,
+                                 mountpoint=request.mountpoint)
+            luks_dev = LUKSDevice("luks-%s" % dev.name,
+                                  format=luks_fmt,
+                                  size=dev.size,
+                                  parents=dev)
+            storage.createDevice(luks_dev)
+
     # make sure preexisting broken lvm/raid configs get out of the way
     return
 
 def _scheduleLVs(storage, devs):
+    """ Schedule creation of autopart lvm lvs. """
+    if not devs:
+        return
+
     if storage.encryptedAutoPart:
         pvs = []
         for dev in devs:
@@ -158,7 +200,7 @@ def _scheduleLVs(storage, devs):
     #
     # Second pass, for LVs only.
     for request in storage.autoPartitionRequests:
-        if not request.asVol:
+        if not request.asVol or not storage.lvmAutoPart:
             continue
 
         if request.requiredSpace and request.requiredSpace > initialVGSize:
@@ -188,6 +230,8 @@ def _scheduleLVs(storage, devs):
 def doAutoPartition(anaconda):
     log.debug("doAutoPartition(%s)" % anaconda)
     log.debug("doAutoPart: %s" % anaconda.storage.doAutoPart)
+    log.debug("encryptedAutoPart: %s" % anaconda.storage.encryptedAutoPart)
+    log.debug("lvmAutoPart: %s" % anaconda.storage.lvmAutoPart)
     log.debug("clearPartType: %s" % anaconda.storage.config.clearPartType)
     log.debug("clearPartDisks: %s" % anaconda.storage.config.clearPartDisks)
     log.debug("autoPartitionRequests: %s" % anaconda.storage.autoPartitionRequests)
@@ -208,7 +252,8 @@ def doAutoPartition(anaconda):
         anaconda.bootloader.clear_drive_list()
 
     if anaconda.storage.doAutoPart:
-        (disks, devs) = _createFreeSpacePartitions(anaconda.storage)
+        disks = _getCandidateDisks(anaconda.storage)
+        devs = _schedulePVs(anaconda.storage, disks)
 
         if disks == []:
             if anaconda.ksdata:
diff --git a/pyanaconda/storage/partspec.py b/pyanaconda/storage/partspec.py
index a126c3f..1602b8a 100644
--- a/pyanaconda/storage/partspec.py
+++ b/pyanaconda/storage/partspec.py
@@ -22,7 +22,7 @@
 class PartSpec(object):
     def __init__(self, mountpoint=None, fstype=None, size=None, maxSize=None,
                  grow=False, asVol=False, singlePV=False, weight=0,
-                 requiredSpace=0):
+                 requiredSpace=0, encrypted=False):
         """ Create a new storage specification.  These are used to specify
             the default partitioning layout as an object before we have the
             storage system up and running.  The attributes are obvious
@@ -45,6 +45,9 @@ class PartSpec(object):
                              other LVs are created inside it.  If not enough
                              space exists, this PartSpec will never get turned
                              into an LV.
+            encrypted -- Should this request be encrypted? For logical volume
+                         requests, this is satisfied if the PVs are encrypted
+                         as in the case of encrypted LVM autopart.
         """
 
         self.mountpoint = mountpoint
@@ -56,6 +59,7 @@ class PartSpec(object):
         self.singlePV = singlePV
         self.weight = weight
         self.requiredSpace = requiredSpace
+        self.encrypted = encrypted
 
         if self.singlePV and not self.asVol:
             self.asVol = True
@@ -63,12 +67,12 @@ class PartSpec(object):
     def __str__(self):
         s = ("%(type)s instance (%(id)s) -- \n"
              "  mountpoint = %(mountpoint)s  asVol = %(asVol)s  singlePV = %(singlePV)s\n"
-             "  weight = %(weight)s  fstype = %(fstype)s\n"
+             "  weight = %(weight)s  fstype = %(fstype)s  encrypted = %(enc)s\n"
              "  size = %(size)s  maxSize = %(maxSize)s  grow = %(grow)s\n" %
              {"type": self.__class__.__name__, "id": "%#x" % id(self),
               "mountpoint": self.mountpoint, "asVol": self.asVol,
               "singlePV": self.singlePV, "weight": self.weight,
-              "fstype": self.fstype, "size": self.size,
+              "fstype": self.fstype, "size": self.size, "enc": self.encrypted,
               "maxSize": self.maxSize, "grow": self.grow})
 
         return s
-- 
1.7.3.4


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