def refresh(self, args=None): NormalTUISpoke.refresh(self, args) # Join the initialization thread to block on it # This print is foul. Need a better message display print(_(PAYLOAD_STATUS_PROBING_STORAGE)) threadMgr.wait(THREAD_STORAGE_WATCHER) # synchronize our local data store with the global ksdata # Commment out because there is no way to select a disk right # now without putting it in ksdata. Seems wrong? #self.selected_disks = self.data.ignoredisk.onlyuse[:] self.autopart = self.data.autopart.autopart self._container = ListColumnContainer(1, spacing=1) message = self._update_summary() # loop through the disks and present them. for disk in self.disks: disk_info = self._format_disk_info(disk) c = CheckboxWidget(title=disk_info, completed=(disk.name in self.selected_disks)) self._container.add(c, self._update_disk_list_callback, disk) # if we have more than one disk, present an option to just # select all disks if len(self.disks) > 1: c = CheckboxWidget(title=_("Select all"), completed=self.select_all) self._container.add(c, self._select_all_disks_callback) self.window.add_with_separator(self._container) self.window.add_with_separator(TextWidget(message))
def _initialize(self): threadMgr.wait(constants.THREAD_PAYLOAD) # Select groups which should be selected by kickstart try: for group in self.payload.selectedGroupsIDs(): if self.environment and self.payload.environmentOptionIsDefault(self.environment, group): self._addonStates[group] = self._ADDON_DEFAULT else: self._addonStates[group] = self._ADDON_SELECTED except PayloadError as e: # Group translation is not supported log.warning(e) # It's better to have all or nothing selected from kickstart self._addonStates = {} if not self._kickstarted: # having done all the slow downloading, we need to do the first refresh # of the UI here so there's an environment selected by default. This # happens inside the main thread by necessity. We can't do anything # that takes any real amount of time, or it'll block the UI from # updating. if not self._first_refresh(): return hubQ.send_ready(self.__class__.__name__, False) # If packages were provided by an input kickstart file (or some other means), # we should do dependency solving here. if not self._error: self._apply() # report that software spoke initialization has been completed self.initialize_done()
def refresh(self, args=None): EditTUISpoke.refresh(self, args) threadMgr.wait(THREAD_PAYLOAD) _methods = [_("CD/DVD"), _("local ISO file"), _("Network")] if self.data.method.method == "harddrive" and \ get_mount_device(DRACUT_ISODIR) == get_mount_device(DRACUT_REPODIR): message = _( "The installation source is in use by the installer and cannot be changed." ) self._window += [TextWidget(message), ""] return True if args == 3: text = [TextWidget(_(p)) for p in self._protocols] else: self._window += [ TextWidget(_("Choose an installation source type.")) ] text = [TextWidget(m) for m in _methods] def _prep(i, w): """ Mangle our text to make it look pretty on screen. """ number = TextWidget("%2d)" % (i + 1)) return ColumnWidget([(4, [number]), (None, [w])], 1) # gnarl and mangle all of our widgets so things look pretty on screen choices = [_prep(i, w) for i, w in enumerate(text)] displayed = ColumnWidget([(78, choices)], 1) self._window += [displayed, ""] return True
def _initialize(self): threadMgr.wait(constants.THREAD_PAYLOAD) # Select groups which should be selected by kickstart try: for group in self.payload.selectedGroupsIDs(): if self.environment and self.payload.environmentOptionIsDefault( self.environment, group): self._addonStates[group] = self._ADDON_DEFAULT else: self._addonStates[group] = self._ADDON_SELECTED except PayloadError as e: # Group translation is not supported log.warning(e) # It's better to have all or nothing selected from kickstart self._addonStates = {} if not self._kickstarted: # having done all the slow downloading, we need to do the first refresh # of the UI here so there's an environment selected by default. This # happens inside the main thread by necessity. We can't do anything # that takes any real amount of time, or it'll block the UI from # updating. if not self._first_refresh(): return hubQ.send_ready(self.__class__.__name__, False) # If packages were provided by an input kickstart file (or some other means), # we should do dependency solving here. if not self._error: self._apply() # report that software spoke initialization has been completed self.initialize_done()
def _unregister(self): """Try to unregister a system.""" # update data in the Subscription DBUS module self._set_data_to_module() # disable controls self.set_registration_controls_sensitive(False) # wait for the previous subscription thread to finish threadMgr.wait(THREAD_SUBSCRIPTION) # try to unregister log.debug("Subscription GUI: attempting to unregister") threadMgr.add( AnacondaThread( name=THREAD_SUBSCRIPTION, target=unregister, kwargs={ "payload": self.payload, "overridden_source_type": self._overridden_source_type, "progress_callback": self._subscription_progress_callback, "error_callback": self._subscription_error_callback, "restart_payload": True } ) )
def refresh(self, args=None): """Prepare the content of the screen.""" super().refresh(args) threadMgr.wait(THREAD_STORAGE_WATCHER) # Get the available partitioning. object_path = self._storage_module.CreatedPartitioning[-1] self._partitioning = STORAGE.get_proxy(object_path) # Create a new container. self._container = ListColumnContainer(1, spacing=1) # loop through the disks and present them. for disk_name in self._available_disks: disk_info = self._format_disk_info(disk_name) c = CheckboxWidget(title=disk_info, completed=(disk_name in self._selected_disks)) self._container.add(c, self._update_disk_list_callback, disk_name) # if we have more than one disk, present an option to just # select all disks if len(self._available_disks) > 1: c = CheckboxWidget(title=_("Select all"), completed=self._select_all) self._container.add(c, self._select_all_disks_callback) self.window.add_with_separator(self._container) self.window.add_with_separator(TextWidget(self._update_summary()))
def _register(self): """Try to register a system.""" # update data in the Subscription DBUS module self._set_data_to_module() # disable controls self.set_registration_controls_sensitive(False) # wait for the previous subscription thread to finish threadMgr.wait(THREAD_SUBSCRIPTION) # check if the current installation source will be overriden # and remember it if it is the case source_proxy = self.payload.get_source_proxy() source_type = source_proxy.Type if source_type in SOURCE_TYPES_OVERRIDEN_BY_CDN: self._overridden_source_type = source_type else: # no override will happen, so clear the variable self._overridden_source_type = None # try to register log.debug("Subscription GUI: attempting to register") threadMgr.add( AnacondaThread( name=THREAD_SUBSCRIPTION, target=register_and_subscribe, kwargs={ "payload": self.payload, "progress_callback": self._subscription_progress_callback, "error_callback": self._subscription_error_callback, "restart_payload": True } ) )
def refresh(self, args=None): NormalTUISpoke.refresh(self, args) threadMgr.wait(THREAD_PAYLOAD) self._container = ListColumnContainer(1, columns_width=78, spacing=1) if self.data.method.method == "harddrive" and \ get_mount_device(DRACUT_ISODIR) == get_mount_device(DRACUT_REPODIR): message = _("The installation source is in use by the installer and cannot be changed.") self.window.add_with_separator(TextWidget(message)) return if args == self.SET_NETWORK_INSTALL_MODE: self._container.add(TextWidget(_("Closest mirror")), self._set_network_close_mirror) self._container.add(TextWidget("http://"), self._set_network_url, SpecifyRepoSpoke.HTTP) self._container.add(TextWidget("https://"), self._set_network_url, SpecifyRepoSpoke.HTTPS) self._container.add(TextWidget("ftp://"), self._set_network_url, SpecifyRepoSpoke.FTP) self._container.add(TextWidget("nfs"), self._set_network_nfs) else: self.window.add(TextWidget(_("Choose an installation source type."))) self._container.add(TextWidget(_("CD/DVD")), self._set_cd_install_source) self._container.add(TextWidget(_("local ISO file")), self._set_iso_install_source) self._container.add(TextWidget(_("Network")), self._set_network_install_source) if self._hmc: self._container.add(TextWidget(_("SE/HMC")), self._set_hmc_install_source) self.window.add_with_separator(self._container)
def _initialize(self): threadMgr.wait(THREAD_PAYLOAD) if not self._kickstarted: # If an environment was specified in the instclass, use that. # Otherwise, select the first environment. if self.payload.environments: environments = self.payload.environments instclass = self.payload.instclass if instclass and instclass.defaultPackageEnvironment and \ instclass.defaultPackageEnvironment in environments: self._selected_environment = environments.index(instclass.defaultPackageEnvironment) else: self._selected_environment = 0 # Apply the initial selection self._apply() # Wait for the software selection thread that might be started by _apply(). # We are already running in a thread, so it should not needlessly block anything # and only like this we can be sure we are really initialized. threadMgr.wait(THREAD_CHECK_SOFTWARE) # report that the software spoke has been initialized self.initialize_done()
def time_initialize(timezone, storage, bootloader): """ Try to guess if RTC uses UTC time or not, set timezone.isUtc properly and set system time from RTC using the UTC guess. Guess is done by searching for bootable ntfs devices. :param timezone: ksdata.timezone object :param storage: pyanaconda.storage.InstallerStorage instance :param bootloader: bootloader.Bootloader instance """ if arch.is_s390(): # nothing to do on s390(x) were hwclock doesn't exist return if not timezone.isUtc and not flags.automatedInstall: # if set in the kickstart, no magic needed here threadMgr.wait(THREAD_STORAGE) ntfs_devs = filter(lambda dev: dev.format.name == "ntfs", storage.devices) timezone.isUtc = not bootloader.has_windows(ntfs_devs) cmd = "hwclock" args = ["--hctosys"] if timezone.isUtc: args.append("--utc") else: args.append("--localtime") util.execWithRedirect(cmd, args)
def _initialize(self): """Finish the initialization. This method is expected to run only once during the initialization. """ # Wait for storage. hubQ.send_message(self.__class__.__name__, _(constants.PAYLOAD_STATUS_PROBING_STORAGE)) threadMgr.wait(constants.THREAD_STORAGE) # Automatically format DASDs if allowed. disks = self._disk_select_module.GetUsableDisks() DasdFormatting.run_automatically(disks, self._show_dasdfmt_report) hubQ.send_message(self.__class__.__name__, _(constants.PAYLOAD_STATUS_PROBING_STORAGE)) # Update the selected disks. select_default_disks() # Apply the partitioning. Do not set ready in the automated # installation before the execute method is run. if flags.automatedInstall: self.execute() else: self._ready = True hubQ.send_ready(self.__class__.__name__) # Report that the storage spoke has been initialized. self.initialize_done()
def time_initialize(timezone, storage, bootloader): """ Try to guess if RTC uses UTC time or not, set timezone.isUtc properly and set system time from RTC using the UTC guess. Guess is done by searching for bootable ntfs devices. :param timezone: ksdata.timezone object :param storage: blivet.Blivet instance :param bootloader: bootloader.Bootloader instance """ if arch.is_s390(): # nothing to do on s390(x) were hwclock doesn't exist return if not timezone.isUtc and not flags.automatedInstall: # if set in the kickstart, no magic needed here threadMgr.wait(THREAD_STORAGE) ntfs_devs = filter(lambda dev: dev.format.name == "ntfs", storage.devices) timezone.isUtc = not bootloader.has_windows(ntfs_devs) cmd = "hwclock" args = ["--hctosys"] if timezone.isUtc: args.append("--utc") else: args.append("--localtime") iutil.execWithRedirect(cmd, args)
def update_disks(self): threadMgr.wait(THREAD_STORAGE) self._available_disks = self.storage.usable_disks # if only one disk is available, go ahead and mark it as selected if len(self._available_disks) == 1: self._update_disk_list(self._available_disks[0])
def install(self): """ Install the payload if it is a tar. Otherwise fall back to rsync of INSTALL_TREE """ # If it doesn't look like a tarfile use the super's install() if not self.is_tarfile: super().install() return # Use 2x the archive's size to estimate the size of the install # This is used to drive the progress display self.source_size = os.stat(self.image_path)[stat.ST_SIZE] * 2 self.pct_lock = Lock() self.pct = 0 threadMgr.add(AnacondaThread(name=THREAD_LIVE_PROGRESS, target=self.progress)) # Run the installation task. task = InstallFromTarTask( sysroot=conf.target.system_root, tarfile=self.image_path ) task.run() # Wait for progress thread to finish with self.pct_lock: self.pct = 100 threadMgr.wait(THREAD_LIVE_PROGRESS)
def input(self, args, key): """Grab the disk choice and update things""" self.errors = [] if self._container.process_user_input(key): return InputState.PROCESSED_AND_REDRAW else: if key.lower() == Prompt.CONTINUE: if self._selected_disks: # Is DASD formatting supported? if DasdFormatting.is_supported(): # Wait for storage. threadMgr.wait(THREAD_STORAGE) # Allow to format DASDs. self._disk_init_module.SetFormatUnrecognizedEnabled( True) self._disk_init_module.SetFormatLDLEnabled(True) # Get selected disks. disks = filter_disks_by_names(self._available_disks, self._selected_disks) # Check if some of the disks should be formatted. dasd_formatting = DasdFormatting() dasd_formatting.search_disks(disks) if dasd_formatting.should_run(): # We want to apply current selection before running dasdfmt to # prevent this information from being lost afterward apply_disk_selection(self._selected_disks) # Run the dialog. self.run_dasdfmt_dialog(dasd_formatting) return InputState.PROCESSED_AND_REDRAW # make sure no containers were split up by the user's disk # selection report = ValidationReport.from_structure( self._disk_select_module.ValidateSelectedDisks( self._selected_disks)) self.errors.extend(report.get_messages()) if self.errors: # The disk selection has to make sense before we can # proceed. return InputState.PROCESSED_AND_REDRAW self.apply() new_spoke = PartTypeSpoke(self.data, self.storage, self.payload, self._storage_module, self._partitioning) ScreenHandler.push_screen_modal(new_spoke) self._partitioning = new_spoke.partitioning self.apply() self.execute() return InputState.PROCESSED_AND_CLOSE else: return super().input(args, key)
def _initialize(self): threadMgr.wait(THREAD_PAYLOAD) if not self._kickstarted: # If an environment was specified in the instclass, use that. # Otherwise, select the first environment. if self.payload.environments: environments = self.payload.environments instclass = self.payload.instclass if instclass and instclass.defaultPackageEnvironment and \ instclass.defaultPackageEnvironment in environments: self._selected_environment = instclass.defaultPackageEnvironment else: self._selected_environment = environments[0] # Apply the initial selection self._apply() # Wait for the software selection thread that might be started by _apply(). # We are already running in a thread, so it should not needlessly block anything # and only like this we can be sure we are really initialized. threadMgr.wait(THREAD_CHECK_SOFTWARE) # report that the software spoke has been initialized self.initialize_done()
def time_initialize(timezone_proxy): """ Try to guess if RTC uses UTC time or not, set timezone.isUtc properly and set system time from RTC using the UTC guess. Guess is done by searching for bootable ntfs devices. :param timezone_proxy: DBus proxy of the timezone module """ if arch.is_s390(): # nothing to do on s390(x) were hwclock doesn't exist return if not timezone_proxy.IsUTC and not flags.automatedInstall: # if set in the kickstart, no magic needed here threadMgr.wait(THREAD_STORAGE) bootloader_proxy = STORAGE.get_proxy(BOOTLOADER) is_utc = not bootloader_proxy.DetectWindows() timezone_proxy.SetIsUTC(is_utc) cmd = "hwclock" args = ["--hctosys"] if timezone_proxy.IsUTC: args.append("--utc") else: args.append("--localtime") util.execWithRedirect(cmd, args)
def refresh(self, args=None): NormalTUISpoke.refresh(self, args) threadMgr.wait(THREAD_PAYLOAD) self._container = ListColumnContainer(1, columns_width=78, spacing=1) if self.data.method.method == "harddrive" and \ get_mount_device(DRACUT_ISODIR) == get_mount_device(DRACUT_REPODIR): message = _("The installation source is in use by the installer and cannot be changed.") self.window.add_with_separator(TextWidget(message)) return if args == self.SET_NETWORK_INSTALL_MODE: if self.payload.mirrors_available: self._container.add(TextWidget(_("Closest mirror")), self._set_network_close_mirror) self._container.add(TextWidget("http://"), self._set_network_url, SpecifyRepoSpoke.HTTP) self._container.add(TextWidget("https://"), self._set_network_url, SpecifyRepoSpoke.HTTPS) self._container.add(TextWidget("ftp://"), self._set_network_url, SpecifyRepoSpoke.FTP) self._container.add(TextWidget("nfs"), self._set_network_nfs) else: self.window.add(TextWidget(_("Choose an installation source type."))) self._container.add(TextWidget(_("CD/DVD")), self._set_cd_install_source) self._container.add(TextWidget(_("local ISO file")), self._set_iso_install_source) self._container.add(TextWidget(_("Network")), self._set_network_install_source) if self._hmc: self._container.add(TextWidget(_("SE/HMC")), self._set_hmc_install_source) self.window.add_with_separator(self._container)
def refresh(self): """ The refresh method that is called every time the spoke is displayed. It should update the UI elements according to the contents of self.data. :see: pyanaconda.ui.common.UIObject.refresh """ for thread_name in [THREAD_EXECUTE_STORAGE, THREAD_STORAGE]: threadMgr.wait(thread_name) if not self._partitioning: # Create the partitioning now. It cannot by done earlier, because # the storage spoke would use it as a default partitioning. self._partitioning = create_partitioning( PARTITIONING_METHOD_BLIVET) self._device_tree = STORAGE.get_proxy( self._partitioning.GetDeviceTree()) self._back_already_clicked = False self._client.initialize(self._partitioning.SendRequest) self._blivetgui.initialize() # if we re-enter blivet-gui spoke, actions from previous visit were # not removed, we need to update number of blivet-gui actions self._blivetgui.set_actions(self._client.get_actions())
def refresh(self): super().refresh() threadMgr.wait(THREAD_PAYLOAD) # Create a new software selection cache. self._selection_cache = SoftwareSelectionCache(self._dnf_manager) self._selection_cache.apply_selection_data(self._selection) # Refresh up the UI. self._refresh_environments() self._refresh_groups() # Set up the info bar. self.clear_info() if self._errors: self.set_warning(_( "Error checking software dependencies. " " <a href=\"\">Click for details.</a>" )) elif self._warnings: self.set_warning(_( "Warning checking software dependencies. " " <a href=\"\">Click for details.</a>" ))
def refresh(self, args=None): NormalTUISpoke.refresh(self, args) threadMgr.wait(THREAD_PAYLOAD) self._container = ListColumnContainer(1, columns_width=78, spacing=1) if args == self.SET_NETWORK_INSTALL_MODE: if conf.payload.enable_closest_mirror: self._container.add(TextWidget(_("Closest mirror")), self._set_network_close_mirror) self._container.add(TextWidget("http://"), self._set_network_url, SpecifyRepoSpoke.HTTP) self._container.add(TextWidget("https://"), self._set_network_url, SpecifyRepoSpoke.HTTPS) self._container.add(TextWidget("ftp://"), self._set_network_url, SpecifyRepoSpoke.FTP) self._container.add(TextWidget("nfs"), self._set_network_nfs) else: self.window.add( TextWidget(_("Choose an installation source type."))) self._container.add(TextWidget(_("CD/DVD")), self._set_cd_install_source) self._container.add(TextWidget(_("local ISO file")), self._set_iso_install_source) self._container.add(TextWidget(_("Network")), self._set_network_install_source) if self._hmc: self._container.add(TextWidget(_("SE/HMC")), self._set_hmc_install_source) self.window.add_with_separator(self._container)
def refresh(self, args=None): """ Refresh screen. """ NormalTUISpoke.refresh(self, args) self._container = None if not self._source_is_set: message = TextWidget( _("Installation source needs to be set up first.")) self.window.add_with_separator(message) return threadMgr.wait(THREAD_CHECK_SOFTWARE) self._container = ListColumnContainer(columns=2, columns_width=38, spacing=2) for environment in self._selection_cache.available_environments: data = self._dnf_manager.get_environment_data(environment) selected = self._selection_cache.is_environment_selected( environment) widget = CheckboxWidget(title=data.name, completed=selected) self._container.add(widget, callback=self._select_environment, data=data.id) self.window.add_with_separator(TextWidget(_("Base environment"))) self.window.add_with_separator(self._container)
def time_initialize(timezone_proxy, storage): """ Try to guess if RTC uses UTC time or not, set timezone.isUtc properly and set system time from RTC using the UTC guess. Guess is done by searching for bootable ntfs devices. :param timezone_proxy: DBus proxy of the timezone module :param storage: pyanaconda.storage.InstallerStorage instance """ if arch.is_s390(): # nothing to do on s390(x) were hwclock doesn't exist return if not timezone_proxy.IsUTC and not flags.automatedInstall: # if set in the kickstart, no magic needed here threadMgr.wait(THREAD_STORAGE) ntfs_devs = filter(lambda dev: dev.format.name == "ntfs", storage.devices) timezone_proxy.SetIsUTC(not storage.bootloader.has_windows(ntfs_devs)) cmd = "hwclock" args = ["--hctosys"] if timezone_proxy.IsUTC: args.append("--utc") else: args.append("--localtime") util.execWithRedirect(cmd, args)
def refresh(self, args=None): """ Refresh screen. """ NormalTUISpoke.refresh(self, args) threadMgr.wait(THREAD_PAYLOAD) if not self.payload.baseRepo: message = TextWidget( _("Installation source needs to be set up first.")) self._window.append(message) # add some more space below self._window.append(TextWidget("")) return True threadMgr.wait(THREAD_CHECK_SOFTWARE) displayed = [] # Display the environments if args is None: environments = self.payload.environments length = len(environments) msg = _("Base environment") for env in environments: name = self.payload.environmentDescription(env)[0] selected = environments.index(env) == self._selection displayed.append( CheckboxWidget(title="%s" % name, completed=selected)) # Display the add-ons else: length = len(args) if length > 0: msg = _("Add-ons for selected environment") else: msg = _("No add-ons to select.") for addon_id in args: name = self.payload.groupDescription(addon_id)[0] selected = addon_id in self._addons_selection displayed.append( CheckboxWidget(title="%s" % name, completed=selected)) def _prep(i, w): """ Do some format magic for display. """ num = TextWidget("%2d)" % (i + 1)) return ColumnWidget([(4, [num]), (None, [w])], 1) # split list of DE's into two columns mid = length / 2 left = [_prep(i, w) for i, w in enumerate(displayed) if i <= mid] right = [_prep(i, w) for i, w in enumerate(displayed) if i > mid] cw = ColumnWidget([(38, left), (38, right)], 2) self._window += [TextWidget(msg), "", cw, ""] return True
def update_disks(self): threadMgr.wait(THREAD_STORAGE) self.disks = sorted(getDisks(self.storage.devicetree), key=lambda d: d.name) # if only one disk is available, go ahead and mark it as selected if len(self.disks) == 1: self._update_disk_list(self.disks[0])
def _restart_thread(self, storage, ksdata, payload, fallback, checkmount, onlyOnChange): # Wait for the old thread to finish threadMgr.wait(THREAD_PAYLOAD) thread_args = (storage, ksdata, payload, fallback, checkmount, onlyOnChange) # Start a new payload thread threadMgr.add(AnacondaThread(name=THREAD_PAYLOAD, target=self._run_thread, args=thread_args))
def _initialize(self): """Initialize the spoke in a separate thread.""" threadMgr.wait(THREAD_PAYLOAD) # Initialize and check the software selection. self._initialize_selection() # Report that the software spoke has been initialized. self.initialize_done()
def _restart_thread(self, payload, fallback, try_media, only_on_change): # Wait for the old thread to finish threadMgr.wait(THREAD_PAYLOAD) # Start a new payload thread threadMgr.add( AnacondaThread(name=THREAD_PAYLOAD, target=self._run_thread, args=(payload, fallback, try_media, only_on_change)))
def input(self, args, key): """Grab the disk choice and update things""" self.errors = [] if self._container.process_user_input(key): self.redraw() return InputState.PROCESSED else: # TRANSLATORS: 'c' to continue if key.lower() == C_('TUI|Spoke Navigation', 'c'): if self.selected_disks: # Is DASD formatting supported? if DasdFormatting.is_supported(): # Wait for storage. threadMgr.wait(THREAD_STORAGE) # Get selected disks. disks = getDisksByNames(self.disks, self.selected_disks) # Check if some of the disks should be formatted. dasd_formatting = DasdFormatting() dasd_formatting.search_disks(disks) if dasd_formatting.should_run(): # We want to apply current selection before running dasdfmt to # prevent this information from being lost afterward applyDiskSelection(self.storage, self.data, self.selected_disks) # Run the dialog. self.run_dasdfmt_dialog(dasd_formatting) self.redraw() return InputState.PROCESSED # make sure no containers were split up by the user's disk # selection self.errors.extend( checkDiskSelection(self.storage, self.selected_disks)) if self.errors: # The disk selection has to make sense before we can # proceed. self.redraw() return InputState.PROCESSED self.apply() new_spoke = PartTypeSpoke(self.data, self.storage, self.payload, self.instclass) ScreenHandler.push_screen_modal(new_spoke) self.apply() self.execute() self.close() return InputState.PROCESSED else: return super().input(args, key)
def unset_source(self): """Unset an already selected source method. Unset the source in kickstart and notify the payload so that it can correctly release all related resources (unmount iso files, drop caches, etc.). """ self._clean_hdd_iso() self.data.method.method = None payloadMgr.restart_thread(self.payload, checkmount=False) # pylint: disable=no-member threadMgr.wait(constants.THREAD_PAYLOAD_RESTART) threadMgr.wait(constants.THREAD_PAYLOAD)
def unset_source(self): """Unset an already selected source method. Unset the source in kickstart and notify the payload so that it can correctly release all related resources (unmount iso files, drop caches, etc.). """ self._clean_hdd_iso() self.data.method.method = None payloadMgr.restartThread(self.storage, self.data, self.payload, self.instclass, checkmount=False) # pylint: disable=no-member threadMgr.wait(constants.THREAD_PAYLOAD_RESTART) threadMgr.wait(constants.THREAD_PAYLOAD)
def install(self): """ Install the payload. """ if self.source_size <= 0: raise PayloadInstallError("Nothing to install") self.pct_lock = Lock() self.pct = 0 threadMgr.add( AnacondaThread(name=THREAD_LIVE_PROGRESS, target=self.progress)) cmd = "rsync" # preserve: permissions, owners, groups, ACL's, xattrs, times, # symlinks, hardlinks # go recursively, include devices and special files, don't cross # file system boundaries args = [ "-pogAXtlHrDx", "--exclude", "/dev/", "--exclude", "/proc/", "--exclude", "/sys/", "--exclude", "/run/", "--exclude", "/boot/*rescue*", "--exclude", "/etc/machine-id", INSTALL_TREE + "/", util.getSysroot() ] try: rc = util.execWithRedirect(cmd, args) except (OSError, RuntimeError) as e: msg = None err = str(e) log.error(err) else: err = None msg = "%s exited with code %d" % (cmd, rc) log.info(msg) if err or rc == 12: exn = PayloadInstallError(err or msg) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Wait for progress thread to finish with self.pct_lock: self.pct = 100 threadMgr.wait(THREAD_LIVE_PROGRESS) # Live needs to create the rescue image before bootloader is written if not os.path.exists(util.getSysroot() + "/usr/sbin/new-kernel-pkg"): log.error( "new-kernel-pkg does not exist - grubby wasn't installed? skipping" ) return for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) util.execInSysroot("new-kernel-pkg", ["--rpmposttrans", kernel])
def setup(self, args): """Set up the spoke right before it is used.""" super().setup(args) # Join the initialization thread to block on it threadMgr.wait(THREAD_SOFTWARE_WATCHER) # Get the packages configuration. self._selection = self.payload.get_packages_data() return True
def initialize(self): NormalTUISpoke.initialize(self) threadMgr.wait(THREAD_STORAGE) for f in [ "services", "protocols", "group", "man.config", "nsswitch.conf", "selinux", "mke2fs.conf" ]: try: os.symlink('/mnt/runtime/etc/' + f, '/etc/' + f) except OSError: pass
def _initialize(self): """ Private initialize. """ threadMgr.wait(THREAD_PAYLOAD) # Enable the SE/HMC option. if self.payload.source_type == SOURCE_TYPE_HMC: self._hmc = True self._ready = True # report that the source spoke has been initialized self.initialize_done()
def _initialize(self): """Initialize the spoke in a separate thread.""" threadMgr.wait(THREAD_PAYLOAD) # Initialize and check the software selection. self._initialize_selection() # Update the status. hubQ.send_ready(self.__class__.__name__) # Report that the software spoke has been initialized. self.initialize_done()
def install(self): """ Install the payload if it is a tar. Otherwise fall back to rsync of INSTALL_TREE """ # If it doesn't look like a tarfile use the super's install() if not self.is_tarfile: super().install() return # Use 2x the archive's size to estimate the size of the install # This is used to drive the progress display self.source_size = os.stat(self.image_path)[stat.ST_SIZE] * 2 self.pct_lock = Lock() self.pct = 0 threadMgr.add( AnacondaThread(name=THREAD_LIVE_PROGRESS, target=self.progress)) cmd = "tar" # preserve: ACL's, xattrs, and SELinux context args = [ "--selinux", "--acls", "--xattrs", "--xattrs-include", "*", "--exclude", "/dev/", "--exclude", "/proc/", "--exclude", "/sys/", "--exclude", "/run/", "--exclude", "/boot/*rescue*", "--exclude", "/etc/machine-id", "-xaf", self.image_path, "-C", util.getSysroot() ] try: rc = util.execWithRedirect(cmd, args) except (OSError, RuntimeError) as e: msg = None err = str(e) log.error(err) else: err = None msg = "%s exited with code %d" % (cmd, rc) log.info(msg) if err: exn = PayloadInstallError(err or msg) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Wait for progress thread to finish with self.pct_lock: self.pct = 100 threadMgr.wait(THREAD_LIVE_PROGRESS) # Live needs to create the rescue image before bootloader is written for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) util.execInSysroot("new-kernel-pkg", ["--rpmposttrans", kernel])
def install(self): """ Install the payload if it is a tar. Otherwise fall back to rsync of INSTALL_TREE """ # If it doesn't look like a tarfile use the super's install() if not self.is_tarfile: super().install() return # Use 2x the archive's size to estimate the size of the install # This is used to drive the progress display self.source_size = os.stat(self.image_path)[stat.ST_SIZE] * 2 self.pct_lock = Lock() self.pct = 0 threadMgr.add(AnacondaThread(name=THREAD_LIVE_PROGRESS, target=self.progress)) cmd = "tar" # preserve: ACL's, xattrs, and SELinux context args = ["--selinux", "--acls", "--xattrs", "--xattrs-include", "*", "--exclude", "/dev/", "--exclude", "/proc/", "--exclude", "/sys/", "--exclude", "/run/", "--exclude", "/boot/*rescue*", "--exclude", "/etc/machine-id", "-xaf", self.image_path, "-C", util.getSysroot()] try: rc = util.execWithRedirect(cmd, args) except (OSError, RuntimeError) as e: msg = None err = str(e) log.error(err) else: err = None msg = "%s exited with code %d" % (cmd, rc) log.info(msg) if err: exn = PayloadInstallError(err or msg) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Wait for progress thread to finish with self.pct_lock: self.pct = 100 threadMgr.wait(THREAD_LIVE_PROGRESS) # Live needs to create the rescue image before bootloader is written for kernel in self.kernel_version_list: log.info("Generating rescue image for %s", kernel) util.execInSysroot("new-kernel-pkg", ["--rpmposttrans", kernel])
def install(self): """ Install the payload. """ if self.source_size <= 0: raise PayloadInstallError("Nothing to install") self.pct_lock = Lock() self.pct = 0 threadMgr.add(AnacondaThread(name=THREAD_LIVE_PROGRESS, target=self.progress)) cmd = "rsync" # preserve: permissions, owners, groups, ACL's, xattrs, times, # symlinks, hardlinks # go recursively, include devices and special files, don't cross # file system boundaries args = ["-pogAXtlHrDx", "--exclude", "/dev/", "--exclude", "/proc/", "--exclude", "/sys/", "--exclude", "/run/", "--exclude", "/boot/*rescue*", "--exclude", "/etc/machine-id", INSTALL_TREE + "/", iutil.getSysroot()] try: rc = iutil.execWithRedirect(cmd, args) except (OSError, RuntimeError) as e: msg = None err = str(e) log.error(err) else: err = None msg = "%s exited with code %d" % (cmd, rc) log.info(msg) if err or rc == 12: exn = PayloadInstallError(err or msg) if errorHandler.cb(exn) == ERROR_RAISE: raise exn # Wait for progress thread to finish with self.pct_lock: self.pct = 100 threadMgr.wait(THREAD_LIVE_PROGRESS) # Live needs to create the rescue image before bootloader is written if not os.path.exists(iutil.getSysroot() + "/usr/sbin/new-kernel-pkg"): log.error("new-kernel-pkg does not exist - grubby wasn't installed? skipping") return for kernel in self.kernelVersionList: log.info("Generating rescue image for %s", kernel) iutil.execInSysroot("new-kernel-pkg", ["--rpmposttrans", kernel])
def input(self, args, key): """Grab the disk choice and update things""" self.errors = [] if self._container.process_user_input(key): return InputState.PROCESSED_AND_REDRAW else: # TRANSLATORS: 'c' to continue if key.lower() == C_('TUI|Spoke Navigation', 'c'): if self._selected_disks: # Is DASD formatting supported? if DasdFormatting.is_supported(): # Wait for storage. threadMgr.wait(THREAD_STORAGE) # Get selected disks. disks = filter_disks_by_names(self._available_disks, self._selected_disks) # Check if some of the disks should be formatted. dasd_formatting = DasdFormatting() dasd_formatting.search_disks(disks) if dasd_formatting.should_run(): # We want to apply current selection before running dasdfmt to # prevent this information from being lost afterward apply_disk_selection(self.storage, self._selected_disks) # Run the dialog. self.run_dasdfmt_dialog(dasd_formatting) return InputState.PROCESSED_AND_REDRAW # make sure no containers were split up by the user's disk # selection self.errors.extend(check_disk_selection(self.storage, self._selected_disks)) if self.errors: # The disk selection has to make sense before we can # proceed. return InputState.PROCESSED_AND_REDRAW self.apply() new_spoke = PartTypeSpoke(self.data, self.storage, self.payload) ScreenHandler.push_screen_modal(new_spoke) self.apply() self.execute() return InputState.PROCESSED_AND_CLOSE else: return super().input(args, key)
def checkStorage(self): from pyanaconda.storage_utils import storage_checker threadMgr.wait(constants.THREAD_EXECUTE_STORAGE) hubQ.send_not_ready(self._mainSpokeClass) hubQ.send_message(self._mainSpokeClass, _("Checking storage configuration...")) report = storage_checker.check(self.storage) # Storage spoke and custom spoke communicate errors via StorageCheckHandler, # so we need to set errors and warnings class attributes here. StorageCheckHandler.errors = report.errors StorageCheckHandler.warnings = report.warnings hubQ.send_ready(self._mainSpokeClass, True) report.log(self.log)
def refresh(self): super().refresh() threadMgr.wait(constants.THREAD_PAYLOAD) first_environment = True self._clear_listbox(self._environment_list_box) # If no environment is selected, use the default from the config. # If nothing is set in the config, the first environment will be # selected below. if not self.environment and conf.payload.default_environment in self.payload.environments: self.environment = conf.payload.default_environment # create rows for all valid environments for environment_id in self.payload.environments: (name, desc) = self.payload.environment_description(environment_id) # use the invisible radio button as a group for all environment # radio buttons radio = Gtk.RadioButton(group=self._fake_radio) # automatically select the first environment if we are on # manual install and the configuration does not specify one if first_environment and not flags.automatedInstall: # manual installation # # Note about self.environment being None: # ======================================= # None indicates that an environment has not been set, which is a valid # value of the environment variable. # Only non existing environments are evaluated as invalid if not self.environment_valid or self.environment is None: self.environment = environment_id first_environment = False # check if the selected environment (if any) does match the current row # and tick the radio button if it does radio.set_active(self.environment_valid and self.environment_id == environment_id) self._add_row(self._environment_list_box, name, desc, radio, self.on_radio_button_toggled) self.refresh_addons() self._environment_list_box.show_all() self._addon_list_box.show_all()
def _initialize(self): # a bit hacky way, but should return the translated strings for i in range(1, 32): day = datetime.date(2000, 1, i).strftime(self._day_format) self.add_to_store_idx(self._daysStore, i, day) for i in range(1, 13): month = datetime.date(2000, i, 1).strftime(self._month_format) self.add_to_store_idx(self._monthsStore, i, month) for i in range(1990, 2051): year = datetime.date(i, 1, 1).strftime(self._year_format) self.add_to_store_idx(self._yearsStore, i, year) cities = set() xlated_regions = ((region, get_xlated_timezone(region)) for region in self._regions_zones.keys()) for region, xlated in sorted(xlated_regions, key=functools.cmp_to_key(_compare_regions)): self.add_to_store_xlated(self._regionsStore, region, xlated) for city in self._regions_zones[region]: cities.add((city, get_xlated_timezone(city))) for city, xlated in sorted(cities, key=functools.cmp_to_key(_compare_cities)): self.add_to_store_xlated(self._citiesStore, city, xlated) self._update_datetime_timer = None kickstart_timezone = self._timezone_module.proxy.Timezone if is_valid_timezone(kickstart_timezone): self._set_timezone(kickstart_timezone) elif not flags.flags.automatedInstall: log.warning("%s is not a valid timezone, falling back to default (%s)", kickstart_timezone, DEFAULT_TZ) self._set_timezone(DEFAULT_TZ) self._timezone_module.proxy.SetTimezone(DEFAULT_TZ) time_init_thread = threadMgr.get(constants.THREAD_TIME_INIT) if time_init_thread is not None: hubQ.send_message(self.__class__.__name__, _("Restoring hardware time...")) threadMgr.wait(constants.THREAD_TIME_INIT) hubQ.send_ready(self.__class__.__name__, False) # report that we are done self.initialize_done()
def refresh(self, args=None): """ Refresh screen. """ NormalTUISpoke.refresh(self, args) threadMgr.wait(THREAD_PAYLOAD) self._container = None if not self.payload.baseRepo: message = TextWidget(_("Installation source needs to be set up first.")) self.window.add_with_separator(message) return threadMgr.wait(THREAD_CHECK_SOFTWARE) self._container = ListColumnContainer(2, columns_width=38, spacing=2) # Display the environments if args is None: environments = self.payload.environments msg = _("Base environment") for env in environments: name = self.payload.environmentDescription(env)[0] selected = (env == self._selected_environment) widget = CheckboxWidget(title="%s" % name, completed=selected) self._container.add(widget, callback=self._set_environment_callback, data=env) # Display the add-ons else: length = len(args) if length > 0: msg = _("Add-ons for selected environment") else: msg = _("No add-ons to select.") for addon_id in args: name = self.payload.groupDescription(addon_id)[0] selected = addon_id in self._addons_selection widget = CheckboxWidget(title="%s" % name, completed=selected) self._container.add(widget, callback=self._set_addons_callback, data=addon_id) self.window.add_with_separator(TextWidget(msg)) self.window.add_with_separator(self._container)
def _initialize(self): """ Secondary initialize so wait for the storage thread to complete before populating our disk list """ threadMgr.wait(THREAD_STORAGE) self.disks = sorted(getDisks(self.storage.devicetree), key=lambda d: d.name) # if only one disk is available, go ahead and mark it as selected if len(self.disks) == 1: self._update_disk_list(self.disks[0]) self._update_summary() self._ready = True # report that the storage spoke has been initialized self.initialize_done()
def _initialize(self): """ Private initialize. """ threadMgr.wait(THREAD_PAYLOAD) # 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) # Enable the SE/HMC option. if flags.hmc: self._hmc = True self._ready = True # report that the source spoke has been initialized self.initialize_done()
def refresh(self, args=None): """ Refresh screen. """ NormalTUISpoke.refresh(self, args) threadMgr.wait(THREAD_PAYLOAD) self._container = None if not self.payload.baseRepo: message = TextWidget(_("Installation source needs to be set up first.")) self.window.add_with_separator(message) return threadMgr.wait(THREAD_CHECK_SOFTWARE) self._container = ListColumnContainer(2, columns_width=38, spacing=2) if args is None: msg = self._refresh_environments() else: msg = self._refresh_addons(args) self.window.add_with_separator(TextWidget(msg)) self.window.add_with_separator(self._container)
def _initialize(self): """ Secondary initialize so wait for the storage thread to complete before populating our disk list """ # Wait for storage. threadMgr.wait(THREAD_STORAGE) # Automatically format DASDs if allowed. DasdFormatting.run_automatically(self.storage, self.data) # Update the selected disks. if flags.automatedInstall: self._selected_disks = select_all_disks_by_default(self.storage) # Update disk list. self.update_disks() # Storage is ready. self._ready = True # Report that the storage spoke has been initialized. self.initialize_done()
def refresh(self): """ The refresh method that is called every time the spoke is displayed. It should update the UI elements according to the contents of self.data. :see: pyanaconda.ui.common.UIObject.refresh """ for thread_name in [THREAD_EXECUTE_STORAGE, THREAD_STORAGE]: threadMgr.wait(thread_name) self._back_already_clicked = False self._storage_playground = self.storage.copy() self.client.initialize(self._storage_playground) self.blivetgui.initialize() # if we re-enter blivet-gui spoke, actions from previous visit were # not removed, we need to update number of blivet-gui actions current_actions = self._storage_playground.devicetree.actions.find() if current_actions: self.blivetgui.set_actions(current_actions)
def run_dasdfmt(self, to_format): """ This generates the list of DASDs requiring dasdfmt and runs dasdfmt against them. """ # if the storage thread is running, wait on it to complete before taking # any further actions on devices; most likely to occur if user has # zerombr in their ks file threadMgr.wait(THREAD_STORAGE) # ask user to verify they want to format if zerombr not in ks file if not self.data.zerombr.zerombr: # prepare our msg strings; copied directly from dasdfmt.glade summary = _("The following unformatted DASDs have been detected on your system. You can choose to format them now with dasdfmt or cancel to leave them unformatted. Unformatted DASDs cannot be used during installation.\n\n") warntext = _("Warning: All storage changes made using the installer will be lost when you choose to format.\n\nProceed to run dasdfmt?\n") displaytext = summary + "\n".join("/dev/" + d.name for d in to_format) + "\n" + warntext # now show actual prompt; note -- in cmdline mode, auto-answer for # this is 'no', so unformatted DASDs will remain so unless zerombr # is added to the ks file question_window = YesNoDialog(displaytext) ScreenHandler.push_screen_modal(question_window) if not question_window.answer: # no? well fine then, back to the storage spoke with you; return None for disk in to_format: try: print(_("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
services_proxy = SERVICES.get_proxy() if services_proxy.SetupOnBoot == SETUP_ON_BOOT_DEFAULT: if flags.automatedInstall: # Disable by default after kickstart installations. services_proxy.SetSetupOnBoot(SETUP_ON_BOOT_DISABLED) # Create pre-install snapshots from pykickstart.constants import SNAPSHOT_WHEN_PRE_INSTALL from pyanaconda.kickstart import check_kickstart_error from pyanaconda.modules.common.constants.objects import SNAPSHOT snapshot_proxy = STORAGE.get_proxy(SNAPSHOT) if snapshot_proxy.IsRequested(SNAPSHOT_WHEN_PRE_INSTALL): # What for the storage to load devices. # FIXME: Don't block the main thread! threadMgr.wait(constants.THREAD_STORAGE) # Prepare the requests. requests = ksdata.snapshot.get_requests(SNAPSHOT_WHEN_PRE_INSTALL) # Run the tasks. with check_kickstart_error(): from pyanaconda.modules.storage.snapshot.create import SnapshotCreateTask SnapshotCreateTask(anaconda.storage, requests, SNAPSHOT_WHEN_PRE_INSTALL).run() anaconda.intf.setup(ksdata) anaconda.intf.run() # vim:tw=78:ts=4:et:sw=4
def _init_after_data_fetch(self, wait_for): """ Waits for data fetching to be finished, extracts it (if needed), populates the stores and evaluates pre-installation fixes from the content and marks the spoke as ready in the end. :param wait_for: name of the thread to wait for (if any) :type wait_for: str or None """ try: threadMgr.wait(wait_for) except data_fetch.DataFetchError: self._data_fetch_failed() with self._fetch_flag_lock: self._fetching = False return finally: # stop the spinner in any case fire_gtk_action(self._progress_spinner.stop) if self._addon_data.fingerprint: hash_obj = utils.get_hashing_algorithm(self._addon_data.fingerprint) digest = utils.get_file_fingerprint(self._addon_data.raw_preinst_content_path, hash_obj) if digest != self._addon_data.fingerprint: self._integrity_check_failed() # fetching done with self._fetch_flag_lock: self._fetching = False return # RPM is an archive at this phase if self._addon_data.content_type in ("archive", "rpm"): # extract the content try: fpaths = common.extract_data(self._addon_data.raw_preinst_content_path, common.INSTALLATION_CONTENT_DIR, [self._addon_data.content_path]) except common.ExtractionError as err: self._extraction_failed(str(err)) # fetching done with self._fetch_flag_lock: self._fetching = False return # and populate missing fields self._content_handling_cls, files = content_handling.explore_content_files(fpaths) files = common.strip_content_dir(files) # pylint: disable-msg=E1103 self._addon_data.content_path = self._addon_data.content_path or files.xccdf self._addon_data.cpe_path = self._addon_data.cpe_path or files.cpe self._addon_data.tailoring_path = (self._addon_data.tailoring_path or files.tailoring) elif self._addon_data.content_type == "datastream": self._content_handling_cls = content_handling.DataStreamHandler elif self._addon_data.content_type == "scap-security-guide": self._content_handling_cls = content_handling.BenchmarkHandler else: raise common.OSCAPaddonError("Unsupported content type") try: self._content_handler = self._content_handling_cls(self._addon_data.preinst_content_path, self._addon_data.preinst_tailoring_path) except content_handling.ContentHandlingError: self._invalid_content() # fetching done with self._fetch_flag_lock: self._fetching = False return if self._using_ds: # populate the stores from items from the content self._ds_checklists = self._content_handler.get_data_streams_checklists() add_ds_ids = GtkActionList() add_ds_ids.add_action(self._ds_store.clear) for dstream in self._ds_checklists.keys(): add_ds_ids.add_action(self._add_ds_id, dstream) add_ds_ids.fire() self._update_ids_visibility() # refresh UI elements self.refresh() # let all initialization and configuration happen before we evaluate # the setup if not self._anaconda_spokes_initialized.is_set(): # only wait (and log the messages) if the event is not set yet log.debug("OSCAP addon: waiting for all Anaconda spokes to be initialized") self._anaconda_spokes_initialized.wait() log.debug("OSCAP addon: all Anaconda spokes have been initialized - continuing") # try to switch to the chosen profile (if any) selected = self._switch_profile() if self._addon_data.profile_id and not selected: # profile ID given, but it was impossible to select it -> invalid # profile ID given self._invalid_profile_id() return # initialize the self._addon_data.rule_data self._addon_data.rule_data = self._rule_data # update the message store with the messages self._update_message_store() # all initialized, we can now let user set parameters fire_gtk_action(self._main_notebook.set_current_page, SET_PARAMS_PAGE) # and use control buttons fire_gtk_action(really_show, self._control_buttons) # fetching done with self._fetch_flag_lock: self._fetching = False # no error self._set_error(None)
def initialize(self): threadMgr.wait(THREAD_STORAGE) create_etc_symlinks()
def wait_initialize(self): threadMgr.wait(THREAD_ADD_LAYOUTS_INIT)
def _run_thread(self, storage, ksdata, payload, fallback, checkmount, onlyOnChange): # This is the thread entry # Set the initial state self._error = None self._set_state(PayloadState.STARTED) # Wait for storage self._set_state(PayloadState.WAITING_STORAGE) threadMgr.wait(THREAD_STORAGE) # Wait for network self._set_state(PayloadState.WAITING_NETWORK) # FIXME: condition for cases where we don't want network # (set and use payload.needs_network ?) threadMgr.wait(THREAD_WAIT_FOR_CONNECTING_NM) payload.setup(storage) # If this is a non-package Payload, we're done if not isinstance(payload, PackagePayload): self._set_state(PayloadState.FINISHED) return # Test if any repository changed from the last update if onlyOnChange: log.debug("Testing repositories availability") self._set_state(PayloadState.VERIFYING_AVAILABILITY) if payload.verify_available_repositories(): log.debug("Payload isn't restarted, repositories are still available.") self._set_state(PayloadState.FINISHED) return # Keep setting up package-based repositories # Download package metadata self._set_state(PayloadState.DOWNLOADING_PKG_METADATA) try: payload.update_base_repo(fallback=fallback, checkmount=checkmount) payload.add_driver_repos() except (OSError, PayloadError) as e: log.error("PayloadError: %s", e) self._error = self.ERROR_SETUP self._set_state(PayloadState.ERROR) payload.unsetup() return # Gather the group data self._set_state(PayloadState.DOWNLOADING_GROUP_METADATA) payload.gather_repo_metadata() payload.release() # Check if that failed if not payload.base_repo: log.error("No base repo configured") self._error = self.ERROR_MD self._set_state(PayloadState.ERROR) payload.unsetup() return # run payload specific post configuration tasks payload.post_setup() self._set_state(PayloadState.FINISHED)