def __init__(self, controller): self.controller = controller self.spinner = Spinner(controller.loop) self.reboot_btn = Toggleable( ok_btn(_("Reboot Now"), on_press=self.reboot)) self.exit_btn = cancel_btn(_("Exit To Shell"), on_press=self.quit) self.view_log_btn = other_btn(_("View full log"), on_press=self.view_log) self.event_listbox = ListBox() self.event_linebox = MyLineBox(self.event_listbox) self.event_buttons = button_pile([self.view_log_btn]) event_body = [ ('pack', Text("")), ('weight', 1, Padding.center_79(self.event_linebox, min_width=76)), ('pack', Text("")), ('pack', self.event_buttons), ('pack', Text("")), ] self.event_pile = Pile(event_body) self.log_listbox = ListBox() log_linebox = MyLineBox(self.log_listbox, _("Full installer output")) log_body = [ ('weight', 1, log_linebox), ('pack', button_pile([other_btn(_("Close"), on_press=self.close_log)])), ] self.log_pile = Pile(log_body) super().__init__(self.event_pile)
def __init__(self, controller): self.controller = controller self.ongoing = {} # context -> line containing a spinner self.reboot_btn = Toggleable(ok_btn( _("Reboot Now"), on_press=self.reboot)) self.view_error_btn = cancel_btn( _("View error report"), on_press=self.view_error) self.view_log_btn = other_btn( _("View full log"), on_press=self.view_log) self.continue_btn = other_btn( _("Continue"), on_press=self.continue_) self.event_listbox = ListBox() self.event_linebox = MyLineBox(self.event_listbox) self.event_buttons = button_pile([self.view_log_btn]) event_body = [ ('weight', 1, Padding.center_79(self.event_linebox, min_width=76)), ('pack', Text("")), ('pack', self.event_buttons), ('pack', Text("")), ] self.event_pile = Pile(event_body) self.log_listbox = ListBox() log_linebox = MyLineBox(self.log_listbox, _("Full installer output")) log_body = [ ('weight', 1, log_linebox), ('pack', button_pile([other_btn(_("Close"), on_press=self.close_log)])), ] self.log_pile = Pile(log_body) super().__init__(self.event_pile)
def make_serial_choices(self): ssh_password = get_installer_password(self.controller.opts.dry_run) ips = get_global_addresses(self.controller.app) btns = [ other_btn(label="Switch to rich mode", on_press=self.enable_rich), forward_btn(label="Continue in basic mode", on_press=self.choose_language, user_arg='C'), ] widgets = [ Text(""), Text(rewrap(SERIAL_TEXT)), Text(""), ] if ssh_password and ips: widgets.append(Text(rewrap(SSH_TEXT))) widgets.append(Text("")) btns.insert( 1, other_btn(label="View SSH instructions", on_press=self.ssh_help, user_arg=ssh_password)) widgets.extend([ button_pile(btns), ]) lb = ListBox(widgets) return screen(lb, buttons=None)
def __init__(self, controller): self.controller = controller self.spinner = Spinner(controller.loop) self.event_listwalker = SimpleFocusListWalker([]) self.event_listbox = ListBox(self.event_listwalker) self.event_linebox = MyLineBox(self.event_listbox) self.event_buttons = button_pile([other_btn("View full log", on_press=self.view_log)]) event_body = [ ('pack', Text("")), ('weight', 1, Padding.center_79(self.event_linebox)), ('pack', Text("")), ('pack', self.event_buttons), ('pack', Text("")), ] self.event_pile = Pile(event_body) self.log_listwalker = SimpleFocusListWalker([]) self.log_listbox = ListBox(self.log_listwalker) log_linebox = MyLineBox(self.log_listbox, _("Full installer output")) log_body = [ ('weight', 1, log_linebox), ('pack', button_pile([other_btn(_("Close"), on_press=self.close_log)])), ] self.log_pile = Pile(log_body) super().__init__(self.event_pile)
def __init__(self, controller): self.controller = controller super().__init__( screen([ Text(_(fail_text)), Text(""), button_pile([ other_btn(_("Show Error Report"), on_press=self.show_error) ]), ], [other_btn(_("Back"), on_press=self.cancel)]))
def __init__(self, app): self.app = app self.shell_btn = other_btn(_("Switch to a shell"), on_press=self._debug_shell) self.close_btn = other_btn(_("Close"), on_press=self._close) widgets = [ Text(rewrap(_(CLOUD_INIT_FAIL_TEXT))), Text(''), button_pile([self.shell_btn, self.close_btn]), ] super().__init__("", widgets, stretchy_index=0, focus_index=2)
def __init__(self, model, controller, opts): self.model = model self.controller = controller self.opts = opts self.form = KeyboardForm() opts = [] for layout, desc in model.layouts.items(): opts.append(Option((desc, True, layout))) opts.sort(key=lambda o: o.label) connect_signal(self.form, 'submit', self.done) connect_signal(self.form, 'cancel', self.cancel) connect_signal(self.form.layout.widget, "select", self.select_layout) self.form.layout.widget._options = opts setting = model.setting.for_ui() try: self.form.layout.widget.value = setting.layout self.form.variant.widget.value = setting.variant except AttributeError: # Don't crash on pre-existing invalid config. pass lb_contents = self.form.as_rows(self) if not self.opts.run_on_serial: lb_contents.extend([ Text(""), button_pile([ other_btn(label=_("Identify keyboard"), on_press=self.detect) ]), ]) super().__init__(screen(lb_contents, self.form.buttons))
def offer_retry(self): self._w = screen( [Text(_("Sorry, loading snaps from the store failed."))], [ other_btn(label=_("Try again"), on_press=self.load), ok_btn(label=_("Continue"), on_press=self.done), ])
def __init__(self, parent, obj): self.parent = parent self.obj = obj delete_ok, reason = can_delete(obj) if delete_ok: title = _("Confirm deletion of {}").format(obj.desc()) lines = [ _("Do you really want to delete {}?").format(obj.label), "", ] new_lines, delete_funcs = delete_consequences( self.parent.controller, obj) lines.extend(new_lines) self.delete_funcs = delete_funcs else: title = "Cannot delete {}".format(obj.desc()) lines = [ _("Cannot delete {} because {}").format(obj.label, reason) ] delete_btn = danger_btn(label=_("Delete"), on_press=self.confirm) if not delete_ok: delete_btn = WidgetDisable( Color.info_minor(delete_btn.original_widget)) widgets = [ Text("\n".join(lines)), Text(""), button_pile([ delete_btn, other_btn(label=_("Cancel"), on_press=self.cancel), ]), ] super().__init__(title, widgets, 0, 2)
def __init__(self, parent, obj): self.parent = parent self.obj = obj title = _("Confirm deletion of {}").format(obj.desc()) lines = [ _("Do you really want to delete {}?").format(obj.label), "", ] fs = obj.fs() if fs is not None: m = fs.mount() if m is not None: lines.append( _("It is formatted as {fstype} and mounted at " "{path}").format(fstype=fs.fstype, path=m.path)) else: lines.append( _("It is formatted as {fstype} and not mounted.").format( fstype=fs.fstype)) else: lines.append(_("It is not formatted or mounted.")) delete_btn = danger_btn(label=_("Delete"), on_press=self.confirm) widgets = [ Text("\n".join(lines)), Text(""), button_pile([ delete_btn, other_btn(label=_("Cancel"), on_press=self.cancel), ]), ] super().__init__(title, widgets, 0, 2)
def make_language_choices(self): btns = [] current_index = None langs = get_languages() cur = self.cur_lang if cur in ["C.UTF-8", None]: cur = "en_US.UTF-8" for i, (code, native) in enumerate(langs): log.debug("%s", (code, cur)) if code == cur: current_index = i btns.append( forward_btn( label=native, on_press=self.choose_language, user_arg=code)) lb = ListBox(btns) back = None if self.serial: back = other_btn(_("Back"), on_press=self.controller.cancel) if current_index is not None: lb.base_widget.focus_position = current_index return screen( lb, focus_buttons=False, narrow_rows=True, buttons=[back] if back else None, excerpt=_("Use UP, DOWN and ENTER keys to select your language."))
def __init__(self, parent, thing, delete_func): self.parent = parent self.thing = thing self.delete_func = delete_func title = _("Confirm deletion of {}").format(thing.desc()) lines = [ _("Do you really want to delete {}?").format(thing.label), ] if isinstance(thing, Partition): lines.append("") if thing.fs(): fs = thing.fs() desc = _("It is formatted as {}").format(fs.fstype) if fs.mount(): desc += _(" and mounted at {}.").format(fs.mount().path) else: desc += _(" and not mounted.") else: desc = _("It is not formatted.") lines.append(desc) else: raise Exception("deletion of {} not yet supported".format( thing.desc())) widgets = [ Text("\n".join(lines)), Text(""), button_pile([ danger_btn(label=_("Delete"), on_press=self.confirm), other_btn(label=_("Cancel"), on_press=self.cancel), ]), ] super().__init__(title, widgets, 0, 2)
def check_state_available(self, sender=None): self.spinner.stop() rows = [ Text(_("You can read the release notes for each version at:")), Text(""), Text("https://github.com/CanonicalLtd/subiquity/releases", align='center'), Text(""), Text( _("If you choose to update, the update will be downloaded " "and the installation will continue from here."), ), ] buttons = button_pile([ done_btn(_("Update to the new installer"), on_press=self.update), done_btn(_("Continue without updating"), on_press=self.done), other_btn(_("Back"), on_press=self.cancel), ]) buttons.base_widget.focus_position = 1 excerpt = _(self.available_excerpt).format( current=self.controller.status.current_snap_version, new=self.controller.status.new_snap_version) self.title = self.available_title self.controller.ui.set_header(self.available_title) self._w = screen(rows, buttons, excerpt=excerpt) if 'update' in self.controller.answers: if self.controller.answers['update']: self.update() else: self.controller.app.aio_loop.call_soon(self.controller.done)
def __init__(self, controller): self.controller = controller found_disk = False found_ok_disk = False for disk in controller.model.all_disks(): found_disk = True if disk.size > 6 * (2**30): found_ok_disk = True break if found_ok_disk: self.form = GuidedForm(model=controller.model) connect_signal(self.form, 'submit', self.done) connect_signal(self.form, 'cancel', self.cancel) super().__init__( self.form.as_screen(focus_buttons=False, excerpt=_(subtitle))) elif found_disk: super().__init__( screen([Text(rewrap(_(no_big_disks)))], [other_btn(_("OK"), on_press=self.manual)])) else: super().__init__(screen([Text(rewrap(_(no_disks)))], []))
def __init__(self, parent, obj): self.parent = parent self.obj = obj lines = [ Text( _("Do you really want to delete the {desc} {label}?").format( desc=obj.desc(), label=obj.label)), Text(""), ] stretchy_index = 0 fs = obj.fs() if fs is not None: m = fs.mount() if m is not None: lines.append( Text( _("It is formatted as {fstype} and mounted at " "{path}").format(fstype=fs.fstype, path=m.path))) else: lines.append( Text( _("It is formatted as {fstype} and not mounted."). format(fstype=fs.fstype))) elif hasattr(obj, 'partitions') and len(obj.partitions()) > 0: n = len(obj.partitions()) if obj.type == "lvm_volgroup": if n == 1: things = _("logical volume") else: things = _("logical volumes") else: if n == 1: things = _("partition") else: things = _("partitions") lines.append( Text( _("It contains {n} {things}:").format(n=n, things=things))) lines.append(Text("")) stretchy_index = len(lines) rows = [] for p, cells in summarize_device(obj): if p not in [None, obj]: rows.append(TableRow(cells)) lines.append(TablePile(rows)) else: lines.append(Text(_("It is not formatted or mounted."))) delete_btn = danger_btn(label=_("Delete"), on_press=self.confirm) widgets = lines + [ Text(""), button_pile([ delete_btn, other_btn(label=_("Cancel"), on_press=self.cancel), ]), ] super().__init__("", widgets, stretchy_index, len(lines) + 1)
def __init__(self, parent, msg, stderr): self.parent = parent ok = other_btn(label=_("Close"), on_press=self.close) widgets = [ Text(msg), Text(""), Text(stderr.strip('\n')), Text(""), button_pile([ok]), ] super().__init__("", widgets, 2, 4)
def make_body(self): return Pile([ Text(_("Is the following key present on your keyboard?")), Text(""), Text(self.step.symbol, align="center"), Text(""), button_pile([ ok_btn(label=_("Yes"), on_press=self.yes), other_btn(label=_("No"), on_press=self.no), ]), ])
def __init__(self, app, tty): self.app = app self.btn = Toggleable( other_btn(_("Switch to a shell"), on_press=self._debug_shell)) self.btn.enabled = False self.app.aio_loop.call_later(0.5, self._enable) widgets = [ Text(rewrap(_(running_text).format(tty=tty))), Text(''), button_pile([self.btn]), ] super().__init__("", widgets, stretchy_index=0, focus_index=2)
def __init__(self, controller): self.controller = controller self.spinner = Spinner(aio_loop=controller.app.aio_loop, style="dots") self.spinner.start() super().__init__( screen([ Text( _("The installer is probing for block devices to install " "to. Please wait until it completes.")), Text(""), self.spinner, ], [other_btn(_("Back"), on_press=self.cancel)]))
def __init__(self, app, report, interrupting=True): self.app = app self.report = report self.interrupting = interrupting self.btns = { 'cancel': other_btn( _("Cancel upload"), on_press=self.cancel_upload), 'close': close_btn(self, _("Close report")), 'continue': close_btn(self, _("Continue")), 'debug_shell': other_btn( _("Switch to a shell"), on_press=self.debug_shell), 'restart': other_btn( _("Restart the installer"), on_press=self.restart), 'submit': other_btn( _("Send to Canonical"), on_press=self.submit), 'submitted': disabled(other_btn(_("Sent to Canonical"))), 'view': other_btn( _("View full report"), on_press=self.view_report), } w = 0 for n, b in self.btns.items(): w = max(w, widget_width(b)) for n, b in self.btns.items(): self.btns[n] = Padding(b, width=w, align='center') self.spinner = Spinner(app.aio_loop, style='dots') self.pile = Pile([]) self._report_changed() super().__init__("", [self.pile], 0, 0) connect_signal(self, 'closed', self.spinner.stop)
def check_state_checking(self): self.spinner.start() rows = [self.spinner] buttons = [ done_btn(_("Continue without updating"), on_press=self.done), other_btn(_("Back"), on_press=self.cancel), ] self.title = self.checking_title self.controller.ui.set_header(self.title) self._w = screen(rows, buttons, excerpt=_(self.checking_excerpt)) schedule_task(self._wait_check_result())
def update(self, sender=None): self.spinner.stop() self.lb_tasks = ListBox([]) self.task_to_bar = {} buttons = [ other_btn(_("Cancel update"), on_press=self.check_state_available), ] self.controller.ui.set_header(_(self.progress_title)) self._w = screen( self.lb_tasks, buttons, excerpt=_(self.progress_excerpt)) schedule_task(self._update())
def __init__(self, parent, obj, action, whynot): self.parent = parent self.obj = obj title = "Cannot {action} {type}".format(action=_(action.value).lower(), type=labels.desc(obj)) widgets = [ Text(whynot), Text(""), button_pile([ other_btn(label=_("Close"), on_press=self.close), ]), ] super().__init__(title, widgets, 0, 2)
def update_failed(self, msg): self.spinner.stop() rows = [Text(msg)] buttons = button_pile([ done_btn(_("Try again"), on_press=self.try_update_again), done_btn(_("Continue without updating"), on_press=self.done), other_btn(_("Back"), on_press=self.cancel), ]) buttons.base_widget.focus_position = 1 self.title = self.update_failed_title self._w = screen(rows, buttons, excerpt=_(self.update_failed_excerpt))
def __init__(self, model, controller, opts): self.model = model self.controller = controller self.opts = opts self.form = KeyboardForm() opts = [] for layout, desc in model.layouts.items(): opts.append(Option((desc, True, layout))) opts.sort(key=lambda o: o.label.text) connect_signal(self.form, 'submit', self.done) connect_signal(self.form, 'cancel', self.cancel) connect_signal(self.form.layout.widget, "select", self.select_layout) self.form.layout.widget.options = opts setting = model.setting.for_ui() try: self.form.layout.widget.value = setting.layout except AttributeError: # Don't crash on pre-existing invalid config. pass self.select_layout(None, setting.layout) try: self.form.variant.widget.value = setting.variant except AttributeError: # Don't crash on pre-existing invalid config. pass if self.opts.run_on_serial: excerpt = _('Please select the layout of the keyboard directly ' 'attached to the system, if any.') else: excerpt = _('Please select your keyboard layout below, or select ' '"Identify keyboard" to detect your layout ' 'automatically.') lb_contents = self.form.as_rows() if not self.opts.run_on_serial: lb_contents.extend([ Text(""), button_pile([ other_btn(label=_("Identify keyboard"), on_press=self.detect) ]), ]) super().__init__( screen(lb_contents, self.form.buttons, excerpt=excerpt, narrow_rows=True))
def loaded(self): if len(self.snap.channels) == 0: # or other indication of failure ff = FetchingFailed(self, self.snap) self.parent.show_overlay(ff, width=ff.width) else: cur_chan = None if self.snap.name in self.parent.to_install: cur_chan = self.parent.to_install[self.snap.name].channel siv = SnapInfoView(self.parent, self.snap, cur_chan) self.parent.show_screen( screen(siv, [ other_btn(label=_("Close"), on_press=self.parent.show_main_screen) ], focus_buttons=False))
def __init__(self, row, snap): self.row = row self.closed = False text = _("Fetching info for {} failed").format(snap.name) # | text | # 12 34 self.width = len(text) + 4 retry = other_btn(label=_("Try again"), on_press=self.load) cancel = cancel_btn(label=_("Cancel"), on_press=self.close) super().__init__( LineBox( Pile([ ('pack', Text(' ' + text)), ('pack', button_pile([retry, cancel])), ])))
def __init__(self, parent, obj): self.parent = parent self.obj = obj fs = obj.fs() if fs is not None: title = _("Remove filesystem from {device}").format( device=obj.desc()) lines = [ _("Do you really want to remove the existing filesystem " "from {device}?").format(device=obj.label), "", ] m = fs.mount() if m is not None: lines.append( _("It is formatted as {fstype} and mounted at " "{path}").format(fstype=fs.fstype, path=m.path)) else: lines.append( _("It is formatted as {fstype} and not mounted.").format( fstype=fs.fstype)) else: if obj.type == "lvm_volgroup": things = _("logical volumes") else: things = _("partitions") # things is either "logical volumes" or "partitions" title = _("Remove all {things} from {obj}").format(things=things, obj=obj.desc()) lines = [ _("Do you really want to remove all {things} from " "{obj}?").format(things=things, obj=obj.label), "", ] # XXX summarize partitions here? delete_btn = danger_btn(label=_("Reformat"), on_press=self.confirm) widgets = [ Text("\n".join(lines)), Text(""), button_pile([ delete_btn, other_btn(label=_("Cancel"), on_press=self.cancel), ]), ] super().__init__(title, widgets, 0, 2)
def make_serial(self): self.rich_btn = forward_btn(label="Continue in rich mode", on_press=self.rich_mode) self.basic_btn = forward_btn(label="Continue in basic mode", on_press=self.basic_mode) btns = [self.rich_btn, self.basic_btn] widgets = [ Text(""), Text(rewrap(SERIAL_TEXT)), Text(""), ] if self.ssh_info: widgets.append(Text(rewrap(SSH_TEXT))) widgets.append(Text("")) btns.append( other_btn(label="View SSH instructions", on_press=self.ssh_help)) return screen(widgets, btns)
def callback(): nonlocal called called = True if fi is not None: fi.close() if len(self.snap.channels) == 0: # or other indication of failure ff = FetchingFailed(self, self.snap) self.parent.show_overlay(ff, width=ff.width) else: cur_chan = None if self.snap.name in self.parent.to_install: cur_chan = self.parent.to_install[self.snap.name].channel self.parent.show_screen( screen(SnapInfoView(self.parent, self.snap, cur_chan), [ other_btn(label=_("Close"), on_press=self.parent.show_main_screen) ], focus_buttons=False))