# # task_gui.py: Choose tasks for installation # # Copyright 2006 Red Hat, Inc. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import gtk import gtk.glade import gobject import gui import iutil import rpmUtils from iw_gui import * from rhpl.translate import _, N_ from constants import productName from netconfig_dialog import NetworkConfigurator import network from yuminstall import AnacondaYumRepo import yum.Errors import logging log = logging.getLogger("anaconda") class TaskWindow(InstallWindow): def getNext(self): if self.xml.get_widget("customRadio").get_active(): self.dispatch.skipStep("group-selection", skip = 0) else: self.dispatch.skipStep("group-selection", skip = 1) tasks = self.xml.get_widget("taskList").get_model() # I move this PAST repo setup: or we get all unselected stuff ... # # Quick hack to handle overlapping groups in tasks for an installclass # for (cb, task, grps) in tasks: # if not cb: # map(self.backend.deselectGroup, grps) # for (cb, task, grps) in tasks: # if cb: # map(self.backend.selectGroup, grps) # if self.anaconda.id.instClass.allowExtraRepos: repos = self.xml.get_widget("repoList").get_model() for (cb, reponame, repo) in repos: if cb: repo.basecachedir = self.backend.ayum.conf.cachedir repo.enable() try: self.backend.ayum.repos.add(repo) except yum.Errors.DuplicateRepoError, e: # # OK, so we could scream here ... however what for ? # this will be triggered if user goes forth-back-forth in anaconda # so actually .. there is NO real error here ... # skip silently and work ;-) # self.intf.messageWindow(_("Error"), # _("The repository %s has already been added. Please " # "choose a different repository name and " # "URL.") % reponame, type="ok", custom_icon="error") continue if not self._setupRepo(repo): continue # else: # try: # self.backend.ayum.repos.delete(repo.id) # except: # continue self.backend.ayum.doGroupSetup() # FIXME: this is a bad hack to remove support for xen on xen (#179387) # FIXME: and another bad hack since our xen kernel is PAE # FIXME: and yet another for vmware. if iutil.inXen() or iutil.inVmware() or \ (rpmUtils.arch.getBaseArch() == "i386" and "pae" not in iutil.cpuFeatureFlags()): if self.backend.ayum.comps._groups.has_key("virtualization"): del self.backend.ayum.comps._groups["virtualization"] # # We make it work as for add-on user repos, or anaconda crashes # (see also yuminstall.py) # Jaroslaw.Polok@cern.ch 07.12.2009 # # repo.enable() # # # Setup any repositories that were in the installclass's # # default list. # if not repo.ready(): # self._setupRepo(repo) # else: # repo.disable() # # jareks comment: and also broken when user goes back in anaconda .. deselects all # # Quick hack to handle overlapping groups in tasks for an installclass for (cb, task, grps) in tasks: if not cb: map(self.backend.deselectGroup, grps) for (cb, task, grps) in tasks: if cb: map(self.backend.selectGroup, grps) def groupsInstalled(self, lst): # FIXME: yum specific rc = False for gid in lst: log.info("groupsInstalled -> %s" % gid) g = self.backend.ayum.comps.return_group(gid) if g and not g.selected: log.info("groupsInstalled -> %s exists but not selected, returns False" % gid) return False elif g: log.info("groupsInstalled -> %s exists and selected" % gid) rc = True log.info("groupsInstalled -> returns %s" % rc) return rc def groupsExist(self, lst): # FIXME: yum specific for gid in lst: g = self.backend.ayum.comps.return_group(gid) if not g: return False return True def _setupRepo(self, repo): try: self.backend.doRepoSetup(self.anaconda, repo.id, fatalerrors = False) log.info("added repository %s with with source URL %s" % (repo.name, repo.baseurl[0])) except yum.Errors.RepoError, e: self.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" %(e,)), type="ok", custom_icon="error") self.backend.ayum.repos.delete(repo.id) return False if not repo.groups_added: self.intf.messageWindow(_("Warning"), _("Unable to find a group file for %s. " "This will make manual selection of packages " "from the repository not work") %(repo.id,), type="warning") return True def _addRepo(self, *args): if not network.hasActiveNetDev(): net = NetworkConfigurator(self.anaconda.id.network) ret = net.run() net.destroy() if ret == gtk.RESPONSE_CANCEL: return gtk.RESPONSE_CANCEL (dxml, dialog) = gui.getGladeWidget("addrepo.glade", "addRepoDialog") gui.addFrame(dialog) lbl = dxml.get_widget("descLabel") txt = lbl.get_text() lbl.set_text(txt %(productName,)) dialog.show_all() while 1: rc = dialog.run() if rc == gtk.RESPONSE_CANCEL: break reponame = dxml.get_widget("nameEntry").get_text() reponame.strip() if len(reponame) == 0: self.intf.messageWindow(_("Invalid Repository Name"), _("You must provide a non-zero length " "repository name.")) continue repourl = dxml.get_widget("urlEntry").get_text() repourl.strip() if (len(repourl) == 0 or not (repourl.startswith("http://") or repourl.startswith("ftp://"))): self.intf.messageWindow(_("Invalid Repository URL"), _("You must provide an HTTP or FTP " "URL to a repository.")) continue # FIXME: this is yum specific repo = AnacondaYumRepo(uri=repourl, repoid=reponame) repo.name = reponame repo.basecachedir = self.backend.ayum.conf.cachedir repo.enable() 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.") % reponame, type="ok", custom_icon="error") continue if not self._setupRepo(repo): continue s = self.xml.get_widget("repoList").get_model() s.append([repo.isEnabled(), repo.name, repo]) self.repos[repo.name] = (repo.baseurl[0], None) break dialog.destroy() return rc def _taskToggled(self, data, row, store): i = store.get_iter(int(row)) val = store.get_value(i, 0) store.set_value(i, 0, not val) def _repoToggled(self, data, row, store): i = store.get_iter(int(row)) val = store.get_value(i, 0) if not val and not network.hasActiveNetDev(): net = NetworkConfigurator(self.anaconda.id.network) ret = net.run() net.destroy() if ret == gtk.RESPONSE_CANCEL: return store.set_value(i, 0, not val) def _createTaskStore(self): store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) tl = self.xml.get_widget("taskList") tl.set_model(store) cbr = gtk.CellRendererToggle() col = gtk.TreeViewColumn('', cbr, active = 0) cbr.connect("toggled", self._taskToggled, store) tl.append_column(col) col = gtk.TreeViewColumn('Text', gtk.CellRendererText(), text = 1) col.set_clickable(False) tl.append_column(col) for (txt, grps) in self.tasks: if not self.groupsExist(grps): continue store.append([self.groupsInstalled(grps), _(txt), grps]) return len(store) def _createRepoStore(self): store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) tl = self.xml.get_widget("repoList") tl.set_model(store) cbr = gtk.CellRendererToggle() col = gtk.TreeViewColumn('', cbr, active = 0) cbr.connect("toggled", self._repoToggled, store) tl.append_column(col) col = gtk.TreeViewColumn('Text', gtk.CellRendererText(), text = 1) col.set_clickable(False) tl.append_column(col) # # Get stuff from InstallClass, do NOT enable , getNext will do it ! # Hmm .. this will break things when user adds own repo and then # goes back in anaconda ... (will it actually ?) # for (reponame, (uri, mirror)) in self.anaconda.id.instClass.repos.items(): rid = reponame.replace(" ", "") repo = AnacondaYumRepo(uri=uri, repoid=rid) repo.name = reponame repo.disable() store.append([repo.isEnabled(), repo.name, repo]) # for (reponame, uri) in self.repos.items(): # repoid = reponame.replace(" ", "") # if not self.backend.ayum.repos.repos.has_key(repoid): # continue # repo = self.backend.ayum.repos.repos[repoid] # store.append([repo.isEnabled(), repo.name, repo]) def getScreen (self, anaconda): self.intf = anaconda.intf self.dispatch = anaconda.dispatch self.backend = anaconda.backend self.anaconda = anaconda self.tasks = anaconda.id.instClass.tasks self.repos = anaconda.id.instClass.repos (self.xml, vbox) = gui.getGladeWidget("tasksel.glade", "taskBox") lbl = self.xml.get_widget("mainLabel") if anaconda.id.instClass.description: lbl.set_text(_(anaconda.id.instClass.description)) else: txt = lbl.get_text() lbl.set_text(txt %(productName,)) custom = not self.dispatch.stepInSkipList("group-selection") if custom: self.xml.get_widget("customRadio").set_active(True) else: self.xml.get_widget("customRadio").set_active(False) if self._createTaskStore() == 0: self.xml.get_widget("cbVBox").hide() self.xml.get_widget("mainLabel").hide() self._createRepoStore() if not anaconda.id.instClass.allowExtraRepos: vbox.remove(self.xml.get_widget("addRepoBox")) self.xml.get_widget("addRepoButton").connect("clicked", self._addRepo) return vbox