We used to do repo setup (including mounting, network enablement) after each single repo edit. In case of repos coming from method=/repo= or ks repo= the only possibility was to edit in dialog or exit. With the patch, edit means going to repo UI screen so the repo can be also disabled. Icons indicating result of setup was added to repo list items. (see http://rvykydal.fedorapeople.org/repoUI/example.ogg) Originally I wanted to do all repo setup after going [Next] from repo UI screen, but there is one UI design issue which makes it impossible: The repotasksel step/screen combines repo editing and task selection which is unfortunate because task selection requires all repositories to be set up so the required steps are: edit repositories (UI) -> setup repositories (nonUI) -> select tasks (UI) Because the first and the third are on the same screen in present UI I have to call non-UI step from the UI screen which I wasn't able to do without some UI flow hacks (see yuminstall.py hunk). Making task selection separate step or adding it to group/package selection screen (where it belongs from the yum backend point of view, not sure if also from user point of view) would make things cleaner. --- pyanaconda/iw/task_gui.py | 620 ++++++++++++++++----------------------------- pyanaconda/yuminstall.py | 26 ++- 2 files changed, 237 insertions(+), 409 deletions(-) diff --git a/pyanaconda/iw/task_gui.py b/pyanaconda/iw/task_gui.py index cba030d..3a6392e 100644 --- a/pyanaconda/iw/task_gui.py +++ b/pyanaconda/iw/task_gui.py @@ -21,45 +21,14 @@ import gtk import gtk.glade import gobject from pyanaconda import gui -import gzip from iw_gui import * -from pyanaconda.image import * from pyanaconda.constants import * -from pyanaconda import isys -import shutil +from pyanaconda import iutil import gettext _ = lambda x: gettext.ldgettext("anaconda", x) -from pyanaconda import network -from pyanaconda import iutil - -from pyanaconda.yuminstall import AnacondaYumRepo -import urlgrabber.grabber -import yum.Errors - -import logging -log = logging.getLogger("anaconda") - -def setupRepo(anaconda, repo): - if repo.needsNetwork() and not network.hasActiveNetDev(): - if not anaconda.intf.enableNetwork(): - return False - urlgrabber.grabber.reset_curl_obj() - try: - anaconda.backend.doRepoSetup(anaconda, thisrepo=repo.id, fatalerrors=False) - anaconda.backend.doSackSetup(anaconda, thisrepo=repo.id, fatalerrors=False) - log.info("added (UI) repository %s with source URL %s, id:%s" % (repo.name, repo.mirrorlist or repo.baseurl, repo.id)) - except (IOError, yum.Errors.RepoError) as e: - anaconda.intf.messageWindow(_("Error"), - _("Unable to read package metadata from repository. " - "This may be due to a missing repodata directory. " - "Please ensure that your repository has been " - "correctly generated.\n\n%s" % str(e)), - type="ok", custom_icon="error") - return False - - return True +from pyanaconda.yuminstall import RepoSpec class RepoEditor: # Window-level callbacks @@ -73,16 +42,13 @@ class RepoEditor: pass def on_typeComboBox_changed(self, widget, *args): - if widget.get_active() == -1: + iter = widget.get_active_iter() + if iter == None: return - # When the combo box's value is changed, set the notebook's current - # page to match. This requires that the combo box and notebook have - # the same method types at the same indices (so, HTTP must be the - # same position on both, etc.). - self.notebook.set_current_page(widget.get_active()) + self.notebook.set_current_page(widget.get_model().get_value(iter, 3)) - if widget.get_active() == 1: + if widget.get_model().get_value(iter, 1) == "http": if self.repo: self.proxyCheckbox.set_active(self.repo.proxy is True) self.proxyTable.set_sensitive(self.repo.proxy is True) @@ -98,11 +64,10 @@ class RepoEditor: def on_mirrorlistCheckbox_toggled(self, widget, *args): pass - def __init__(self, anaconda, repoObj): - self.anaconda = anaconda - self.backend = self.anaconda.backend - self.intf = self.anaconda.intf - self.repo = repoObj + def __init__(self, backend, intf, repoSpec): + self.backend = backend + self.intf = intf + self.repo = repoSpec (self.dxml, self.dialog) = gui.getGladeWidget("addrepo.glade", "addRepoDialog") self.dxml.signal_autoconnect(self) @@ -128,41 +93,43 @@ class RepoEditor: self.dialog.set_title(_("Edit Repository")) - # Remove these until they are actually implemented - self.typeComboBox.remove_text(3) - - # Given a method string, return the index of the typeComboBox that should - # be made active in order to match. - def _methodToIndex(self, method): - mapping = {"http": 0, "ftp": 0, "https": 0, - "cdrom": 1, - "nfs": 2} -# "nfs": 2, "nfsiso": 2, -# "hd": 3} - - try: - return mapping[method.split(':')[0].lower()] - except: - return 0 - - def _addAndEnableRepo(self, repo): - try: - self.backend.ayum.repos.add(repo) - except yum.Errors.DuplicateRepoError, e: - self.intf.messageWindow(_("Error"), - _("The repository %s has already been added. Please " - "choose a different repository name and " - "URL.") % repo.name, type="ok", custom_icon="error") - return False - - repo.enable() - return True + self._setupTypeCombobox(repoSpec.type) - def _disableAndRemoveRepo(self, repo): - repo.disable() - repo.close() - self.anaconda.backend.ayum.repos.delete(repo.id) + def _setupTypeCombobox(self, repotype): + store = gtk.ListStore(gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_PYOBJECT, + gobject.TYPE_INT) + self.typeComboBox.set_model(store) + store.append(["HTTP/FTP", "http", self._applyURL, 0]) + store.append(["NFS", "nfs", self._applyNfs, 2]) + if repotype == "method": + store.append(["CD/DVD", "cdrom", self._applyMedia, 1]) + #store.append(["HD", "hd", self._applyHd, 3]) + + def _urlToMethod(self, url): + d = {"http":"http", + "ftp":"http", + "cdrom":"cdrom", + "nfs":"nfs", + "hd":"hd"} + for prefix in d: + if url.startswith(prefix): + return d[prefix] + else: + return "http" + # Given a method string, return the iter of the typeComboBox that should + # be made active in order to match. + def _urlToIter(self, url): + method = self._urlToMethod(url) + model = self.typeComboBox.get_model() + iter = model.get_iter_first() + while iter: + if method == model.get_value(iter, 1): + return iter + iter = model.iter_next(iter) + return model.get_iter_first() def _validURL(self, url): return len(url) > 0 and (url.startswith("http://") or @@ -171,22 +138,14 @@ class RepoEditor: def createDialog(self): - if self.repo: + if self.repo.url: self.nameEntry.set_text(self.repo.name) - if self.repo.anacondaBaseURLs: - url = self.repo.anacondaBaseURLs[0] - else: - url = '' - self.typeComboBox.set_active(self._methodToIndex(url)) + url = self.repo.url + self.typeComboBox.set_active_iter(self._urlToIter(url)) - if not url or url.startswith("http") or url.startswith("ftp"): - if self.repo.mirrorlist: - self.baseurlEntry.set_text(self.repo.mirrorlist) - self.mirrorlistCheckbox.set_active(True) - else: - self.baseurlEntry.set_text(url) - - self.mirrorlistCheckbox.set_active(False) + if url.startswith("http") or url.startswith("ftp"): + self.baseurlEntry.set_text(url) + self.mirrorlistCheckbox.set_active(self.repo.mirrorlist) if self.repo.proxy: self.proxyCheckbox.set_active(True) @@ -213,7 +172,8 @@ class RepoEditor: (device, fstype, path) = m.split(":") # find device in self.partitionComboBox and select it - self.directoryChooser.set_current_folder("%s%s" % (self.anaconda.backend.ayum.isodir, path)) + # TODORV isodir is a problem + self.directoryChooser.set_current_folder("%s%s" % (self.backend.ayum.isodir, path)) else: self.baseurlEntry.set_text(url) @@ -230,7 +190,15 @@ class RepoEditor: self.dialog.show_all() - def _applyURL(self, repo): + def _applyURL(self): + repourl = self.baseurlEntry.get_text() + repourl.strip() + if not self._validURL(repourl): + self.intf.messageWindow(_("Invalid Repository URL"), + _("You must provide an HTTP, HTTPS, " + "or FTP URL to a repository.")) + return False + if self.proxyCheckbox.get_active(): proxy = self.proxyEntry.get_text() proxy.strip() @@ -241,55 +209,24 @@ class RepoEditor: "or FTP URL to a proxy.")) return False - repo.proxy = proxy - # with empty string yum would create invalid proxy string - repo.proxy_username = self.usernameEntry.get_text() or None - repo.proxy_password = self.passwordEntry.get_text() or None + self.repo.proxy = proxy + self.repo.proxy_username = self.usernameEntry.get_text() + self.repo.proxy_password = self.passwordEntry.get_text() - repourl = self.baseurlEntry.get_text() - repourl.strip() - if not self._validURL(repourl): - self.intf.messageWindow(_("Invalid Repository URL"), - _("You must provide an HTTP, HTTPS, " - "or FTP URL to a repository.")) - return False + self.repo.url = repourl if self.mirrorlistCheckbox.get_active(): - repo.baseurl = [] - repo.mirrorlist = repourl - else: - repo.baseurl = [repourl] - repo.mirrorlist = None - repo.anacondaBaseURLs = repo.baseurl - - repo.name = self.nameEntry.get_text() + self.repo.mirrorlist = True + self.repo.name = self.nameEntry.get_text() return True - def _applyMedia(self, repo): - # FIXME works only if storage has detected format of cdrom drive - ayum = self.anaconda.backend.ayum - cdr = scanForMedia(ayum.tree, self.anaconda.storage) - if not cdr: - self.intf.messageWindow(_("No Media Found"), - _("No installation media was found. " - "Please insert a disc into your drive " - "and try again.")) - return False - - log.info("found installation media on %s" % cdr) - repo.name = self.nameEntry.get_text() - repo.anacondaBaseURLs = ["cdrom://%s:%s" % (cdr, self.anaconda.backend.ayum.tree)] - 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)) - + def _applyMedia(self): + self.repo.name = self.nameEntry.get_text() + self.repo.url = "cdrom://" return True - def _applyNfs(self, repo): + def _applyNfs(self): server = self.nfsServerEntry.get_text() server.strip() @@ -299,221 +236,64 @@ class RepoEditor: options = self.nfsOptionsEntry.get_text() options.strip() - repo.name = self.nameEntry.get_text() - if not server or not path: self.intf.messageWindow(_("Error"), _("Please enter an NFS server and path.")) return False - if not network.hasActiveNetDev(): - if not self.anaconda.intf.enableNetwork(): - self.intf.messageWindow(_("No Network Available"), - _("Some of your software repositories require " - "networking, but there was an error enabling the " - "network on your system.")) - return False - urlgrabber.grabber.reset_curl_obj() - - import tempfile - dest = tempfile.mkdtemp("", repo.name.replace(" ", ""), "/mnt") - - try: - isys.mount("%s:%s" % (server, path), dest, "nfs", options=options) - 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 - repo.anacondaBaseURLs = ["nfs:%s:%s:%s" % (options,server,path)] + self.repo.name = self.nameEntry.get_text() + self.repo.url = "nfs:%s:%s:%s" % (options,server,path) return True - def _applyHd(self, repo): + def _applyHd(self): return True def run(self): - applyFuncs = [ self._applyURL, self._applyMedia, self._applyNfs, - self._applyHd ] + repo = None while True: rc = self.dialog.run() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: break - - reponame = self.nameEntry.get_text() - reponame.strip() - if len(reponame) == 0: - self.intf.messageWindow(_("Invalid Repository Name"), - _("You must provide a repository name.")) - continue - - # Always create a new repo object here instead of attempting to - # somehow expire the metadata and refetch. We'll just have to make - # sure that if we're just editing the repo, we grab all the - # attributes from the old one before deleting it. - if self.repo: - # use temporary id so that we don't get Duplicate Repo error - # when adding - newRepoObj = AnacondaYumRepo("UIedited_%s" % - self.anaconda.backend.ayum.repoIDcounter.next()) - newRepoObj.cost = self.repo.cost - removeOld = True else: - newRepoObj = AnacondaYumRepo(reponame.replace(" ", "")) - removeOld = False - - # corresponds to self.repos.setCacheDir in AnacondaYum.doConfigSetup - newRepoObj.basecachedir = self.anaconda.backend.ayum.conf.cachedir - - type = self.typeComboBox.get_active() - if (not applyFuncs[type](newRepoObj) or - not self._addAndEnableRepo(newRepoObj)): - continue - if not setupRepo(self.anaconda, newRepoObj): - self._disableAndRemoveRepo(newRepoObj) - continue - - if removeOld: - try: - os.unlink("%s/cachecookie" % self.repo.cachedir) - os.unlink("%s/repomd.xml" % self.repo.cachedir) - 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: - log.warning("error removing cachedir for %s: %s" %(self.repo, e)) - pass - - if (newRepoObj.enablegroups or - (removeOld and self.repo.enablegroups)): - # update groups information - try: - self.anaconda.backend.ayum.doGroupSetup() - except Exception as e: - log.debug("unable to reset group information after UI repo edit: %s" - % e) - else: - log.info("group information reset after UI repo edit") - - self.repo = newRepoObj - break - - self.dialog.hide() - return rc - -class RepoMethodstrEditor(RepoEditor): - def __init__(self, anaconda, methodstr): - # Create temporary repo to store methodstr needed for - # createDialog parent method. - temprepo = AnacondaYumRepo("UITmpMethodstrRepo") - temprepo.name = "Installation Repo" - temprepo.anacondaBaseURLs = [methodstr] - RepoEditor.__init__(self, anaconda, temprepo) - - 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.nameEntry.set_sensitive(False) - self.mirrorlistCheckbox.hide() - self.proxyCheckbox.hide() - self.proxyTable.hide() - - def _applyURL(self): - repourl = self.baseurlEntry.get_text() - repourl.strip() - if not self._validURL(repourl): - self.intf.messageWindow(_("Invalid Repository URL"), - _("You must provide an HTTP, HTTPS, " - "or FTP URL to a repository.")) - return False - - return repourl - - def _applyMedia(self): - cdr = scanForMedia(self.anaconda.backend.ayum.tree, self.anaconda.storage) - if not cdr: - self.intf.messageWindow(_("No Media Found"), - _("No installation media was found. " - "Please insert a disc into your drive " - "and try again.")) - return False - - self.anaconda.backend.ayum.mediagrabber = self.anaconda.backend.ayum.mediaHandler - self.anaconda.backend.ayum.anaconda.mediaDevice = cdr - self.anaconda.backend.ayum.currentMedia = 1 - log.info("found installation media on %s" % cdr) - return "cdrom://%s:%s" % (cdr, self.anaconda.backend.ayum.tree) - - def _applyNfs(self): - server = self.nfsServerEntry.get_text() - server.strip() - - path = self.nfsPathEntry.get_text() - path.strip() - - options = self.nfsOptionsEntry.get_text() - options.strip() - - if not server or not path: - self.intf.messageWindow(_("Error"), - _("Please enter an NFS server and path.")) - return False - - return "nfs:%s:%s:%s" % (options, server, path) - - def _applyHd(self): - return None - - def run(self): - applyFuncs = [ self._applyURL, self._applyMedia, self._applyNfs, - self._applyHd ] - - while True: - rc = self.dialog.run() - if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: - rc = None - break - - type = self.typeComboBox.get_active() - retval = applyFuncs[type]() - if not retval: - continue - - rc = retval - break - - self.dialog.hide() - return rc + active = self.typeComboBox.get_active_iter() + apply = self.typeComboBox.get_model().get_value(active, 2) + if apply(): + repo = self.repo + break + self.dialog.destroy() + return repo class RepoCreator(RepoEditor): - def __init__(self, anaconda): - RepoEditor.__init__(self, anaconda, None) + def __init__(self, backend, intf): + repo = RepoSpec() + repo.type = "UI" + RepoEditor.__init__(self, backend, intf, repo) self.dialog.set_title(_("Add Repository")) class TaskWindow(InstallWindow): def getNext(self): - if not self._anyRepoEnabled(): - self.anaconda.intf.messageWindow(_("No Software Repos Enabled"), + repos = self._getRepos() + + if not [repo for repo in repos if repo.enabled]: + self.intf.messageWindow(_("No Software Repos Enabled"), _("You must have at least one software repository enabled to " "continue installation.")) raise gui.StayOnScreen + if [repo for repo in repos if repo.enabled and not repo.setup == "OK"]: + self.intf.messageWindow(_("Enabled Repo Not Set Up"), + _("All enabled repos must be set up to " + "continue installation.")) + raise gui.StayOnScreen + if self.xml.get_widget("customRadio").get_active(): self.dispatch.skipStep("group-selection", skip = 0) else: self.dispatch.skipStep("group-selection", skip = 1) + self.anaconda.repos = repos + tasks = self.xml.get_widget("taskList").get_model() for (cb, task, grps) in filter(lambda x: not x[0], tasks): map(lambda g: setattr(self.backend.ayum.comps.return_group(g), @@ -522,42 +302,35 @@ class TaskWindow(InstallWindow): map(lambda g: setattr(self.backend.ayum.comps.return_group(g), "default", True), grps) - def _editRepo(self, *args): - repo = None + def _editRepo(self, widget, repolist): - # If we were passed an extra argument, it's the repo store and we - # are editing an existing repo as opposed to adding a new one. - if len(args) > 1: - (model, iter) = args[1].get_selection().get_selected() - if iter: - repo = model.get_value(iter, 2) - else: - return + (model, iter) = repolist.get_selection().get_selected() + if iter: + repo = model.get_value(iter, 3) else: return - if repo.needsNetwork() and not network.hasActiveNetDev(): - if not self.anaconda.intf.enableNetwork(): - return gtk.RESPONSE_CANCEL - - urlgrabber.grabber.reset_curl_obj() - - dialog = RepoEditor(self.anaconda, repo) + dialog = RepoEditor(self.backend, self.intf, repo) dialog.createDialog() - dialog.run() - - model.set_value(iter, 0, dialog.repo.isEnabled()) - model.set_value(iter, 1, dialog.repo.name) - model.set_value(iter, 2, dialog.repo) - - def _addRepo(self, *args): - dialog = RepoCreator(self.anaconda) + if dialog.run(): + repo.setup = "?" + model.set_value(iter, 0, repo.enabled) + model.set_value(iter, 1, self._resultPixbuf(repo.setup)) + model.set_value(iter, 2, repo.name) + if repo.enabled: + self._updateTaskStore() + + def _addRepo(self, widget, repos, repolist): + dialog = RepoCreator(self.backend, self.intf) dialog.createDialog() - if dialog.run() in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: - return gtk.RESPONSE_CANCEL - - s = self.xml.get_widget("repoList").get_model() - s.append([dialog.repo.isEnabled(), dialog.repo.name, dialog.repo]) + newRepo = dialog.run() + if newRepo: + newRepo.enabled = True + s = repolist.get_model() + repos.append(newRepo) + s.append([newRepo.enabled, self._resultPixbuf(newRepo.setup), + newRepo.name, newRepo]) + self._updateTaskStore() def _taskToggled(self, button, path, store): # First, untoggle everything in the store. @@ -567,44 +340,64 @@ class TaskWindow(InstallWindow): # Then, enable the one that was clicked. store[path][0] = True - def _anyRepoEnabled(self): - model = self.rs.get_model() - iter = model.get_iter_first() + def _repoToggled(self, button, row, store): + i = store.get_iter(int(row)) + wasChecked = store.get_value(i, 0) + repo = store.get_value(i, 3) + repo.enabled = not wasChecked + store.set_value(i, 0, not wasChecked) + self._updateTaskStore() - while True: - if model.get_value(iter, 0): - return True + def _getRepos(self): + repos = [] + model = self.rl.get_model() + iter = model.get_iter_first() + while iter: + repos.append(model.get_value(iter, 3)) + iter = model.iter_next(iter) + return repos + def _updateSetupResults(self, repos): + model = self.rl.get_model() + iter = model.get_iter_first() + while iter: + repo = model.get_value(iter, 3) + model.set_value(iter, 0, repo.enabled) + model.set_value(iter, 1, self._resultPixbuf(repo.setup)) iter = model.iter_next(iter) - if not iter: - return False - return False + def _updateTaskStore(self): + """Update task list for new repos selection""" + # This should go away when task selection is + # moved to groups selection screen + store = self.tl.get_model() + store.clear() + + self.anaconda.repos = self._getRepos() + rc = self.backend.doBackendSetup(self.anaconda, + called_from_repotasksel=True) + self._updateSetupResults(self.anaconda.repos) + if rc == DISPATCH_BACK: + self.tl.set_sensitive(False) + return False + else: + self.tl.set_sensitive(True) - def _repoToggled(self, button, row, store): - i = store.get_iter(int(row)) - wasChecked = store.get_value(i, 0) - repo = store.get_value(i, 2) + anyEnabled = False - if not wasChecked: - if repo.needsNetwork() and not network.hasActiveNetDev(): - if not self.anaconda.intf.enableNetwork(): - return + for (txt, grps) in self.tasks: + if not self.backend.groupListExists(grps): + continue - urlgrabber.grabber.reset_curl_obj() + enabled = self.backend.groupListDefault(grps) + store.append([not anyEnabled and enabled, _(txt), grps]) - repo.enable() - if not setupRepo(self.anaconda, repo): - repo.disable() - repo.close() - return - else: - repo.disable() - repo.close() + if enabled: + anyEnabled = True - store.set_value(i, 0, not wasChecked) + return True - def _createTaskStore(self): + def _createTaskList(self): store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) @@ -622,37 +415,36 @@ class TaskWindow(InstallWindow): col.set_clickable(False) tl.append_column(col) - anyEnabled = False - - for (txt, grps) in self.tasks: - if not self.backend.groupListExists(grps): - continue - - enabled = self.backend.groupListDefault(grps) - store.append([not anyEnabled and enabled, _(txt), grps]) - - if enabled: - anyEnabled = True - return tl def __sortRepos(self, store, aIter, bIter): - aStr = store.get_value(aIter, 1) - bStr = store.get_value(bIter, 1) + aRepo = store.get_value(aIter, 3) + bRepo = store.get_value(bIter, 3) - if aStr == "Installation Repo": + if bRepo is None: + return -1 + elif aRepo is None: + return 1 + elif aRepo.type == "method": return -1 - elif bStr == "Installation Repo": + elif bRepo.type == "method": return 1 - elif aStr < bStr or bStr is None: + elif aRepo.type == "config": return -1 - elif aStr > bStr or aStr is None: + elif bRepo.type == "config": return 1 + elif aRepo.name <= bRepo.name: + return -1 else: - return aStr == bStr + return 1 + + def _resultPixbuf(self, result): + return self.rl.render_icon(self.setup_icons[result], + size = gtk.ICON_SIZE_MENU) - def _createRepoStore(self): + def _createRepoList(self, repos): store = gtk.ListStore(gobject.TYPE_BOOLEAN, + gtk.gdk.Pixbuf, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) @@ -664,26 +456,32 @@ class TaskWindow(InstallWindow): cbr.connect("toggled", self._repoToggled, store) tl.append_column(col) - col = gtk.TreeViewColumn('Text', gtk.CellRendererText(), text = 1) + col = gtk.TreeViewColumn('Set Up', gtk.CellRendererPixbuf(), pixbuf = 1) col.set_clickable(False) tl.append_column(col) - for (reponame, repo) in self.repos.repos.items(): - store.append([repo.isEnabled(), repo.name, repo]) + col = gtk.TreeViewColumn('Name', gtk.CellRendererText(), text = 2) + col.set_clickable(False) + tl.append_column(col) store.set_sort_column_id(1, gtk.SORT_ASCENDING) store.set_sort_func(1, self.__sortRepos) return tl + def getScreen (self, anaconda): self.intf = anaconda.intf self.dispatch = anaconda.dispatch self.backend = anaconda.backend self.anaconda = anaconda + self.setup_icons = {"?" : gtk.STOCK_DISCARD, + "OK" : gtk.STOCK_YES, + "failed": gtk.STOCK_NO} + self.tasks = anaconda.instClass.tasks - self.repos = anaconda.backend.ayum.repos + self.repos = anaconda.repos (self.xml, vbox) = gui.getGladeWidget("tasksel.glade", "taskBox") @@ -700,14 +498,24 @@ class TaskWindow(InstallWindow): else: self.xml.get_widget("customRadio").set_active(False) - self.ts = self._createTaskStore() - self.rs = self._createRepoStore() + self.tl = self._createTaskList() + # TODORV: we may need separate list for base repo with addons + self.rl = self._createRepoList(self.repos) - if len(self.ts.get_model()) == 0: + for repo in self.repos: + self.rl.get_model().append([repo.enabled, + self._resultPixbuf(repo.setup), + repo.name, repo]) + + if len(self.tl.get_model()) == 0: self.xml.get_widget("cbVBox").hide() self.xml.get_widget("mainLabel").hide() - self.xml.get_widget("addRepoButton").connect("clicked", self._addRepo) - self.xml.get_widget("editRepoButton").connect("clicked", self._editRepo, self.rs) + self.xml.get_widget("addRepoButton").connect("clicked", self._addRepo, + self.repos, self.rl) + self.xml.get_widget("editRepoButton").connect("clicked", self._editRepo, + self.rl) + + self._updateTaskStore() return vbox diff --git a/pyanaconda/yuminstall.py b/pyanaconda/yuminstall.py index 3b9f765..551cf0d 100644 --- a/pyanaconda/yuminstall.py +++ b/pyanaconda/yuminstall.py @@ -1229,9 +1229,29 @@ reposdir=/etc/anaconda.repos.d,/tmp/updates/anaconda.repos.d,/tmp/product/anacon self.anaconda.repos.append(rs) ayum.readReposFromConfig = False - def doBackendSetup(self, anaconda): - if anaconda.dir == DISPATCH_BACK: - return DISPATCH_BACK + + def doBackendSetup(self, anaconda, called_from_repotasksel=False): + + # This is hack needed because of task selection being + # on the same screen as repo selection + if called_from_repotasksel: + # called after reposetup step fail or UI back + if anaconda.dir == DISPATCH_BACK: + anaconda.dir = DISPATCH_FORWARD + # after fail we don't want to try again right away + if self.ayum: + self.ayum.close() + self.ayum = None + return DISPATCH_BACK + else: + if anaconda.dir == DISPATCH_BACK: + self.ayum.close() + self.ayum = None + return DISPATCH_BACK + else: + # already set up in repotasksel + if self.ayum: + return if anaconda.upgrade: # FIXME: make sure that the rpmdb doesn't have stale locks :/ -- 1.7.2 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list