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:
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(-)
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
+ # 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(u rl))
+ 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.mirro rlist)
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
@@ -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:
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)
- # 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
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)
- 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
@@ -700,14 +498,24 @@ class TaskWindow(InstallWindow):
else:
self.xml.get_widget("customRadio").set_active(Fals e)
- 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()
- 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@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list