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