[PATCH 5/6] Fix repo editing dialogs (#502208, #516053, #516042)

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

 



Fixes editing of Install Repo, added repos, and methodstr dialog raised e.g.
when incorrect repo= nfs option is added.  Works with assumption that install
(repo/method) url points to a single repo, which is true for Fedora (as
opposed to RHEL5 where we various repos in directories). dgregor told me that
the target for RHEL6 is to have just one repo and handle product
differentiation by comps. If we had to work with multirepo install urls, the
UI for repo editing would need to be redesigned and rewritten because now we
are mixing install urls with repo urls there.

Installation Repo is handled as other repos, not by using "Base" yuminstall
functions which is incompatible with editing by means of creating temporary
repo object.

Our repo= url is stored in AnacondaYumRepo so that e.g nfs: type of target can
be edited (instead of having mountpoint url in the dialog). I remember that we
wanted to get rid of the class in yuminstall cleanup, but couldn't come with
better solution.

cdrom: repo option is still broken. Change to CD/DVD repo target in non-media
install too. It may be next step that would probably involve refreshing of
format information of the device. Change to CD/DVD in dialogs after booting
from media is fixed.

The patch is tested.
---
 gui.py         |    4 +-
 iw/task_gui.py |  141 +++++++++++++++++++++++++++++++------------------------
 yuminstall.py  |   47 ++++++++++++------
 3 files changed, 112 insertions(+), 80 deletions(-)

diff --git a/gui.py b/gui.py
index c83ff8c..77f9fce 100755
--- a/gui.py
+++ b/gui.py
@@ -1044,9 +1044,9 @@ class InstallInterface:
         dialog.createDialog()
         dialog.run()
 
-    def methodstrRepoWindow(self):
+    def methodstrRepoWindow(self, methodstr):
         from task_gui import RepoMethodstrEditor
-        dialog = RepoMethodstrEditor(self.anaconda)
+        dialog = RepoMethodstrEditor(self.anaconda, methodstr)
         dialog.createDialog()
         return dialog.run()
 
diff --git a/iw/task_gui.py b/iw/task_gui.py
index 30c28dc..91128b5 100644
--- a/iw/task_gui.py
+++ b/iw/task_gui.py
@@ -43,7 +43,7 @@ def setupRepo(anaconda, repo):
     try:
         anaconda.backend.doRepoSetup(anaconda, thisrepo=repo.id, fatalerrors=False)
         anaconda.backend.doSackSetup(anaconda, thisrepo=repo.id, fatalerrors=False)
-        log.info("added repository %s with source URL %s" % (repo.name, repo.mirrorlist or repo.baseurl))
+        log.info("added (UI) repository %s with source URL %s, id:%s" % (repo.name, repo.mirrorlist or repo.baseurl, repo.id))
         # FIXME: need a per-repo way of doing this; largely cut and paste
         # from yum right now
         if not repo.groups_added:
@@ -66,26 +66,13 @@ def setupRepo(anaconda, repo):
                 "Please ensure that your repository has been "
                 "correctly generated.\n\n%s" % str(e)),
                                 type="ok", custom_icon="error")
+        repo.disable()
+        repo.close()
         anaconda.backend.ayum.repos.delete(repo.id)
         return False
 
     return True
 
-def setupBaseRepo(anaconda, methodstr):
-    anaconda.setMethodstr(methodstr)
-
-    try:
-        anaconda.backend.ayum.configBaseURL()
-    except SystemError as e:
-        anaconda.intf.messageWindow(_("Error Setting Up Repository"),
-            _("The following error occurred while setting up the "
-              "installation repository:\n\n%s\n\nPlease provide the "
-              "correct information for installing %s") % (e, productName))
-        return False
-
-    anaconda.backend.ayum.configBaseRepo(replace=True)
-    return True
-
 class RepoEditor:
     # Window-level callbacks
     def on_addRepoDialog_destroy(self, widget, *args):
@@ -170,10 +157,9 @@ class RepoEditor:
         except:
             return 0
 
-    def _enableRepo(self, repo):
+    def _addAndEnableRepo(self, repo):
         try:
             self.backend.ayum.repos.add(repo)
-            self.backend.ayum.repos.enableRepo(repo.id)
         except yum.Errors.DuplicateRepoError, e:
             self.intf.messageWindow(_("Error"),
                   _("The repository %s has already been added.  Please "
@@ -181,6 +167,16 @@ class RepoEditor:
                     "URL.") % self.repo.name, type="ok", custom_icon="error")
             return False
 
+        self.backend.ayum.repos.enableRepo(repo.id)
+        # XXX maybe catch specific exception when we know which,
+        # but it shouldn't happen anyway
+#        try:
+#            self.backend.ayum.repos.enableRepo(repo.id)
+#        except:
+#            newRepoObj.close()
+#            self.backend.ayum.repos.delete(repo.id)
+#            return False
+
         return True
 
     def _validURL(self, url):
@@ -189,18 +185,17 @@ class RepoEditor:
                                  url.startswith("ftp://";))
 
     def createDialog(self):
-
         if self.repo:
             self.nameEntry.set_text(self.repo.name)
-            self.typeComboBox.set_active(self._methodToIndex(self.anaconda.methodstr))
+            self.typeComboBox.set_active(self._methodToIndex(self.repo.anacondabaseurl[0]))
 
-            if not self.anaconda.methodstr or self.anaconda.methodstr.startswith("http") or self.anaconda.methodstr.startswith("ftp"):
+            if not self.repo.anacondabaseurl or self.repo.anacondabaseurl[0].startswith("http") or self.repo.anacondabaseurl[0].startswith("ftp"):
                 if self.repo.mirrorlist:
                     self.baseurlEntry.set_text(self.repo.mirrorlist)
                     self.mirrorlistCheckbox.set_active(True)
                 else:
-                    if self.repo.baseurl:
-                        self.baseurlEntry.set_text(self.repo.baseurl[0])
+                    if self.repo.anacondabaseurl:
+                        self.baseurlEntry.set_text(self.repo.anacondabaseurl[0])
                     else:
                         self.baseurlEntry.set_text("")
 
@@ -215,15 +210,18 @@ class RepoEditor:
                 else:
                     self.proxyCheckbox.set_active(False)
                     self.proxyTable.set_sensitive(False)
-            elif self.anaconda.methodstr.startswith("nfs"):
-                (method, server, dir) = self.anaconda.methodstr.split(":")
-                self.nfsServerEntry.set_text(server)
-                self.nfsPathEntry.set_text(dir)
+            elif self.repo.anacondabaseurl[0].startswith("nfs"):
+                method_server_dir = self.repo.anacondabaseurl[0].split(":")
+                try:
+                    self.nfsServerEntry.set_text(method_server_dir[1])
+                    self.nfsPathEntry.set_text(method_server_dir[2])
+                except IndexError:
+                    pass
                 self.nfsOptionsEntry.set_text("")
-            elif self.anaconda.methodstr.startswith("cdrom:"):
+            elif self.repo.anacondabaseurl[0].startswith("cdrom:"):
                 pass
-            elif self.anaconda.methodstr.startswith("hd:"):
-                m = self.anaconda.methodstr[3:]
+            elif self.repo.anacondabaseurl[0].startswith("hd:"):
+                m = self.repo.anacondabaseurl[0][3:]
                 if m.count(":") == 1:
                     (device, path) = m.split(":")
                     fstype = "auto"
@@ -274,16 +272,16 @@ class RepoEditor:
         else:
             repo.baseurl = [repourl]
             repo.mirrorlist = None
+        repo.anacondabaseurl = repo.baseurl
 
         repo.name = self.nameEntry.get_text()
 
-        if repo.name == "Installation Repo":
-            return setupBaseRepo(self.anaconda, repourl)
-
         return True
 
     def _applyMedia(self, repo):
-        cdr = scanForMedia(self.anaconda.backend.ayum.tree, self.anaconda.id.storage)
+        # FIXME - to be fixed with media handling general fix
+        ayum = self.anaconda.backend.ayum
+        cdr = scanForMedia(ayum.tree, self.anaconda.id.storage)
         if not cdr:
             self.intf.messageWindow(_("No Media Found"),
                                     _("No installation media was found. "
@@ -291,7 +289,17 @@ class RepoEditor:
                                       "and try again."))
             return False
 
-        return setupBaseRepo(self.anaconda, "cdrom://%s:%s" % (cdr, self.anaconda.backend.ayum.tree))
+        log.info("found installation media on %s" % cdr)
+        repo.name = self.nameEntry.get_text()
+        repo.anacondabaseurl = ["cdrom:"]
+        repo.baseurl = "file://%s" % ayum.tree
+        ayum.mediagrabber = ayum.mediaHandler
+        self.anaconda.mediaDevice = cdr
+        ayum.currentMedia = 1
+        repo.mediaid = getMediaId(ayum.tree)
+        log.info("set mediaid of repo %s to: %s" % (repo.name, repo.mediaid))
+
+        return True
 
     def _applyNfs(self, repo):
         server = self.nfsServerEntry.get_text()
@@ -307,22 +315,22 @@ class RepoEditor:
                                     _("Please enter an NFS server and path."))
             return False
 
-        if repo.name == "Installation Repo":
-            return setupBaseRepo(self.anaconda, "nfs:%s:%s" % (server, path))
-        else:
-            import tempfile
-            dest = tempfile.mkdtemp("", repo.name, "/mnt")
+        import tempfile
+        prefix = repo.name.replace(' ', '')
+        dest = tempfile.mkdtemp("", prefix, "/mnt")
 
-            try:
-                isys.mount("%s:%s" % (server, path), dest, "nfs")
-            except Exception as e:
-                self.intf.messageWindow(_("Error Setting Up Repository"),
-                    _("The following error occurred while setting up the "
-                      "repository:\n\n%s") % e)
-                return False
+        try:
+            # XXX umount somewhere, when deleting?
+            isys.mount("%s:%s" % (server, path), dest, "nfs")
+        except Exception as e:
+            self.intf.messageWindow(_("Error Setting Up Repository"),
+                _("The following error occurred while setting up the "
+                  "repository:\n\n%s") % e)
+            return False
 
-            repo.baseurl = "file://%s" % dest
-            return True
+        repo.baseurl = "file://%s" % dest
+        repo.anacondabaseurl = ["nfs:%s:%s" % (server,path)]
+        return True
 
     def _applyHd(self, repo):
         return True
@@ -348,17 +356,18 @@ class RepoEditor:
             # sure that if we're just editing the repo, we grab all the
             # attributes from the old one before deleting it.
             if self.repo:
-                newRepoObj = AnacondaYumRepo(self.repo.id)
+                # use temporary id so that we don't get Duplicate Repo error
+                newRepoObj = AnacondaYumRepo("UIedited_%s" %
+                                             self.anaconda.backend.ayum.repoIDcounter.next())
+                newRepoObj.cost = self.repo.cost
                 removeOld = True
             else:
                 newRepoObj = AnacondaYumRepo(reponame.replace(" ", ""))
                 removeOld = False
 
             type = self.typeComboBox.get_active()
-            if not applyFuncs[type](newRepoObj) or not self._enableRepo(newRepoObj) or not \
+            if not applyFuncs[type](newRepoObj) or not self._addAndEnableRepo(newRepoObj) or not \
                    setupRepo(self.anaconda, newRepoObj):
-                newRepoObj.close()
-                self.anaconda.backend.ayum.repos.delete(newRepoObj.id)
                 continue
 
             if removeOld:
@@ -368,8 +377,11 @@ class RepoEditor:
                 except:
                     pass
 
+                self.repo.disable()
                 self.repo.close()
                 self.anaconda.backend.ayum.repos.delete(self.repo.id)
+                log.info("deleted (UI) repository %s with source URL %s, id:%s"
+                         % (self.repo.name, self.repo.mirrorlist or self.repo.baseurl, self.repo.id))
                 try:
                     shutil.rmtree(self.repo.cachedir)
                 except Exception as e:
@@ -383,19 +395,24 @@ class RepoEditor:
         return rc
 
 class RepoMethodstrEditor(RepoEditor):
-    def __init__(self, anaconda):
-        RepoEditor.__init__(self, anaconda, None)
+    def __init__(self, anaconda, methodstr):
+        # Create temporary repo to store methodstr needed for
+        # createDialog parent method.
+        tempRepoObj = AnacondaYumRepo("UITmpMethodstrRepo")
+        tempRepoObj.name = "Installation Repo"
+        tempRepoObj.anacondabaseurl = [methodstr]
+        RepoEditor.__init__(self, anaconda, tempRepoObj)
 
     def createDialog(self):
         RepoEditor.createDialog(self)
 
         # Hide a bunch of stuff that doesn't apply when we're just prompting
         # for enough information to form a methodstr.
-        self.dxml.get_widget("nameLabel").hide()
-        self.nameEntry.hide()
-        self.mirrorlistCheckbox.hide()
-        self.proxyCheckbox.hide()
-        self.proxyTable.hide()
+        self.dxml.get_widget("nameLabel").set_sensitive(False)
+        self.nameEntry.set_sensitive(False)
+        self.mirrorlistCheckbox.set_sensitive(False)
+        self.proxyCheckbox.set_sensitive(False)
+        self.proxyTable.set_sensitive(False)
 
     def _applyURL(self):
         repourl = self.baseurlEntry.get_text()
@@ -409,7 +426,7 @@ class RepoMethodstrEditor(RepoEditor):
         return repourl
 
     def _applyMedia(self):
-        cdr = scanForMedia(self.anaconda.backend.ayum.tree, self.anaconda.id.storage)
+        cdr = scanForMedia("/mnt/source", self.anaconda.id.storage)
         if not cdr:
             self.intf.messageWindow(_("No Media Found"),
                                     _("No installation media was found. "
@@ -417,7 +434,7 @@ class RepoMethodstrEditor(RepoEditor):
                                       "and try again."))
             return False
 
-        return "cdrom://%s:%s" % (cdr, self.anaconda.backend.ayum.tree)
+        return "cdrom:%s" % cdr
 
     def _applyNfs(self):
         server = self.nfsServerEntry.get_text()
diff --git a/yuminstall.py b/yuminstall.py
index 99239d7..a8571ad 100644
--- a/yuminstall.py
+++ b/yuminstall.py
@@ -30,6 +30,7 @@ import types
 import locale
 import glob
 import tempfile
+import itertools
 
 import rpm
 import rpmUtils
@@ -242,6 +243,7 @@ class AnacondaYumRepo(YumRepository):
     def __init__(self, *args, **kwargs):
         YumRepository.__init__(self, *args, **kwargs)
         self.enablegroups = True
+        self._anacondabaseurl = None
 
     def needsNetwork(self):
         def _isURL(s):
@@ -266,6 +268,18 @@ class AnacondaYumRepo(YumRepository):
                 if os.path.exists("%s/packages" % cachedir):
                     shutil.rmtree("%s/packages" % cachedir)
 
+    #yum doesn't support nfs:// url so store it here
+    @property
+    def anacondabaseurl(self):
+        return (self._anacondabaseurl or self.baseurl or
+                (type(self.mirrorlist) is type([]) and self.mirrorlist) or
+                [self.mirrorlist])
+
+
+    @anacondabaseurl.setter
+    def anacondabaseurl(self, value):
+        self._anacondabaseurl = value
+
 class YumSorter(yum.YumBase):
     def _transactionDataFactory(self):
         return SplitMediaTransactionData()
@@ -276,6 +290,8 @@ class AnacondaYum(YumSorter):
         self.anaconda = anaconda
         self._timestamp = None
 
+        self.repoIDcounter = itertools.count()
+
         # Only needed for hard drive and nfsiso installs.
         self._discImages = {}
         self.isodir = None
@@ -302,7 +318,7 @@ class AnacondaYum(YumSorter):
                       "installation repository:\n\n%s\n\nPlease provide the "
                       "correct information for installing %s.") % (e, productName))
 
-                self.anaconda.methodstr = self.anaconda.intf.methodstrRepoWindow()
+                self.anaconda.methodstr = self.anaconda.intf.methodstrRepoWindow(self.anaconda.methodstr or "cdrom:")
 
         self.doConfigSetup(root=anaconda.rootPath)
         self.conf.installonlypkgs = []
@@ -444,7 +460,9 @@ class AnacondaYum(YumSorter):
                     self.anaconda.methodstr = "nfsiso:%s" % m[4:]
                     self.configBaseURL()
                     return
+                self._baseRepoURL = "file://%s" % self.tree
             elif m.startswith("cdrom:"):
+                # FIXME
                 self._switchCD(1)
                 self.mediagrabber = self.mediaHandler
                 self._baseRepoURL = "file://%s" % self.tree
@@ -464,27 +482,23 @@ class AnacondaYum(YumSorter):
                 # default to using whatever's enabled in /etc/yum.repos.d/
                 self._baseRepoURL = None
 
-    def configBaseRepo(self, root='/', replace=False):
+    def configBaseRepo(self, root='/'):
         # Create the "base" repo object, assuming there is one.  Otherwise we
         # just skip all this and use the defaults from /etc/yum.repos.d.
         if not self._baseRepoURL:
             return
 
         # add default repos
+        anacondabaseurl = (self.anaconda.methodstr or
+                           "cdrom://%s:%s" % (self.anaconda.mediaDevice, self.tree))
+        # we need to keep them for editing in UI
+        anacondabasepaths = self.anaconda.id.instClass.getPackagePaths(anacondabaseurl)
         for (name, uri) in self.anaconda.id.instClass.getPackagePaths(self._baseRepoURL).items():
             rid = name.replace(" ", "")
 
-            if replace:
-                try:
-                    repo = self.repos.getRepo("anaconda-%s-%s" % (rid, productStamp))
-                    repo.baseurl = uri
-                except RepoError:
-                    replace = False
-
-            # If there was an error finding the "base" repo, create a new one now.
-            if not replace:
-                repo = AnacondaYumRepo("anaconda-%s-%s" % (rid, productStamp))
-                repo.baseurl = uri
+            repo = AnacondaYumRepo("anaconda-%s-%s" % (rid, productStamp))
+            repo.baseurl = uri
+            repo.anacondabaseurl = anacondabasepaths[name]
 
             repo.name = name
             repo.cost = 100
@@ -494,9 +508,7 @@ class AnacondaYum(YumSorter):
                 log.info("set mediaid of repo %s to: %s" % (rid, repo.mediaid))
 
             repo.enable()
-
-            if not replace:
-                self.repos.add(repo)
+            self.repos.add(repo)
 
     def mediaHandler(self, *args, **kwargs):
         mediaid = kwargs["mediaid"]
@@ -645,6 +657,7 @@ class AnacondaYum(YumSorter):
                 # yum doesn't understand nfs:// and doesn't want to.  We need
                 # to first do the mount, then translate it into a file:// that
                 # yum does understand.
+                anacondabaseurl = None
                 if ksrepo.baseurl and ksrepo.baseurl.startswith("nfs://"):
                     if not network.hasActiveNetDev() and not self.anaconda.intf.enableNetwork():
                         self.anaconda.intf.messageWindow(_("No Network Available"),
@@ -662,6 +675,7 @@ class AnacondaYum(YumSorter):
                     except Exception as e:
                         log.error("error mounting NFS repo: %s" % e)
 
+                    anacondabaseurl = [ksrepo.baseurl]
                     ksrepo.baseurl = "file://%s" % dest
 
                 repo = AnacondaYumRepo(ksrepo.name)
@@ -672,6 +686,7 @@ class AnacondaYum(YumSorter):
                     repo.baseurl = []
                 else:
                     repo.baseurl = [ ksrepo.baseurl ]
+                repo.anacondabaseurl = anacondabaseurl
 
                 if ksrepo.cost:
                     repo.cost = ksrepo.cost
-- 
1.6.0.6

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux