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

[PATCH 7/7] Convert livecd.py to use the storage module where appropriate.



Removes rootFsType from AnacondaBackend since it was really only
there for livecd anyhow. Now the livecd-specific code scattered
throughout storage will be slightly easier to identify.

Removes the extra check of root device size from
LiveCDCopyBackend.doBackendSetup. We already do that in
Storage.sanityCheck.
---
 pyanaconda/backend.py              |    1 -
 pyanaconda/livecd.py               |  101 +++++-------------------------------
 pyanaconda/storage/__init__.py     |   23 ++++++--
 pyanaconda/storage/formats/fs.py   |   28 ++++++++++
 pyanaconda/storage/partitioning.py |    8 ++--
 5 files changed, 63 insertions(+), 98 deletions(-)

diff --git a/pyanaconda/backend.py b/pyanaconda/backend.py
index 6d8ea1c..1f4a8b2 100644
--- a/pyanaconda/backend.py
+++ b/pyanaconda/backend.py
@@ -55,7 +55,6 @@ class AnacondaBackend:
         # some backends may have a special case for rootfs formatting
         # FIXME: we should handle this a little more elegantly
         self.skipFormatRoot = False
-        self.rootFsType = None
 
     def postAction(self, anaconda):
         pass
diff --git a/pyanaconda/livecd.py b/pyanaconda/livecd.py
index 54fb7c3..d2f1165 100644
--- a/pyanaconda/livecd.py
+++ b/pyanaconda/livecd.py
@@ -116,8 +116,8 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
         self.supportsPackageSelection = False
         self.skipFormatRoot = True
 
-        self.osimg = anaconda.methodstr[8:]
-        if not stat.S_ISBLK(os.stat(self.osimg)[stat.ST_MODE]):
+        osimg_path = anaconda.methodstr[9:]
+        if not stat.S_ISBLK(os.stat(osimg_path)[stat.ST_MODE]):
             anaconda.intf.messageWindow(_("Unable to find image"),
                                _("The given location isn't a valid %s "
                                  "live CD to use as an installation source.")
@@ -125,28 +125,6 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
                                custom_icon="error",
                                custom_buttons=[_("Exit installer")])
             sys.exit(0)
-        self.rootFsType = isys.readFSType(self.osimg)
-
-    def _getLiveBlockDevice(self):
-        return os.path.normpath(self.osimg)
-
-    def _getLiveSize(self):
-        def parseField(output, field):
-            for line in output.split("\n"):
-                if line.startswith(field + ":"):
-                    return line[len(field) + 1:].strip()
-            raise KeyError("Failed to find field '%s' in output" % field)
-
-        output = subprocess.Popen(['/sbin/dumpe2fs', '-h', self.osimg],
-                                  stdout=subprocess.PIPE,
-                                  stderr=open('/dev/null', 'w')
-                                  ).communicate()[0]
-        blkcnt = int(parseField(output, "Block count"))
-        blksize = int(parseField(output, "Block size"))
-        return blkcnt * blksize
-
-    def _getLiveSizeMB(self):
-        return self._getLiveSize() / 1048576
 
     def postAction(self, anaconda):
         try:
@@ -165,15 +143,14 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
         progress.set_label(_("Copying live image to hard drive."))
         progress.processEvents()
 
-        osimg = self._getLiveBlockDevice() # the real image
-        osfd = os.open(osimg, os.O_RDONLY)
+        osfd = os.open(self.anaconda.storage.liveImage.path, os.O_RDONLY)
 
         rootDevice = anaconda.storage.rootDevice
         rootDevice.setup()
         rootfd = os.open(rootDevice.path, os.O_WRONLY)
 
         readamt = 1024 * 1024 * 8 # 8 megs at a time
-        size = self._getLiveSize()
+        size = self.anaconda.storage.liveImage.format.currentSize * 1024 * 1024
         copied = 0
         while copied < size:
             try:
@@ -214,22 +191,17 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
                                         _("Performing post-installation filesystem changes.  This may take several minutes."))
 
         # resize rootfs first, since it is 100% full due to genMinInstDelta
-        self._resizeRootfs(anaconda, wait)
+        rootDevice = anaconda.storage.rootDevice
+        rootDevice.setup()
+        rootDevice.format.targetSize = rootDevice.format.minSize
+        rootDevice.format.doResize(intf=anaconda.intf)
+
+        # ensure we have a random UUID on the rootfs
+        rootDevice.format.writeRandomUUID()
 
         # remount filesystems
         anaconda.storage.mountFilesystems()
 
-        # restore the label of / to what we think it is
-        rootDevice = anaconda.storage.rootDevice
-        rootDevice.setup()
-        # ensure we have a random UUID on the rootfs
-        # FIXME: this should be abstracted per filesystem type
-        iutil.execWithRedirect("tune2fs",
-                               ["-U",
-                                "random",
-                                rootDevice.path],
-                               stdout="/dev/tty5",
-                               stderr="/dev/tty5")
         # and now set the uuid in the storage layer
         rootDevice.updateSysfsPath()
         iutil.notify_kernel("/sys%s" %rootDevice.sysfsPath)
@@ -337,36 +309,6 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
 
         wait.pop()
 
-    def _resizeRootfs(self, anaconda, win = None):
-        log.info("going to do resize")
-        rootDevice = anaconda.storage.rootDevice
-
-        # FIXME: we'd like to have progress here to give an idea of
-        # how long it will take.  or at least, to give an indefinite
-        # progress window.  but, not for this time
-        cmd = ["resize2fs", rootDevice.path, "-p"]
-        out = open("/dev/tty5", "w")
-        proc = subprocess.Popen(cmd, stdout=out, stderr=out)
-        rc = proc.poll()
-        while rc is None:
-            win and win.refresh()
-            time.sleep(0.5)
-            rc = proc.poll()
-
-        if rc:
-            log.error("error running resize2fs; leaving filesystem as is")
-            return
-
-        # we should also do a fsck afterwards
-        cmd = ["e2fsck", "-f", "-y", rootDevice.path]
-        out = open("/dev/tty5", "w")
-        proc = subprocess.Popen(cmd, stdout=out, stderr=out)
-        rc = proc.poll()
-        while rc is None:
-            win and win.refresh()
-            time.sleep(0.5)
-            rc = proc.poll()
-
     def doPostInstall(self, anaconda):
         import rpm
 
@@ -402,28 +344,11 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
 
     def getMinimumSizeMB(self, part):
         if part == "/":
-            return self._getLiveSizeMB()
+            return self.anaconda.storage.liveImage.format.size
         return 0
 
     def doBackendSetup(self, anaconda):
-        # ensure there's enough space on the rootfs
-        # FIXME: really, this should be in the general sanity checking, but
-        # trying to weave that in is a little tricky at present.
-        ossize = self._getLiveSizeMB()
-        slash = anaconda.storage.rootDevice
-        if slash.size < ossize:
-            rc = anaconda.intf.messageWindow(_("Error"),
-                                        _("The root filesystem you created is "
-                                          "not large enough for this live "
-                                          "image (%.2f MB required).") % ossize,
-                                        type = "custom",
-                                        custom_icon = "error",
-                                        custom_buttons=[_("_Back"),
-                                                        _("_Exit installer")])
-            if rc == 0:
-                return DISPATCH_BACK
-            else:
-                sys.exit(1)
+        pass
 
     # package/group selection doesn't apply for this backend
     def groupExists(self, group):
diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py
index bf74f88..1531685 100644
--- a/pyanaconda/storage/__init__.py
+++ b/pyanaconda/storage/__init__.py
@@ -616,6 +616,14 @@ class Storage(object):
         protected.sort(key=lambda d: d.name)
         return protected
 
+    @property
+    def liveImage(self):
+        """ The OS image used by live installs. """
+        _image = None
+        if flags.livecdInstall:
+            _image = self.devicetree.getDeviceByPath(self.anaconda.methodstr[9:])
+        return _image
+
     def exceptionDisks(self):
         """ Return a list of removable devices to save exceptions to.
 
@@ -1001,20 +1009,25 @@ class Storage(object):
 
         if (root and
             root.size < self.anaconda.backend.getMinimumSizeMB("/")):
+            if flags.livecdInstall:
+                live = " Live"
+            else:
+                live = ""
             errors.append(_("Your / partition is less than %(min)s "
                             "MB which is lower than recommended "
-                            "for a normal %(productName)s install.")
+                            "for a normal %(productName)s%(live)s install.")
                           % {'min': self.anaconda.backend.getMinimumSizeMB("/"),
-                             'productName': productName})
+                             'productName': productName,
+                             'live': live})
 
         # livecds have to have the rootfs type match up
         if (root and
-            self.anaconda.backend.rootFsType and
-            root.format.type != self.anaconda.backend.rootFsType):
+            self.liveImage and
+            root.format.type != self.liveImage.format.type):
             errors.append(_("Your / partition does not match the "
                             "the live image you are installing from.  "
                             "It must be formatted as %s.")
-                          % (self.anaconda.backend.rootFsType,))
+                          % (self.liveImage.format.type,))
 
         for (mount, size) in checkSizes:
             if mount in filesystems and filesystems[mount].size < size:
diff --git a/pyanaconda/storage/formats/fs.py b/pyanaconda/storage/formats/fs.py
index f055ce2..1095139 100644
--- a/pyanaconda/storage/formats/fs.py
+++ b/pyanaconda/storage/formats/fs.py
@@ -682,6 +682,13 @@ class FS(DeviceFormat):
         self.label = label
         self.notifyKernel()
 
+    def _getRandomUUID(self):
+        uuid = iutil.execWithCapture("uuidgen").strip()
+        return uuid
+
+    def writeRandomUUID(self):
+        raise NotImplementedError("FS does not implement writeRandomUUID")
+
     @property
     def isDirty(self):
         return False
@@ -947,6 +954,27 @@ class Ext2FS(FS):
         except Exception as e:
             log.error("failed to run tune2fs on %s: %s" % (self.device, e))
 
+    def writeRandomUUID(self):
+        if not self.exists:
+            raise FSError("filesystem does not exist")
+
+        err = None
+        try:
+            rc = iutil.execWithRedirect("tune2fs",
+                                        ["-U",
+                                         "random",
+                                         self.device],
+                                        stdout="/dev/tty5",
+                                        stderr="/dev/tty5")
+        except Exception as e:
+            err = str(e)
+        else:
+            if rc:
+                err = rc
+
+        if err:
+            raise FSError("failed to set UUID for %s: %s" % (self.device, err))
+
     @property
     def minSize(self):
         """ Minimum size for this filesystem in MB. """
diff --git a/pyanaconda/storage/partitioning.py b/pyanaconda/storage/partitioning.py
index 85af948..2c6f30a 100644
--- a/pyanaconda/storage/partitioning.py
+++ b/pyanaconda/storage/partitioning.py
@@ -99,8 +99,8 @@ def _schedulePartitions(anaconda, disks):
 
         # This is a little unfortunate but let the backend dictate the rootfstype
         # so that things like live installs can do the right thing
-        if request.mountpoint == "/" and anaconda.backend.rootFsType != None:
-            request.fstype = anaconda.backend.rootFsType
+        if request.mountpoint == "/" and anaconda.storage.liveImage:
+            request.fstype = anaconda.storage.liveImage.format.type
 
         dev = anaconda.storage.newPartition(fmt_type=request.fstype,
                                             size=request.size,
@@ -152,8 +152,8 @@ def _scheduleLVs(anaconda, devs):
 
         # This is a little unfortunate but let the backend dictate the rootfstype
         # so that things like live installs can do the right thing
-        if request.mountpoint == "/" and anaconda.backend.rootFsType != None:
-            request.fstype = anaconda.backend.rootFsType
+        if request.mountpoint == "/" and anaconda.storage.liveImage:
+            request.fstype = anaconda.storage.liveImage.format.type
 
         # FIXME: move this to a function and handle exceptions
         dev = anaconda.storage.newLV(vg=vg,
-- 
1.7.3.3


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