def refresh(self): self._shown = True #update the displayed time self._update_datetime_timer_id = GLib.timeout_add_seconds( 1, self._update_datetime) self._start_updating_timer_id = None if is_valid_timezone(self.data.timezone.timezone): self._tzmap.set_timezone(self.data.timezone.timezone) self._update_datetime() has_active_network = nm.nm_is_connected() if not has_active_network: self._show_no_network_warning() else: self.clear_info() gtk_call_once(self._config_dialog.refresh_servers_state) if flags.can_touch_runtime_system("get NTP service state"): ntp_working = has_active_network and iutil.service_running( NTP_SERVICE) else: ntp_working = not self.data.timezone.nontp self._ntpSwitch.set_active(ntp_working)
def refresh(self): self._shown = True # update the displayed time self._update_datetime_timer = Timer() self._update_datetime_timer.timeout_sec(1, self._update_datetime) self._start_updating_timer = None kickstart_timezone = self._timezone_module.proxy.Timezone if is_valid_timezone(kickstart_timezone): self._tzmap.set_timezone(kickstart_timezone) time.tzset() self._update_datetime() has_active_network = self._network_module.proxy.Connected if not has_active_network: self._show_no_network_warning() else: self.clear_info() gtk_call_once(self._config_dialog.refresh_servers_state) if conf.system.can_set_time_synchronization: ntp_working = has_active_network and util.service_running(NTP_SERVICE) else: ntp_working = self._timezone_module.proxy.NTPEnabled self._ntpSwitch.set_active(ntp_working)
def _on_installation_done(self): log.debug("The installation has finished.") # Stop the spinner. gtk_call_once(self._spinner.stop) gtk_call_once(self._spinner.hide) # Finish the installation task. Re-raise tracebacks if any. self._task.finish() util.ipmi_report(IPMI_FINISHED) if conf.license.eula: self.set_warning( _("Use of this product is subject to the license agreement " "found at %s") % conf.license.eula) self.window.show_all() # Show the reboot message. self._progressNotebook.set_current_page(1) # Enable the continue button. self.window.set_may_continue(True) # Hide the quit button. quit_button = self.window.get_quit_button() quit_button.hide() # kickstart install, continue automatically if reboot or shutdown selected if flags.automatedInstall and self.data.reboot.action in [ KS_REBOOT, KS_SHUTDOWN ]: self.window.emit("continue-clicked")
def _autostepSpoke(self): """Process a single spoke, if no more spokes are available report autostep as finished for the hub.""" # do we have some spokes to work on ? if self._spokesToStepIn: # take one of them spoke = self._spokesToStepIn.pop() # increment the number of processed spokes self._spokeAutostepIndex += 1 log.debug("stepping to spoke %s (%d/%d)", spoke.__class__.__name__, self._spokeAutostepIndex, len(self._spokes)) # notify the spoke about the upcoming automatic entry and set a callback that will be called # once the spoke has been successfully processed spoke.automaticEntry = True spoke.autostepDoneCallback = lambda x: self._autostepSpoke() # if this is the last spoke, tell it to return to hub once processed if self._spokesToStepIn == []: spoke.lastAutostepSpoke = True gtk_call_once(self._on_spoke_clicked, None, None, spoke) else: log.info("autostep for hub %s finished", self.__class__.__name__) gtk_call_once(self._doPostAutostep)
def _step_progress_bar(self): if not self._totalSteps: return self._currentStep += 1 gtk_call_once(self._progressBar.set_fraction, self._currentStep / self._totalSteps)
def refresh(self): self._shown = True #update the displayed time self._update_datetime_timer_id = GLib.timeout_add_seconds(1, self._update_datetime) self._start_updating_timer_id = None if is_valid_timezone(self.data.timezone.timezone): self._tzmap.set_timezone(self.data.timezone.timezone) self._update_datetime() has_active_network = nm.nm_is_connected() if not has_active_network: self._show_no_network_warning() else: self.clear_info() gtk_call_once(self._config_dialog.refresh_servers_state) if flags.can_touch_runtime_system("get NTP service state"): ntp_working = has_active_network and iutil.service_running(NTP_SERVICE) else: ntp_working = not self.data.timezone.nontp self._ntpSwitch.set_active(ntp_working)
def on_remove_clicked(self, button): if not self._selection.count_selected_rows(): return (store, itr) = self._selection.get_selected() itr2 = store.get_iter_first() #if the first item is selected, try to select the next one if store[itr][0] == store[itr2][0]: itr2 = store.iter_next(itr2) if itr2: #next one existing self._selection.select_iter(itr2) self._removeLayout(store, itr) # Re-emit the selection changed signal now that the backing store is updated # in order to update the first/last/only-based button sensitivities self._selection.emit("changed") return #nothing left, run AddLayout dialog to replace the current layout #add it to GLib.idle to make sure the underlaying gui is correctly #redrawn self._remove_last_attempt = True add_button = self.builder.get_object("addLayoutButton") gtk_call_once(self.on_add_clicked, add_button) return #the selected item is not the first, select the previous one #XXX: there is no model.iter_previous() so we have to find it this way itr3 = store.iter_next(itr2) #look-ahead iterator while itr3 and (store[itr3][0] != store[itr][0]): itr2 = store.iter_next(itr2) itr3 = store.iter_next(itr3) self._removeLayout(store, itr) self._selection.select_iter(itr2)
def refresh(self): self._shown = True # update the displayed time self._update_datetime_timer = Timer() self._update_datetime_timer.timeout_sec(1, self._update_datetime) self._start_updating_timer = None kickstart_timezone = self._timezone_module.proxy.Timezone if is_valid_timezone(kickstart_timezone): self._tzmap.set_timezone(kickstart_timezone) time.tzset() self._update_datetime() has_active_network = self._network_module.proxy.Connected if not has_active_network: self._show_no_network_warning() else: self.clear_info() gtk_call_once(self._config_dialog.refresh_servers_state) if conf.system.can_set_time_synchronization: ntp_working = has_active_network and util.service_running( NTP_SERVICE) else: ntp_working = self._timezone_module.proxy.NTPEnabled self._ntpSwitch.set_active(ntp_working)
def _on_progress_changed(self, step, message): """Handle a new progress report.""" if message: gtk_call_once(self._progressLabel.set_text, message) if self._task.steps > 0: gtk_call_once(self._progressBar.set_fraction, step / self._task.steps)
def _initialize(self): hubQ.send_message(self.__class__.__name__, _("Probing storage...")) threadMgr.wait(constants.THREAD_STORAGE) hubQ.send_message(self.__class__.__name__, _(METADATA_DOWNLOAD_MESSAGE)) threadMgr.wait(constants.THREAD_PAYLOAD) added = False # If there's no fallback mirror to use, we should just disable that option # in the UI. if not self.payload.mirrorEnabled: self._protocolComboBox.remove(PROTOCOL_MIRROR) # If we've previously set up to use a CD/DVD method, the media has # already been mounted by payload.setup. We can't try to mount it # again. So just use what we already know to create the selector. # Otherwise, check to see if there's anything available. if self.data.method.method == "cdrom": self._cdrom = self.payload.install_device elif not flags.automatedInstall: self._cdrom = opticalInstallMedia(self.storage.devicetree) if self._cdrom: @gtk_action_wait def gtk_action_1(): self._autodetectDeviceLabel.set_text( _("Device: %s") % self._cdrom.name) self._autodetectLabel.set_text( _("Label: %s") % (getattr(self._cdrom.format, "label", "") or "")) gtk_action_1() added = True if self.data.method.method == "harddrive": self._currentIsoFile = self.payload.ISOImage # These UI elements default to not being showable. If optical install # media were found, mark them to be shown. if added: gtk_call_once(self._autodetectBox.set_no_show_all, False) gtk_call_once(self._autodetectButton.set_no_show_all, False) # Add the mirror manager URL in as the default for HTTP and HTTPS. # We'll override this later in the refresh() method, if they've already # provided a URL. # FIXME self._reset_repoStore() self._ready = True hubQ.send_ready(self.__class__.__name__, False)
def _initialize(self): hubQ.send_message(self.__class__.__name__, _("Probing storage...")) threadMgr.wait(constants.THREAD_STORAGE) hubQ.send_message(self.__class__.__name__, _(METADATA_DOWNLOAD_MESSAGE)) threadMgr.wait(constants.THREAD_PAYLOAD) added = False # If there's no fallback mirror to use, we should just disable that option # in the UI. if not self.payload.mirrorEnabled: self._protocolComboBox.remove(PROTOCOL_MIRROR) # If we've previously set up to use a CD/DVD method, the media has # already been mounted by payload.setup. We can't try to mount it # again. So just use what we already know to create the selector. # Otherwise, check to see if there's anything available. if self.data.method.method == "cdrom": self._cdrom = self.payload.install_device elif not flags.automatedInstall: self._cdrom = opticalInstallMedia(self.storage.devicetree) if self._cdrom: @gtk_action_wait def gtk_action_1(): self._autodetectDeviceLabel.set_text(_("Device: %s") % self._cdrom.name) self._autodetectLabel.set_text(_("Label: %s") % (getattr(self._cdrom.format, "label", "") or "")) gtk_action_1() added = True if self.data.method.method == "harddrive": self._currentIsoFile = self.payload.ISOImage # These UI elements default to not being showable. If optical install # media were found, mark them to be shown. if added: gtk_call_once(self._autodetectBox.set_no_show_all, False) gtk_call_once(self._autodetectButton.set_no_show_all, False) # Add the mirror manager URL in as the default for HTTP and HTTPS. # We'll override this later in the refresh() method, if they've already # provided a URL. # FIXME self._reset_repoStore() self._ready = True hubQ.send_ready(self.__class__.__name__, False)
def run_dasdfmt(self, epoch_started, *args): """ Loop through our disks and run dasdfmt against them. """ for disk in self.to_format: try: gtk_call_once(self._formatting_label.set_text, _("Formatting /dev/%s. This may take a moment.") % disk.name) blockdev.s390.dasd_format(disk.name) except blockdev.S390Error as err: # Log errors if formatting fails, but don't halt the installer log.error(str(err)) continue with self._epoch_lock: self.update_dialog(epoch_started)
def enterSpoke(self, spoke): """Enter a spoke. The spoke will be displayed as the current screen, but the current-action to which the spoke will return will not be changed. :param AnacondaWidgets.SpokeWindow spoke: a spoke to enter """ self._setVisibleChild(spoke) # autostep through the spoke if required if spoke.automaticEntry: # we need to use idle_add here to give GTK time to render the spoke gtk_call_once(self._autostep_spoke, spoke)
def run_dasdfmt(self, epoch_started, *args): """ Loop through our disks and run dasdfmt against them. """ for disk in self.to_format: try: gtk_call_once(self._formatting_label.set_text, _("Formatting /dev/%s. This may take a moment.") % disk) format_dasd(disk) except DasdFormatError as err: # Log errors if formatting fails, but don't halt the installer log.error(str(err)) continue # And now to fire up the storage reinitialization. protectedNames = [d.name for d in self.storage.protectedDevices] storageInitialize(self.storage, self.data, protectedNames) with self._epoch_lock: self.update_dialog(epoch_started)
def enterSpoke(self, spoke): """Enter a spoke. The spoke will be displayed as the current screen, but the current-action to which the spoke will return will not be changed. :param AnacondaWidgets.SpokeWindow spoke: a spoke to enter """ # Slide up, as if the spoke is under the hub self._stack.set_transition_type(Gtk.StackTransitionType.UNDER_UP) self._setVisibleChild(spoke) # autostep through the spoke if required if spoke.automaticEntry: # we need to use idle_add here to give GTK time to render the spoke gtk_call_once(self._autostep_spoke, spoke)
def refresh(self): from pyanaconda.installation import RunInstallationTask super().refresh() # Initialize the progress bar. gtk_call_once(self._progressBar.set_fraction, 0.0) # Start the installation task. self._task = RunInstallationTask(payload=self.payload, ksdata=self.data) self._task.progress_changed_signal.connect(self._on_progress_changed) self._task.stopped_signal.connect(self._on_installation_done) self._task.start() # Start the spinner. gtk_call_once(self._spinner.start) log.debug("The installation has started.")
def _runSpoke(self, action): from gi.repository import Gtk # This duplicates code in widgets/src/BaseWindow.c, but we want to make sure # maximize gets called every time a spoke is displayed to prevent the 25% # UI from showing up. action.window.maximize() action.window.set_property("expand", True) action.refresh() action.window.set_transient_for(self.window) action.window.show_all() # step through the spoke if required if action.automaticEntry: # we need to use idle_add here to give GTK time to render the spoke gtk_call_once(self._autostep_spoke, action) # Start a recursive main loop for this spoke, which will prevent # signals from going to the underlying (but still displayed) Hub and # prevent the user from switching away. It's up to the spoke's back # button handler to kill its own layer of main loop. Gtk.main() action.window.set_transient_for(None) # don't apply any actions if the spoke was visited automatically if action.automaticEntry: action.automaticEntry = False return action._visitedSinceApplied = True # Don't take _visitedSinceApplied into account here. It will always be # True from the line above. if action.changed and (not action.skipTo or (action.skipTo and action.applyOnSkip)): action.apply() action.execute() action._visitedSinceApplied = False
def getRepoMetadata(self): hubQ.send_not_ready("SoftwareSelectionSpoke") hubQ.send_not_ready(self.__class__.__name__) hubQ.send_message(self.__class__.__name__, _(BASEREPO_SETUP_MESSAGE)) # this sleep is lame, but without it the message above doesn't seem # to get processed by the hub in time, and is never shown. # FIXME this should get removed when we figure out how to ensure # that the message takes effect on the hub before we try to mount # a bad NFS server. time.sleep(1) try: self.payload.updateBaseRepo(fallback=False, checkmount=False) except (OSError, PayloadError) as e: log.error("PayloadError: %s" % (e, )) self._error = True hubQ.send_message(self.__class__.__name__, _("Failed to set up installation source")) if not (hasattr(self.data.method, "proxy") and self.data.method.proxy): gtk_call_once( self.set_warning, _("Failed to set up installation source; check the repo url" )) else: gtk_call_once( self.set_warning, _("Failed to set up installation source; check the repo url and proxy settings" )) else: self._error = False hubQ.send_message(self.__class__.__name__, _(METADATA_DOWNLOAD_MESSAGE)) self.payload.gatherRepoMetadata() self.payload.release() if not self.payload.baseRepo: hubQ.send_message(self.__class__.__name__, _(METADATA_ERROR_MESSAGE)) hubQ.send_ready(self.__class__.__name__, False) self._error = True gtk_call_once( self.set_warning, _("Failed to set up installation source; check the repo url" )) else: try: # Grabbing the list of groups could potentially take a long time the # first time (yum does a lot of magic property stuff, some of which # involves side effects like network access) so go ahead and grab # them now. These are properties with side-effects, just accessing # them will trigger yum. e = self.payload.environments g = self.payload.groups except MetadataError: hubQ.send_message("SoftwareSelectionSpoke", _("No installation source available")) else: hubQ.send_ready("SoftwareSelectionSpoke", False) finally: hubQ.send_ready(self.__class__.__name__, False)
def _update_progress(self, callback=None): from pyanaconda.progress import progressQ import queue q = progressQ.q # Grab all messages may have appeared since last time this method ran. while True: # Attempt to get a message out of the queue for how we should update # the progress bar. If there's no message, don't error out. try: (code, args) = q.get(False) except queue.Empty: break if code == progressQ.PROGRESS_CODE_INIT: self._init_progress_bar(args[0]) elif code == progressQ.PROGRESS_CODE_STEP: self._step_progress_bar() elif code == progressQ.PROGRESS_CODE_MESSAGE: self._update_progress_message(args[0]) elif code == progressQ.PROGRESS_CODE_COMPLETE: q.task_done() # we are done, stop the progress indication gtk_call_once(self._progressBar.set_fraction, 1.0) gtk_call_once(self._progressLabel.set_text, _("Complete!")) gtk_call_once(self._spinner.stop) gtk_call_once(self._spinner.hide) if callback: callback() # There shouldn't be any more progress bar updates, so return False # to indicate this method should be removed from the idle loop. return False elif code == progressQ.PROGRESS_CODE_QUIT: sys.exit(args[0]) q.task_done() return True
def getRepoMetadata(self): hubQ.send_not_ready("SoftwareSelectionSpoke") hubQ.send_not_ready(self.__class__.__name__) hubQ.send_message(self.__class__.__name__, _(BASEREPO_SETUP_MESSAGE)) # this sleep is lame, but without it the message above doesn't seem # to get processed by the hub in time, and is never shown. # FIXME this should get removed when we figure out how to ensure # that the message takes effect on the hub before we try to mount # a bad NFS server. time.sleep(1) try: self.payload.updateBaseRepo(fallback=False, checkmount=False) except (OSError, PayloadError) as e: log.error("PayloadError: %s", e) self._error = True hubQ.send_message(self.__class__.__name__, _("Failed to set up installation source")) if not (hasattr(self.data.method, "proxy") and self.data.method.proxy): gtk_call_once(self.set_warning, _("Failed to set up installation source; check the repo url")) else: gtk_call_once(self.set_warning, _("Failed to set up installation source; check the repo url and proxy settings")) else: self._error = False hubQ.send_message(self.__class__.__name__, _(METADATA_DOWNLOAD_MESSAGE)) self.payload.gatherRepoMetadata() self.payload.release() if not self.payload.baseRepo: hubQ.send_message(self.__class__.__name__, _(METADATA_ERROR_MESSAGE)) hubQ.send_ready(self.__class__.__name__, False) self._error = True gtk_call_once(self.set_warning, _("Failed to set up installation source; check the repo url")) else: try: # Grabbing the list of groups could potentially take a long time the # first time (yum does a lot of magic property stuff, some of which # involves side effects like network access) so go ahead and grab # them now. These are properties with side-effects, just accessing # them will trigger yum. # pylint: disable-msg=W0104 self.payload.environments # pylint: disable-msg=W0104 self.payload.groups except MetadataError: hubQ.send_message("SoftwareSelectionSpoke", _("No installation source available")) else: hubQ.send_ready("SoftwareSelectionSpoke", False) finally: hubQ.send_ready(self.__class__.__name__, False)
def _init_progress_bar(self, steps): self._totalSteps = steps self._currentStep = 0 gtk_call_once(self._progressBar.set_fraction, 0.0)
def _step_progress_bar(self): if not self._totalSteps: return self._currentStep += 1 gtk_call_once(self._progressBar.set_fraction, self._currentStep/self._totalSteps)
def _update_spokes(self): from pyanaconda.ui.communication import hubQ import Queue q = hubQ.q if not self._spokes and self.continueButton: # no spokes, move on gtk_call_once(self.continueButton.emit, "clicked") # Grab all messages that may have appeared since last time this method ran. while True: try: (code, args) = q.get(False) except Queue.Empty: break # The first argument to all codes is the name of the spoke we are # acting on. If no such spoke exists, throw the message away. spoke = self._spokes.get(args[0], None) if not spoke: q.task_done() continue if code == hubQ.HUB_CODE_NOT_READY: self._updateCompleteness(spoke) if spoke not in self._notReadySpokes: self._notReadySpokes.append(spoke) self._updateContinueButton() log.info("spoke is not ready: %s", spoke) elif code == hubQ.HUB_CODE_READY: self._updateCompleteness(spoke) if spoke in self._notReadySpokes: self._notReadySpokes.remove(spoke) self._updateContinueButton() log.info("spoke is ready: %s", spoke) # If this is a real kickstart install (the kind with an input ks file) # and all spokes are now completed, we should skip ahead to the next # hub automatically. Take into account the possibility the user is # viewing a spoke right now, though. if flags.automatedInstall: # Spokes that were not initially ready got the execute call in # _createBox skipped. Now that it's become ready, do it. Note # that we also provide a way to skip this processing (see comments # communication.py) to prevent getting caught in a loop. if not args[1] and spoke.changed and spoke._visitedSinceApplied: spoke.execute() spoke._visitedSinceApplied = False if self.continuePossible: if self._inSpoke: self._autoContinue = False elif self._autoContinue and q.empty() and self.continueButton: # enqueue the emit to the Gtk message queue gtk_call_once(self.continueButton.emit, "clicked") elif code == hubQ.HUB_CODE_MESSAGE: spoke.selector.set_property("status", args[1]) log.info("setting %s status to: %s", spoke, args[1]) q.task_done() return True
def _method_changed(self): """ Check to see if the install method has changed. :returns: True if it changed, False if not :rtype: bool """ import copy old_source = copy.deepcopy(self.data.method) if self._autodetectButton.get_active(): if not self._cdrom: return False self.data.method.method = "cdrom" self.payload.install_device = self._cdrom if old_source.method == "cdrom": # XXX maybe we should always redo it for cdrom in case they # switched disks return False elif self._isoButton.get_active(): # If the user didn't select a partition (not sure how that would # happen) or didn't choose a directory (more likely), then return # as if they never did anything. part = self._get_selected_partition() if not part or not self._currentIsoFile: return False self.data.method.method = "harddrive" self.data.method.partition = part.name # The / gets stripped off by payload.ISOImage self.data.method.dir = "/" + self._currentIsoFile if (old_source.method == "harddrive" and old_source.partition == self.data.method.partition and old_source.dir == self.data.method.dir): return False # Make sure anaconda doesn't touch this device. part.protected = True self.storage.config.protectedDevSpecs.append(part.name) elif self._mirror_active(): # this preserves the url for later editing self.data.method.method = None self.data.method.proxy = self._proxyUrl if not old_source.method and self.payload.baseRepo and \ not self._proxyChange: return False elif self._http_active() or self._ftp_active(): url = self._urlEntry.get_text().strip() mirrorlist = False # If the user didn't fill in the URL entry, just return as if they # selected nothing. if url == "": return False # Make sure the URL starts with the protocol. yum will want that # to know how to fetch, and the refresh method needs that to know # which element of the combo to default to should this spoke be # revisited. if self._ftp_active() and not url.startswith("ftp://"): url = "ftp://" + url elif self._protocolComboBox.get_active( ) == PROTOCOL_HTTP and not url.startswith("http://"): url = "http://" + url mirrorlist = self._mirrorlistCheckbox.get_active() elif self._protocolComboBox.get_active( ) == PROTOCOL_HTTPS and not url.startswith("https://"): url = "https://" + url mirrorlist = self._mirrorlistCheckbox.get_active() if old_source.method == "url" and not self._proxyChange and \ ((not mirrorlist and old_source.url == url) or \ (mirrorlist and old_source.mirrorlist == url)): return False self.data.method.method = "url" self.data.method.proxy = self._proxyUrl if mirrorlist: self.data.method.mirrorlist = url self.data.method.url = "" else: self.data.method.url = url self.data.method.mirrorlist = "" elif self._nfs_active(): url = self._urlEntry.get_text().strip() # If the user didn't fill in the URL entry, or it does not contain # a ':' (so, no host/directory split), just return as if they # selected nothing. if url == "" or not ':' in url: return False self.data.method.method = "nfs" try: (self.data.method.server, self.data.method.dir) = url.split(":", 2) except ValueError as e: log.error("ValueError: %s", e) gtk_call_once( self.set_warning, _("Failed to set up installation source; check the repo url" )) self._error = True return self.data.method.opts = self.builder.get_object( "nfsOptsEntry").get_text() or "" if (old_source.method == "nfs" and old_source.server == self.data.method.server and old_source.dir == self.data.method.dir and old_source.opts == self.data.method.opts): return False # If the user moved from an HDISO method to some other, we need to # clear the protected bit on that device. if old_source.method == "harddrive" and old_source.partition: self._currentIsoFile = None self._isoChooserButton.set_label(self._origIsoChooserButton) self._isoChooserButton.set_use_underline(True) if old_source.partition in self.storage.config.protectedDevSpecs: self.storage.config.protectedDevSpecs.remove( old_source.partition) dev = self.storage.devicetree.getDeviceByName(old_source.partition) if dev: dev.protected = False self._proxyChange = False return True
def _update_spokes(self): from pyanaconda.ui.communication import hubQ import queue q = hubQ.q if not self._spokes and self.window.get_may_continue(): # no spokes, move on log.debug("no spokes available on %s, continuing automatically", self) gtk_call_once(self.window.emit, "continue-clicked") click_continue = False # Grab all messages that may have appeared since last time this method ran. while True: try: (code, args) = q.get(False) except queue.Empty: break # The first argument to all codes is the name of the spoke we are # acting on. If no such spoke exists, throw the message away. spoke = self._spokes.get(args[0], None) if not spoke or spoke.__class__.__name__ not in self._spokes: q.task_done() continue if code == hubQ.HUB_CODE_NOT_READY: self._updateCompleteness(spoke) if spoke not in self._notReadySpokes: self._notReadySpokes.append(spoke) self._updateContinueButton() log.debug("spoke is not ready: %s", spoke) elif code == hubQ.HUB_CODE_READY: self._updateCompleteness(spoke) if spoke in self._notReadySpokes: self._notReadySpokes.remove(spoke) self._updateContinueButton() log.debug("spoke is ready: %s", spoke) # If this is a real kickstart install (the kind with an input ks file) # and all spokes are now completed, we should skip ahead to the next # hub automatically. Take into account the possibility the user is # viewing a spoke right now, though. if flags.automatedInstall: spoke_title = spoke.title.replace("_", "") # Users might find it helpful to know why a kickstart install # went interactive. Log that here. if not spoke.completed and spoke.mandatory: autoinstall_stopped( "User interaction required on spoke %s" % spoke_title) else: log.debug("kickstart installation, spoke %s is ready", spoke_title) # Spokes that were not initially ready got the execute call in # _createBox skipped. Now that it's become ready, do it. Note # that we also provide a way to skip this processing (see comments # communication.py) to prevent getting caught in a loop. if not args[ 1] and spoke.changed and spoke.visitedSinceApplied: log.debug("execute spoke from event loop %s", spoke.title.replace("_", "")) spoke.execute() spoke.visitedSinceApplied = False if self.continuePossible: if self._inSpoke: self._autoContinue = False elif self._autoContinue: click_continue = True elif code == hubQ.HUB_CODE_MESSAGE: spoke.selector.set_property("status", args[1]) log.debug("setting %s status to: %s", spoke, args[1]) q.task_done() # queue is now empty, should continue be clicked? if self._autoContinue and click_continue and self.window.get_may_continue( ): # enqueue the emit to the Gtk message queue log.debug("_autoContinue clicking continue button") gtk_call_once(self.window.emit, "continue-clicked") return True
def show_dasdfmt_report(self, msg): """Show the report from the DASD formatting. The callback should be run in the glib loop. """ gtk_call_once(self._formatting_label.set_text, msg)
def _update_spokes(self): from pyanaconda.ui.communication import hubQ import queue q = hubQ.q if not self._spokes and self.window.get_may_continue(): # no spokes, move on log.debug("no spokes available on %s, continuing automatically", self) gtk_call_once(self.window.emit, "continue-clicked") click_continue = False # Grab all messages that may have appeared since last time this method ran. while True: try: (code, args) = q.get(False) except queue.Empty: break # The first argument to all codes is the name of the spoke we are # acting on. If no such spoke exists, throw the message away. spoke = self._spokes.get(args[0], None) if not spoke or spoke.__class__.__name__ not in self._spokes: q.task_done() continue if code == hubQ.HUB_CODE_NOT_READY: self._updateCompleteness(spoke) if spoke not in self._notReadySpokes: self._notReadySpokes.append(spoke) self._updateContinueButton() log.debug("spoke is not ready: %s", spoke) elif code == hubQ.HUB_CODE_READY: self._updateCompleteness(spoke) if spoke in self._notReadySpokes: self._notReadySpokes.remove(spoke) self._updateContinueButton() log.debug("spoke is ready: %s", spoke) # If this is a real kickstart install (the kind with an input ks file) # and all spokes are now completed, we should skip ahead to the next # hub automatically. Take into account the possibility the user is # viewing a spoke right now, though. if flags.automatedInstall: # Users might find it helpful to know why a kickstart install # went interactive. Log that here. if not spoke.completed: log.info("kickstart installation stopped for info: %s", spoke.title.replace("_", "")) # Spokes that were not initially ready got the execute call in # _createBox skipped. Now that it's become ready, do it. Note # that we also provide a way to skip this processing (see comments # communication.py) to prevent getting caught in a loop. if not args[1] and spoke.changed and spoke.visitedSinceApplied: spoke.execute() spoke.visitedSinceApplied = False if self.continuePossible: if self._inSpoke: self._autoContinue = False elif self._autoContinue: click_continue = True elif code == hubQ.HUB_CODE_MESSAGE: spoke.selector.set_property("status", args[1]) log.debug("setting %s status to: %s", spoke, args[1]) q.task_done() # queue is now empty, should continue be clicked? if self._autoContinue and click_continue and self.window.get_may_continue(): # enqueue the emit to the Gtk message queue log.debug("_autoContinue clicking continue button") gtk_call_once(self.window.emit, "continue-clicked") return True
def _doPostAutostep(self): # we are done, re-emit the continue clicked signal we "consumed" previously # so that the Anaconda GUI can switch to the next screen gtk_call_once(self.window.emit, "continue-clicked")
def _update_progress_message(self, message): if not self._totalSteps: return gtk_call_once(self._progressLabel.set_text, message)
def _update_spokes(self): from pyanaconda.ui.communication import hubQ import Queue q = hubQ.q if not self._spokes and self.continueButton: # no spokes, move on gtk_call_once(self.continueButton.emit, "clicked") click_continue = False # Grab all messages that may have appeared since last time this method ran. while True: try: (code, args) = q.get(False) except Queue.Empty: break # The first argument to all codes is the name of the spoke we are # acting on. If no such spoke exists, throw the message away. spoke = self._spokes.get(args[0], None) if not spoke: q.task_done() continue if code == hubQ.HUB_CODE_NOT_READY: self._updateCompleteness(spoke) if spoke not in self._notReadySpokes: self._notReadySpokes.append(spoke) self._updateContinueButton() log.info("spoke is not ready: %s", spoke) elif code == hubQ.HUB_CODE_READY: self._updateCompleteness(spoke) if spoke in self._notReadySpokes: self._notReadySpokes.remove(spoke) self._updateContinueButton() log.info("spoke is ready: %s", spoke) # If this is a real kickstart install (the kind with an input ks file) # and all spokes are now completed, we should skip ahead to the next # hub automatically. Take into account the possibility the user is # viewing a spoke right now, though. if flags.automatedInstall: # Spokes that were not initially ready got the execute call in # _createBox skipped. Now that it's become ready, do it. Note # that we also provide a way to skip this processing (see comments # communication.py) to prevent getting caught in a loop. if not args[1] and spoke.changed and spoke._visitedSinceApplied: spoke.execute() spoke._visitedSinceApplied = False if self.continuePossible: if self._inSpoke: # STACKIQ # self._autoContinue = False self._autoContinue = True # STACKIQ elif self._autoContinue and q.empty() and self.continueButton: click_continue = True elif code == hubQ.HUB_CODE_MESSAGE: spoke.selector.set_property("status", args[1]) log.info("setting %s status to: %s", spoke, args[1]) q.task_done() # queue is now empty, should continue be clicked? if self._autoContinue and click_continue: # enqueue the emit to the Gtk message queue log.info("_autoContinue clicking continue button") gtk_call_once(self.continueButton.emit, "clicked") return True
def _method_changed(self): """ Check to see if the install method has changed. :returns: True if it changed, False if not :rtype: bool """ import copy old_source = copy.deepcopy(self.data.method) if self._autodetectButton.get_active(): if not self._cdrom: return False self.data.method.method = "cdrom" self.payload.install_device = self._cdrom if old_source.method == "cdrom": # XXX maybe we should always redo it for cdrom in case they # switched disks return False elif self._isoButton.get_active(): # If the user didn't select a partition (not sure how that would # happen) or didn't choose a directory (more likely), then return # as if they never did anything. part = self._get_selected_partition() if not part or not self._currentIsoFile: return False self.data.method.method = "harddrive" self.data.method.partition = part.name # The / gets stripped off by payload.ISOImage self.data.method.dir = "/" + self._currentIsoFile if (old_source.method == "harddrive" and old_source.partition == self.data.method.partition and old_source.dir == self.data.method.dir): return False # Make sure anaconda doesn't touch this device. part.protected = True self.storage.config.protectedDevSpecs.append(part.name) elif self._mirror_active(): # this preserves the url for later editing self.data.method.method = None self.data.method.proxy = self._proxyUrl if not old_source.method and self.payload.baseRepo and \ not self._proxyChange: return False elif self._http_active() or self._ftp_active(): url = self._urlEntry.get_text().strip() mirrorlist = False # If the user didn't fill in the URL entry, just return as if they # selected nothing. if url == "": return False # Make sure the URL starts with the protocol. yum will want that # to know how to fetch, and the refresh method needs that to know # which element of the combo to default to should this spoke be # revisited. if self._ftp_active() and not url.startswith("ftp://"): url = "ftp://" + url elif self._protocolComboBox.get_active() == PROTOCOL_HTTP and not url.startswith("http://"): url = "http://" + url mirrorlist = self._mirrorlistCheckbox.get_active() elif self._protocolComboBox.get_active() == PROTOCOL_HTTPS and not url.startswith("https://"): url = "https://" + url mirrorlist = self._mirrorlistCheckbox.get_active() if old_source.method == "url" and not self._proxyChange and \ ((not mirrorlist and old_source.url == url) or \ (mirrorlist and old_source.mirrorlist == url)): return False self.data.method.method = "url" self.data.method.proxy = self._proxyUrl if mirrorlist: self.data.method.mirrorlist = url self.data.method.url = "" else: self.data.method.url = url self.data.method.mirrorlist = "" elif self._nfs_active(): url = self._urlEntry.get_text().strip() # If the user didn't fill in the URL entry, or it does not contain # a ':' (so, no host/directory split), just return as if they # selected nothing. if url == "" or not ':' in url: return False self.data.method.method = "nfs" try: (self.data.method.server, self.data.method.dir) = url.split(":", 2) except ValueError as e: log.error("ValueError: %s", e) gtk_call_once(self.set_warning, _("Failed to set up installation source; check the repo url")) self._error = True return self.data.method.opts = self.builder.get_object("nfsOptsEntry").get_text() or "" if (old_source.method == "nfs" and old_source.server == self.data.method.server and old_source.dir == self.data.method.dir and old_source.opts == self.data.method.opts): return False # If the user moved from an HDISO method to some other, we need to # clear the protected bit on that device. if old_source.method == "harddrive" and old_source.partition: self._currentIsoFile = None self._isoChooserButton.set_label(self._origIsoChooserButton) self._isoChooserButton.set_use_underline(True) if old_source.partition in self.storage.config.protectedDevSpecs: self.storage.config.protectedDevSpecs.remove(old_source.partition) dev = self.storage.devicetree.getDeviceByName(old_source.partition) if dev: dev.protected = False self._proxyChange = False return True