def check_disk_selection(storage, selected_disks): """Return a list of errors related to a proposed disk selection. :param storage: blivet.Blivet instance :param selected_disks: names of selected disks :type selected_disks: list of str :returns: a list of error messages :rtype: list of str """ errors = [] for name in selected_disks: selected = storage.devicetree.get_device_by_name(name, hidden=True) related = sorted(storage.devicetree.get_related_disks(selected), key=lambda d: d.name) missing = [r.name for r in related if r.name not in selected_disks] if not missing: continue errors.append(P_( "You selected disk %(selected)s, which contains " "devices that also use unselected disk " "%(unselected)s. You must select or de-select " "these disks as a set.", "You selected disk %(selected)s, which contains " "devices that also use unselected disks " "%(unselected)s. You must select or de-select " "these disks as a set.", len(missing)) % { "selected": selected.name, "unselected": ",".join(missing) }) return errors
def _update_summary(self): """ Update the summary based on the UI. """ count = 0 capacity = 0 free = Size(0) # pass in our disk list so hidden disks' free space is available free_space = self.storage.get_free_space(disks=self.disks) selected = [d for d in self.disks if d.name in self.selected_disks] for disk in selected: capacity += disk.size free += free_space[disk.name][0] count += 1 summary = (P_(("%d disk selected; %s capacity; %s free ..."), ("%d disks selected; %s capacity; %s free ..."), count) % (count, str(Size(capacity)), free)) if len(self.disks) == 0: summary = _( "No disks detected. Please shut down the computer, connect at least one disk, and restart to complete installation." ) elif count == 0: summary = (_( "No disks selected; please select at least one disk to install to." )) # Append storage errors to the summary if self.errors: summary = summary + "\n" + "\n".join(self.errors) elif self.warnings: summary = summary + "\n" + "\n".join(self.warnings) return summary
def _update_progress(self): if self._terminate: # give users time to realize they should stop typing time.sleep(3) Gtk.main_quit() # remove the method from idle queue return False else: self._num_loops += 1 current_entropy = get_current_entropy() current_fraction = min( float(current_entropy) / self._desired_entropy, 1.0) remaining = (MAX_ENTROPY_WAIT * 1000 - self._num_loops * LOOP_TIMEOUT) / 1000 / 60.0 self._progress_bar.set_fraction(current_fraction) self._progress_bar.set_text( "%(pct)d %% (%(rem)d %(min)s remaining)" % { "pct": (int(current_fraction * 100)), "rem": math.ceil(remaining), "min": P_("minute", "minutes", int(remaining)) }) # if we have enough our time ran out, terminate the dialog, but let # the progress_bar refresh in the main loop self._terminate = (current_entropy >= self._desired_entropy) or (remaining <= 0) self.force_cont = (remaining <= 0) # keep updating return True
def connectToView(self): """Attempt to connect to self.vncconnecthost""" maxTries = 10 self.log.info(_("Attempting to connect to vnc client on host %s..."), self.vncconnecthost) if self.vncconnectport != "": hostarg = self.vncconnecthost + ":" + self.vncconnectport else: hostarg = self.vncconnecthost vncconfigcommand = [self.root + "/usr/bin/vncconfig", "-display", ":%s" % constants.X_DISPLAY_NUMBER, "-connect", hostarg] for _i in range(maxTries): vncconfp = util.startProgram(vncconfigcommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # vncconfig process err = vncconfp.communicate()[1].decode("utf-8") if err == '': self.log.info(_("Connected!")) return True elif err.startswith("connecting") and err.endswith("failed\n"): self.log.info(_("Will try to connect again in 15 seconds...")) time.sleep(15) continue else: log.critical(err) util.ipmi_abort(scripts=self.anaconda.ksdata.scripts) sys.exit(1) self.log.error(P_("Giving up attempting to connect after %d try!\n", "Giving up attempting to connect after %d tries!\n", maxTries), maxTries) return False
def _update_labels(self, nDisks=None, totalReclaimable=None, selectedReclaimable=None): if nDisks is not None and totalReclaimable is not None: text = P_("<b>%(count)s disk; %(size)s reclaimable space</b> (in file systems)", "<b>%(count)s disks; %(size)s reclaimable space</b> (in file systems)", nDisks) % {"count" : escape_markup(str(nDisks)), "size" : escape_markup(totalReclaimable)} self._reclaimable_label.set_markup(text) if selectedReclaimable is not None: text = _("Total selected space to reclaim: <b>%s</b>") % \ escape_markup(selectedReclaimable) self._selected_label.set_markup(text)
def get_disks_summary(storage, selected): """Get a summary of the selected disks :param storage: an instance of the storage :param selected: a list of selected disks :return: a string with a summary """ count = len(selected) capacity = sum((disk.size for disk in selected), Size(0)) free_space = storage.get_disk_free_space(selected) return P_("{count} disk selected; {capacity} capacity; {free} free", "{count} disks selected; {capacity} capacity; {free} free", count).format(count=count, capacity=capacity, free=free_space)
def get_disks_summary(disks): """Get a summary of the selected disks :param disks: a list of names of selected disks :return: a string with a summary """ device_tree = STORAGE.get_proxy(DEVICE_TREE) count = len(disks) capacity = Size(device_tree.GetDiskTotalSpace(disks)) free_space = Size(device_tree.GetDiskFreeSpace(disks)) return P_("{count} disk selected; {capacity} capacity; {free} free", "{count} disks selected; {capacity} capacity; {free} free", count).format(count=count, capacity=capacity, free=free_space)
def _update_summary(self): count = 0 size = Size(0) free = Size(0) for row in self._store: count += 1 size += Size(row[SIZE_COL]) free += Size(row[FREE_SPACE_COL]) # pylint: disable=unescaped-markup text = P_( "<b>%(count)d disk; %(size)s capacity; %(free)s free space</b> " "(unpartitioned and in file systems)", "<b>%(count)d disks; %(size)s capacity; %(free)s free space</b> " "(unpartitioned and in file systems)", count) % { "count": count, "size": escape_markup(size), "free": escape_markup(free) } self._summary_label.set_markup(text)
def status(self): """ A short string describing the current status of storage setup. """ msg = _("No disks selected") if flags.automatedInstall and not self.storage.root_device: msg = _("Kickstart insufficient") elif self.data.ignoredisk.onlyuse: msg = P_(("%d disk selected"), ("%d disks selected"), len(self.data.ignoredisk.onlyuse)) % len( self.data.ignoredisk.onlyuse) if self.errors: msg = _("Error checking storage configuration") elif self.warnings: msg = _("Warning checking storage configuration") # Maybe show what type of clearpart and which disks selected? elif self.data.autopart.autopart: msg = _("Automatic partitioning selected") else: msg = _("Custom partitioning selected") return msg
def _tui_wait(msg, desired_entropy): """Tell user we are waiting for entropy""" print(msg) print(_("Entropy can be increased by typing randomly on keyboard")) print( _("After %d minutes, the installation will continue regardless of the " "amount of available entropy") % (MAX_ENTROPY_WAIT / 60)) fd = sys.stdin.fileno() termios_attrs_changed = False try: old = termios.tcgetattr(fd) new = termios.tcgetattr(fd) new[3] = new[3] & ~termios.ICANON & ~termios.ECHO new[6][termios.VMIN] = 1 termios.tcsetattr(fd, termios.TCSANOW, new) termios_attrs_changed = True except termios.error as term_err: if term_err.args[0] == errno.ENOTTY: # "Inappropriate ioctl for device" --> terminal attributes not supported pass else: raise # wait for the entropy to become high enough or time has run out cur_entr = get_current_entropy() secs = 0 while cur_entr < desired_entropy and secs <= MAX_ENTROPY_WAIT: remaining = (MAX_ENTROPY_WAIT - secs) / 60.0 print( _("Available entropy: %(av_entr)s, Required entropy: %(req_entr)s [%(pct)d %%] (%(rem)d %(min)s remaining)" ) % { "av_entr": cur_entr, "req_entr": desired_entropy, "pct": int((float(cur_entr) / desired_entropy) * 100), "min": P_("minute", "minutes", remaining), "rem": math.ceil(remaining) }) time.sleep(1) cur_entr = get_current_entropy() secs += 1 # print the final state as well print( _("Available entropy: %(av_entr)s, Required entropy: %(req_entr)s [%(pct)d %%]" ) % { "av_entr": cur_entr, "req_entr": desired_entropy, "pct": int((float(cur_entr) / desired_entropy) * 100) }) if secs <= MAX_ENTROPY_WAIT: print(_("Enough entropy gathered, please stop typing.")) force_cont = False else: print( _("Giving up, time (%d minutes) ran out.") % (MAX_ENTROPY_WAIT / 60)) force_cont = True # we are done # first let the user notice we are done and stop typing time.sleep(5) # and then just read everything from the input buffer and revert the # termios state data = "have something" while sys.stdin in select.select([sys.stdin], [], [], 0)[0] and data: # just read from stdin and scratch the read data data = sys.stdin.read(1) if termios_attrs_changed: termios.tcsetattr(fd, termios.TCSAFLUSH, old) return force_cont