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

[PATCH 3/8] Add support for cdrom and harddrive methods, including switching.



Clean up mountImage and opticalInstallMedia to match their new surroundings.

Allow a path to a specific image file to be specified to mountImage.

Don't automatically mount optical media we detect in opticalInstallMedia.
---
 pyanaconda/image.py                |   23 +++++---
 pyanaconda/install.py              |    1 +
 pyanaconda/packaging/__init__.py   |   21 +++++++-
 pyanaconda/packaging/yumpayload.py |   98 +++++++++++++++++++++++++----------
 pyanaconda/ui/gui/spokes/source.py |   22 +++++++--
 5 files changed, 121 insertions(+), 44 deletions(-)

diff --git a/pyanaconda/image.py b/pyanaconda/image.py
index 4af7973..009e38a 100644
--- a/pyanaconda/image.py
+++ b/pyanaconda/image.py
@@ -152,17 +152,21 @@ def mountImageDirectory(method, storage):
                 if errorHandler.cb(exn) == ERROR_RAISE:
                     raise exn
 
-def mountImage(isodir, tree, messageWindow):
+def mountImage(isodir, tree):
     while True:
-        image = findFirstIsoImage(isodir, messageWindow)
-        if image is None:
-            exn = MissingImageError()
-            if errorHandler.cb(exn) == ERROR_RAISE:
-                raise exn
-            else:
-                continue
+        if os.path.isfile(isodir):
+            image = isodir
+        else:
+            image = findFirstIsoImage(isodir)
+            if image is None:
+                exn = MissingImageError()
+                if errorHandler.cb(exn) == ERROR_RAISE:
+                    raise exn
+                else:
+                    continue
+
+            image = os.path.normpath("%s/%s" % (isodir, image))
 
-        image = os.path.normpath("%s/%s" % (isodir, image))
         try:
             isys.mount(image, tree, fstype = 'iso9660', readOnly = True)
         except SystemError:
@@ -190,6 +194,7 @@ def opticalInstallMedia(devicetree, mountpoint=INSTALL_TREE):
             dev.format.unmount()
             continue
 
+        dev.format.unmount()
         retval = dev
         break
 
diff --git a/pyanaconda/install.py b/pyanaconda/install.py
index 86ae076..00a517c 100644
--- a/pyanaconda/install.py
+++ b/pyanaconda/install.py
@@ -63,6 +63,7 @@ def doInstall(storage, payload, ksdata, instClass):
     progress.send_init(steps)
 
     # Do partitioning.
+    payload.preStorage()
     turnOnFilesystems(storage)
 
     # Do packaging.
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py
index 9b8f94e..8b56268 100644
--- a/pyanaconda/packaging/__init__.py
+++ b/pyanaconda/packaging/__init__.py
@@ -411,7 +411,11 @@ class Payload(object):
             if mdev == device.path:
                 return
             else:
-                log.info("mounting on top of it")
+                try:
+                    isys.umount(mountpoint, removeDir=False)
+                except Exception as e:
+                    log.error(str(e))
+                    log.info("umount failed -- mounting on top of it")
 
         try:
             device.setup()
@@ -427,8 +431,19 @@ class Payload(object):
         """ Prepare an NFS directory for use as a package source. """
         log.info("mounting %s:%s:%s on %s" % (server, path, options, mountpoint))
         if os.path.ismount(mountpoint):
-            log.debug("%s already has something mounted on it" % mountpoint)
-            return
+            dev = get_mount_device(mountpoint)
+            _server, colon, _path = dev.partition(":")
+            if colon == ":" and server == _server and path == _path:
+                log.debug("%s:%s already mounted on %s" % (server, path,
+                                                           mountpoint))
+                return
+            else:
+                log.debug("%s already has something mounted on it" % mountpoint)
+                try:
+                    isys.umount(mountpoint, removeDir=False)
+                except Exception as e:
+                    log.error(str(e))
+                    log.info("umount failed -- mounting on top of it")
 
         # mount the specified directory
         url = "%s:%s" % (server, path)
diff --git a/pyanaconda/packaging/yumpayload.py b/pyanaconda/packaging/yumpayload.py
index 852a882..e948da7 100644
--- a/pyanaconda/packaging/yumpayload.py
+++ b/pyanaconda/packaging/yumpayload.py
@@ -111,17 +111,26 @@ class YumPayload(PackagePayload):
         """ Reset this instance to its initial (unconfigured) state. """
         from pyanaconda.storage.size import Size
 
+        """
+            cdrom: install_device.teardown (INSTALL_TREE)
+            hd: umount INSTALL_TREE, install_device.teardown (ISO_DIR)
+            nfs: umount INSTALL_TREE
+            nfsiso: umount INSTALL_TREE, umount ISO_DIR
+        """
         if os.path.ismount(INSTALL_TREE) and not flags.testing:
-            isys.umount(INSTALL_TREE)
-
-        if os.path.islink(INSTALL_TREE):
-            os.unlink(INSTALL_TREE)
+            if self.install_device and \
+               get_mount_device(INSTALL_TREE) == self.install_device.path:
+                self.install_device.teardown(recursive=True)
+            else:
+                isys.umount(INSTALL_TREE, removeDir=False)
 
         if os.path.ismount(ISO_DIR) and not flags.testing:
-            isys.umount(INSTALL_TREE)
-
-        if self.install_device:
-            self.install_device.teardown(recursive=True)
+            if self.install_device and \
+               get_mount_device(ISO_DIR) == self.install_device.path:
+                self.install_device.teardown(recursive=True)
+            else:
+                # NFS
+                isys.umount(ISO_DIR, removeDir=False)
 
         self.install_device = None
 
@@ -283,6 +292,11 @@ reposdir=%s
         for repo in self._yum.repos.repos.values():
             repo._sack = None
 
+    def preStorage(self):
+        self._yum.close()
+        if os.path.ismount(INSTALL_TREE):
+            isys.umount(INSTALL_TREE, removeDir=False)
+
     ###
     ### METHODS FOR WORKING WITH REPOSITORIES
     ###
@@ -407,6 +421,48 @@ reposdir=%s
 
         log.info("metadata retrieval complete")
 
+    @property
+    def ISOImage(self):
+        if self.data.method.method == "harddrive":
+            return get_mount_device(INSTALL_TREE)[len(ISO_DIR)+1:]
+
+    def _setUpMedia(self, device):
+        method = self.data.method
+        if method.method == "harddrive":
+            self._setupDevice(device, mountpoint=ISO_DIR)
+
+            # check for ISO images in the newly mounted dir
+            path = ISO_DIR
+            if method.dir:
+                path = os.path.normpath("%s/%s" % (path, method.dir))
+
+            # XXX it would be nice to streamline this when we're just setting
+            #     things back up after storage activation instead of having to
+            #     pretend we don't already know which ISO image we're going to
+            #     use
+            image = findFirstIsoImage(path)
+            if not image:
+                device.teardown(recursive=True)
+                raise PayloadSetupError("failed to find valid iso image")
+
+            if path.endswith(".iso"):
+                path = os.path.dirname(path)
+
+            # this could already be set up the first time through
+            if not os.path.ismount(INSTALL_TREE):
+                # mount the ISO on a loop
+                image = os.path.normpath("%s/%s" % (path, image))
+                mountImage(image, INSTALL_TREE)
+
+            if not method.dir.endswith(".iso"):
+                method.dir = os.path.normpath("%s/%s" % (method.dir,
+                                                         os.path.basename(image)))
+                while method.dir.startswith("/"):
+                    # riduculous
+                    method.dir = method.dir[1:]
+        else:
+            device.format.setup(mountpoint=INSTALL_TREE)
+
     def _configureBaseRepo(self, storage):
         """ Configure the base repo.
 
@@ -434,25 +490,7 @@ reposdir=%s
 
             # FIXME: teach DeviceTree.resolveDevice about biospart
             device = storage.devicetree.resolveDevice(devspec)
-            self._setupDevice(device, mountpoint=ISO_DIR)
-
-            # check for ISO images in the newly mounted dir
-            path = ISO_DIR
-            if method.dir:
-                path = os.path.normpath("%s/%s" % (path, method.dir))
-
-            image = findFirstIsoImage(path)
-            if not image:
-                device.teardown(recursive=True)
-                raise PayloadSetupError("failed to find valid iso image")
-
-            if path.endswith(".iso"):
-                path = os.path.dirname(path)
-
-            # mount the ISO on a loop
-            image = os.path.normpath("%s/%s" % (path, image))
-            mountImage(image, INSTALL_TREE)
-
+            self._setUpMedia(device)
             self.install_device = device
             url = "file://" + INSTALL_TREE
         elif method.method == "nfs":
@@ -489,6 +527,7 @@ reposdir=%s
             # cdrom or no method specified -- check for media
             device = opticalInstallMedia(storage.devicetree)
             if device:
+                self._setUpMedia(device)
                 self.install_device = device
                 url = "file://" + INSTALL_TREE
                 if not method.method:
@@ -617,7 +656,7 @@ reposdir=%s
 
         if mountpoint and os.path.ismount(mountpoint):
             try:
-                isys.umount(mountpoint)
+                isys.umount(mountpoint, removeDir=False)
             except SystemError as e:
                 log.error("failed to unmount nfs repo %s: %s" % (mountpoint, e))
 
@@ -873,6 +912,9 @@ reposdir=%s
         super(YumPayload, self).preInstall(packages=packages)
         progress.send_message(_("Starting package installation process"))
 
+        if self.install_device:
+            self._setUpMedia(self.install_device)
+
         self._writeInstallConfig()
         self.checkSoftwareSelection()
 
diff --git a/pyanaconda/ui/gui/spokes/source.py b/pyanaconda/ui/gui/spokes/source.py
index 64f109d..f127042 100644
--- a/pyanaconda/ui/gui/spokes/source.py
+++ b/pyanaconda/ui/gui/spokes/source.py
@@ -203,6 +203,7 @@ class IsoChooser(UIObject):
     def run(self, dev):
         retval = None
 
+        unmount = not dev.format.status
         dev.format.mount(mountpoint=MOUNTPOINT)
 
         # If any directory was chosen, return that.  Otherwise, return None.
@@ -212,7 +213,8 @@ class IsoChooser(UIObject):
             if f:
                 retval = f.replace(MOUNTPOINT, "")
 
-        dev.format.unmount()
+        if unmount:
+            dev.format.unmount()
 
         self.window.destroy()
         return retval
@@ -360,6 +362,8 @@ class SourceSpoke(NormalSpoke):
 
     @property
     def status(self):
+        if not self.ready:
+            return _("Not ready")
         if self.data.method.method == "url":
             return self.data.method.url
         elif self.data.method.method == "nfs":
@@ -447,6 +451,9 @@ class SourceSpoke(NormalSpoke):
                 self._autodetectMediaBox.pack_start(selector, False, False, 0)
                 added = True
 
+            if self.data.method.method == "harddrive":
+                self._currentIsoFile = self.payload.ISOImage
+
             # These UI elements default to not being showable.  If optical install
             # media were found, mark them to be shown.
             if added:
@@ -458,16 +465,21 @@ class SourceSpoke(NormalSpoke):
             store = self.builder.get_object("partitionStore")
 
             added = False
+            active = 0
+            idx = 0
             for dev in potentialHdisoSources(self.storage.devicetree):
                 store.append([dev, "%s (%s MB)" % (self._sanitize_model(dev.disk.model), int(dev.size))])
+                if dev.name == self.data.method.partition:
+                    active = idx
                 added = True
+                idx += 1
 
             # Again, only display these widgets if an HDISO source was found.
             if added:
                 self._isoBox.set_no_show_all(False)
                 self._isoButton.set_no_show_all(False)
                 combo = self.builder.get_object("isoPartitionCombo")
-                combo.set_active(0)
+                combo.set_active(active)
 
             # Add the mirror manager URL in as the default for HTTP and HTTPS.
             # We'll override this later in the refresh() method, if they've already
@@ -511,7 +523,7 @@ class SourceSpoke(NormalSpoke):
         elif self.data.method.method == "harddrive":
             self._isoButton.set_active(True)
 
-            self._isoChooserButton.set_label(os.path.basename(self.data.method.dir))
+            self._isoChooserButton.set_label(os.path.basename(self._currentIsoFile))
             self._isoChooserButton.set_use_underline(False)
         else:
             # No method was given in advance, so now we need to make a sensible
@@ -606,9 +618,11 @@ class SourceSpoke(NormalSpoke):
         dialog = MediaCheckDialog(self.data)
         with enlightbox(self.window, dialog.window):
             dev = self.storage.devicetree.getDeviceByName(dev)
+            unmount = not dev.format.status
             dev.format.mount(mountpoint=MOUNTPOINT)
             dialog.run(MOUNTPOINT + "/" + f)
-            dev.format.unmount()
+            if unmount:
+                dev.format.unmount()
 
     def on_verify_media_clicked(self, button):
         dev = self._get_selected_media()
-- 
1.7.7.6


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