Example #1
0
    def render_placement_view(self, loop, config, cb):
        """ render placement view

        :param cb: deploy callback trigger
        """
        if self.placement_view is None:
            assert self.controller is not None
            pc = self.controller.placement_controller
            self.placement_view = PlacementView(self, pc, loop, config, cb)
        self.placement_view.update()
        self.frame.body = self.placement_view
Example #2
0
 def render_placement_view(self, display_controller,
                           placement_controller):
     if self.placement_view is None:
         self.placement_view = PlacementView(display_controller,
                                             placement_controller)
     self.placement_view.update()
     self.frame.body = self.placement_view
Example #3
0
    def render_placement_view(self, loop, config, cb):
        """ render placement view

        :param cb: deploy callback trigger
        """
        if self.placement_view is None:
            assert self.controller is not None
            pc = self.controller.placement_controller
            self.placement_view = PlacementView(self, pc, loop, config, cb)
        self.placement_view.update()
        self.frame.body = self.placement_view
Example #4
0
class PegasusGUI(WidgetWrap):

    def __init__(self, header=None, body=None, footer=None):
        _check_encoding()  # Make sure terminal supports utf8
        cb = self.show_exception_message
        utils.register_async_exception_callback(cb)
        self.header = header if header else Header()
        self.body = body if body else Banner()
        self.footer = footer if footer else StatusBar('')

        self.frame = Frame(self.body,
                           header=self.header,
                           footer=self.footer)

        self.services_view = None
        self.placement_view = None
        self.controller = None
        self.machine_wait_view = None
        self.add_services_dialog = None
        super().__init__(self.frame)

    def _build_overlay_widget(self,
                              top_w,
                              align,
                              width,
                              valign,
                              height,
                              min_width,
                              min_height):
        return Overlay(top_w=Filler(top_w),
                       bottom_w=self.frame,
                       align=align,
                       width=width,
                       valign=valign,
                       height=height,
                       min_width=width,
                       min_height=height)

    def show_widget_on_top(self,
                           widget,
                           width,
                           height,
                           align='center',
                           valign='middle',
                           min_height=0,
                           min_width=0):
        """Show `widget` on top of :attr:`frame`."""
        self._w = self._build_overlay_widget(top_w=widget,
                                             align=align,
                                             width=width,
                                             valign=valign,
                                             height=height,
                                             min_width=min_width,
                                             min_height=min_height)

    def focus_next(self):
        if hasattr(self.frame.body, 'scroll_down'):
            self.frame.body.scroll_down()

    def focus_previous(self):
        if hasattr(self.frame.body, 'scroll_up'):
            self.frame.body.scroll_up()

    def focus_first(self):
        if hasattr(self.frame.body, 'scroll_top'):
            self.frame.body.scroll_top()

    def focus_last(self):
        if hasattr(self.frame.body, 'scroll_bottom'):
            self.frame.body.scroll_bottom()

    def hide_widget_on_top(self):
        """Hide the topmost widget (if any)."""
        self._w = self.frame

    def show_help_info(self):
        widget = HelpScreen()
        self.show_widget_on_top(widget, width=80, height=22,
                                align="center", valign="middle",
                                min_height=10)

    def hide_help_info(self):
        self.hide_widget_on_top()

    def show_step_info(self, msg):
        self.hide_step_info()
        widget = StepInfo(msg)
        self.show_widget_on_top(widget, width=60,
                                height=14,
                                align="center",
                                valign="middle",
                                min_height=10)

    def hide_step_info(self):
        self.hide_widget_on_top()

    def show_selector_info(self, title, opts, cb):
        widget = Selector(title, opts, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_selector_info(self):
        self.hide_widget_on_top()

    def show_selector_with_desc(self, title, opts, cb):
        widget = SelectorWithDescription(title, opts, cb)
        self.show_widget_on_top(widget, width=80, height=14)

    def hide_selector_with_desc(self):
        self.hide_widget_on_top()

    def show_fatal_error_message(self, msg, cb):
        w = InfoDialog(msg, cb)
        self.show_widget_on_top(w, width=50, height=20)

    def show_password_input(self, title, cb):
        widget = PasswordInput(title, cb)
        self.show_widget_on_top(widget, width=50, height=7)

    def hide_show_password_input(self):
        self.hide_widget_on_top()

    def show_maas_input(self, title, cb):
        widget = MaasServerInput(title, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_show_maas_input(self):
        self.hide_widget_on_top()

    def show_dhcp_range(self, range_low, range_high, title, cb):
        widget = DhcpRangeInput(range_low, range_high, title, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_show_dhcp_range(self):
        self.hide_widget_on_top()

    def show_landscape_input(self, title, cb):
        widget = LandscapeInput(title, cb)
        self.show_widget_on_top(widget, width=50, height=9)

    def hide_show_landscape_input(self):
        self.hide_widget_on_top()

    def set_pending_deploys(self, pending_charms):
        self.frame.footer.set_pending_deploys(pending_charms)

    def flash(self, msg):
        self.frame.body.flash("{}\N{HORIZONTAL ELLIPSIS}".format(msg))

    def flash_reset(self):
        self.frame.body.flash_reset()

    def status_message(self, text):
        self.frame.footer.message(text)
        self.frame.set_footer(self.frame.footer)

    def status_error_message(self, message):
        self.frame.footer.error_message(message)

    def status_info_message(self, message):
        self.frame.footer.info_message(
            "{}\N{HORIZONTAL ELLIPSIS}".format(message))

    def set_dashboard_url(self, ip, user, password):
        self.frame.footer.set_dashboard_url(ip, user, password)

    def set_jujugui_url(self, ip):
        self.frame.footer.set_jujugui_url(ip)

    def set_openstack_rel(self, text):
        self.frame.footer.set_openstack_rel(text)

    def clear_status(self):
        self.frame.footer = None
        self.frame.set_footer(self.frame.footer)

    def render_services_view(self, nodes, juju_state, maas_state, config,
                             **kwargs):
        if self.services_view is None:
            self.services_view = ServicesView(nodes, juju_state, maas_state,
                                              config)

        self.services_view.update(nodes)
        self.frame.set_body(self.services_view)
        self.header.set_show_add_units_hotkey(True)

    def render_node_install_wait(self, message=None, **kwargs):
        self.frame.body = NodeInstallWaitMode(message, **kwargs)
        self.frame.set_body(self.frame.body)

    def render_placement_view(self, loop, config, cb):
        """ render placement view

        :param cb: deploy callback trigger
        """
        if self.placement_view is None:
            assert self.controller is not None
            pc = self.controller.placement_controller
            self.placement_view = PlacementView(self, pc, loop,
                                                config, cb)
        self.placement_view.update()
        self.frame.body = self.placement_view

    def render_machine_wait_view(self, config):
        if self.machine_wait_view is None:
            self.machine_wait_view = MachineWaitView(
                self, self.current_installer, config)
        self.machine_wait_view.update()
        self.frame.body = self.machine_wait_view

    def render_add_services_dialog(self, deploy_cb, cancel_cb):
        def reset():
            self.add_services_dialog = None

        def cancel():
            reset()
            cancel_cb()

        def deploy():
            reset()
            deploy_cb()

        if self.add_services_dialog is None:
            self.add_services_dialog = AddServicesDialog(self.controller,
                                                         deploy_cb=deploy,
                                                         cancel_cb=cancel)
        self.add_services_dialog.update()
        self.frame.body = Filler(self.add_services_dialog)

    def show_exception_message(self, ex, logpath="~/.cloud-install/commands"):
        def handle_done(*args, **kwargs):
            raise urwid.ExitMainLoop()
        self.hide_widget_on_top()
        msg = ("A fatal error has occurred: {}\n"
               "See {} for further info.".format(ex.args[0],
                                                 logpath))
        self.show_fatal_error_message(msg, handle_done)

    def select_install_type(self, install_types, cb):
        """ Dialog for selecting installation type
        """
        self.status_info_message("Choose your installation path")
        self.show_selector_with_desc('Install Type',
                                     install_types,
                                     cb)

    def select_maas_type(self, cb):
        """ Perform multi install based on existing
        MAAS or if a new MAAS will be installed
        """
        self.status_info_message(
            "If a MAAS exists please enter the Server IP and your "
            "administrator's API Key. Otherwise leave blank and a new "
            "MAAS will be created for you")
        self.show_maas_input("MAAS Setup", cb)

    def __repr__(self):
        return "<Ubuntu OpenStack Installer GUI Interface>"

    def tasker(self, loop, config):
        """ Interface with Tasker class

        :param loop: urwid.Mainloop
        :param dict config: config object
        """
        return Tasker(self, loop, config)

    def exit(self, loop=None):
        """ Provide exit loop helper

        :param loop: Just a placeholder, exit with urwid.
        """
        urwid.ExitMainLoop()
Example #5
0
class PegasusGUI(WidgetWrap):
    key_conversion_map = {'tab': 'down', 'shift tab': 'up'}

    def __init__(self, header=None, body=None, footer=None):
        _check_encoding()  # Make sure terminal supports utf8
        cb = self.show_exception_message
        utils.register_async_exception_callback(cb)
        self.header = header if header else Header()
        self.body = body if body else Banner()
        self.footer = footer if footer else StatusBar('')

        self.frame = Frame(self.body, header=self.header, footer=self.footer)

        self.services_view = None
        self.placement_view = None
        self.controller = None
        self.machine_wait_view = None
        self.add_services_dialog = None
        super().__init__(self.frame)

    def keypress(self, size, key):
        key = self.key_conversion_map.get(key, key)
        return super().keypress(size, key)

    def _build_overlay_widget(self, top_w, align, width, valign, height,
                              min_width, min_height):
        return Overlay(top_w=Filler(top_w),
                       bottom_w=self.frame,
                       align=align,
                       width=width,
                       valign=valign,
                       height=height,
                       min_width=width,
                       min_height=height)

    def show_widget_on_top(self,
                           widget,
                           width,
                           height,
                           align='center',
                           valign='middle',
                           min_height=0,
                           min_width=0):
        """Show `widget` on top of :attr:`frame`."""
        self._w = self._build_overlay_widget(top_w=widget,
                                             align=align,
                                             width=width,
                                             valign=valign,
                                             height=height,
                                             min_width=min_width,
                                             min_height=min_height)

    def focus_next(self):
        if hasattr(self.frame.body, 'scroll_down'):
            self.frame.body.scroll_down()

    def focus_previous(self):
        if hasattr(self.frame.body, 'scroll_up'):
            self.frame.body.scroll_up()

    def focus_first(self):
        if hasattr(self.frame.body, 'scroll_top'):
            self.frame.body.scroll_top()

    def focus_last(self):
        if hasattr(self.frame.body, 'scroll_bottom'):
            self.frame.body.scroll_bottom()

    def hide_widget_on_top(self):
        """Hide the topmost widget (if any)."""
        self._w = self.frame

    def show_help_info(self):
        self.controller = self.frame.body
        self.frame.body = HelpScreen()

    def show_step_info(self, msg):
        self.frame.body = StepInfo(msg)

    def show_selector_with_desc(self, title, opts, cb):
        self.frame.body = SelectorWithDescription(title, opts, cb)

    def show_fatal_error_message(self, msg, cb):
        w = InfoDialog(msg, cb)
        self.show_widget_on_top(w, width=50, height=20)

    def show_password_input(self, title, cb):
        self.frame.body = PasswordInput(title, cb)

    def show_maas_input(self, title, cb):
        self.frame.body = MaasServerInput(title, cb)

    def show_landscape_input(self, title, cb):
        self.frame.body = LandscapeInput(title, cb)

    def set_pending_deploys(self, pending_charms):
        self.frame.footer.set_pending_deploys(pending_charms)

    def flash(self, msg):
        self.frame.body.flash("{}\N{HORIZONTAL ELLIPSIS}".format(msg))

    def flash_reset(self):
        self.frame.body.flash_reset()

    def status_message(self, text):
        self.frame.footer.message(text)
        self.frame.set_footer(self.frame.footer)

    def status_error_message(self, message):
        self.frame.footer.error_message(message)

    def status_info_message(self, message):
        self.frame.footer.info_message(
            "{}\N{HORIZONTAL ELLIPSIS}".format(message))

    def set_dashboard_url(self, ip, user, password):
        self.frame.footer.set_dashboard_url(ip, user, password)

    def set_jujugui_url(self, ip):
        self.frame.footer.set_jujugui_url(ip)

    def set_openstack_rel(self, release):
        self.frame.header.set_openstack_rel(release)

    def clear_status(self):
        self.frame.footer = None
        self.frame.set_footer(self.frame.footer)

    def render_services_view(self, nodes, juju_state, maas_state, config,
                             **kwargs):
        if self.services_view is None:
            self.services_view = ServicesView(nodes, juju_state, maas_state,
                                              config)

        self.services_view.update(nodes)
        self.frame.set_body(self.services_view)
        self.header.set_show_add_units_hotkey(True)
        dc = config.getopt('deploy_complete')
        dcstr = "complete" if dc else "pending"
        rc = config.getopt('relations_complete')
        rcstr = "complete" if rc else "pending"
        ppc = config.getopt('postproc_complete')
        ppcstr = "complete" if ppc else "pending"
        self.status_info_message("Status: Deployments {}, "
                                 "Relations {}, "
                                 "Post-processing {} ".format(
                                     dcstr, rcstr, ppcstr))

    def render_node_install_wait(self, message=None, **kwargs):
        self.frame.body = NodeInstallWaitMode(message, **kwargs)

    def render_placement_view(self, loop, config, cb):
        """ render placement view

        :param cb: deploy callback trigger
        """
        if self.placement_view is None:
            assert self.controller is not None
            pc = self.controller.placement_controller
            self.placement_view = PlacementView(self, pc, loop, config, cb)
        self.placement_view.update()
        self.frame.body = self.placement_view

    def render_machine_wait_view(self, config):
        if self.machine_wait_view is None:
            self.machine_wait_view = MachineWaitView(self,
                                                     self.current_installer,
                                                     config)
        self.machine_wait_view.update()
        self.frame.body = self.machine_wait_view

    def render_add_services_dialog(self, deploy_cb, cancel_cb):
        def reset():
            self.add_services_dialog = None

        def cancel():
            reset()
            cancel_cb()

        def deploy():
            reset()
            deploy_cb()

        if self.add_services_dialog is None:
            self.add_services_dialog = AddServicesDialog(self.controller,
                                                         deploy_cb=deploy,
                                                         cancel_cb=cancel)
        self.add_services_dialog.update()
        self.frame.body = Filler(self.add_services_dialog)

    def show_exception_message(self, ex):
        msg = ("A fatal error has occurred: {}\n".format(ex.args[0]))
        log.error(msg)
        self.frame.body = ErrorView(ex.args[0])
        AlarmMonitor.remove_all()

    def select_install_type(self, install_types, cb):
        """ Dialog for selecting installation type
        """
        self.show_selector_with_desc(
            'Select the type of installation to perform', install_types, cb)

    def __repr__(self):
        return "<Ubuntu OpenStack Installer GUI Interface>"

    def tasker(self, loop, config):
        """ Interface with Tasker class

        :param loop: urwid.Mainloop
        :param dict config: config object
        """
        return Tasker(self, loop, config)

    def exit(self, loop=None):
        """ Provide exit loop helper

        :param loop: Just a placeholder, exit with urwid.
        """
        urwid.ExitMainLoop()
Example #6
0
class PegasusGUI(WidgetWrap):
    def __init__(self, header=None, body=None, footer=None):
        _check_encoding()  # Make sure terminal supports utf8
        cb = self.show_exception_message
        utils.register_async_exception_callback(cb)
        self.header = header if header else Header()
        self.body = body if body else Banner()
        self.footer = footer if footer else StatusBar('')

        self.frame = Frame(self.body, header=self.header, footer=self.footer)

        self.services_view = None
        self.placement_view = None
        self.controller = None
        self.machine_wait_view = None
        self.add_services_dialog = None
        super().__init__(self.frame)

    def _build_overlay_widget(self, top_w, align, width, valign, height,
                              min_width, min_height):
        return Overlay(top_w=Filler(top_w),
                       bottom_w=self.frame,
                       align=align,
                       width=width,
                       valign=valign,
                       height=height,
                       min_width=width,
                       min_height=height)

    def show_widget_on_top(self,
                           widget,
                           width,
                           height,
                           align='center',
                           valign='middle',
                           min_height=0,
                           min_width=0):
        """Show `widget` on top of :attr:`frame`."""
        self._w = self._build_overlay_widget(top_w=widget,
                                             align=align,
                                             width=width,
                                             valign=valign,
                                             height=height,
                                             min_width=min_width,
                                             min_height=min_height)

    def focus_next(self):
        if hasattr(self.frame.body, 'scroll_down'):
            self.frame.body.scroll_down()

    def focus_previous(self):
        if hasattr(self.frame.body, 'scroll_up'):
            self.frame.body.scroll_up()

    def focus_first(self):
        if hasattr(self.frame.body, 'scroll_top'):
            self.frame.body.scroll_top()

    def focus_last(self):
        if hasattr(self.frame.body, 'scroll_bottom'):
            self.frame.body.scroll_bottom()

    def hide_widget_on_top(self):
        """Hide the topmost widget (if any)."""
        self._w = self.frame

    def show_help_info(self):
        widget = HelpScreen()
        self.show_widget_on_top(widget,
                                width=80,
                                height=22,
                                align="center",
                                valign="middle",
                                min_height=10)

    def hide_help_info(self):
        self.hide_widget_on_top()

    def show_step_info(self, msg):
        self.hide_step_info()
        widget = StepInfo(msg)
        self.show_widget_on_top(widget,
                                width=60,
                                height=14,
                                align="center",
                                valign="middle",
                                min_height=10)

    def hide_step_info(self):
        self.hide_widget_on_top()

    def show_selector_info(self, title, opts, cb):
        widget = Selector(title, opts, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_selector_info(self):
        self.hide_widget_on_top()

    def show_selector_with_desc(self, title, opts, cb):
        widget = SelectorWithDescription(title, opts, cb)
        self.show_widget_on_top(widget, width=80, height=14)

    def hide_selector_with_desc(self):
        self.hide_widget_on_top()

    def show_fatal_error_message(self, msg, cb):
        w = InfoDialog(msg, cb)
        self.show_widget_on_top(w, width=50, height=20)

    def show_password_input(self, title, cb):
        widget = PasswordInput(title, cb)
        self.show_widget_on_top(widget, width=50, height=7)

    def hide_show_password_input(self):
        self.hide_widget_on_top()

    def show_maas_input(self, title, cb):
        widget = MaasServerInput(title, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_show_maas_input(self):
        self.hide_widget_on_top()

    def show_dhcp_range(self, range_low, range_high, title, cb):
        widget = DhcpRangeInput(range_low, range_high, title, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_show_dhcp_range(self):
        self.hide_widget_on_top()

    def show_landscape_input(self, title, cb):
        widget = LandscapeInput(title, cb)
        self.show_widget_on_top(widget, width=50, height=9)

    def hide_show_landscape_input(self):
        self.hide_widget_on_top()

    def set_pending_deploys(self, pending_charms):
        self.frame.footer.set_pending_deploys(pending_charms)

    def flash(self, msg):
        self.frame.body.flash("{}\N{HORIZONTAL ELLIPSIS}".format(msg))

    def flash_reset(self):
        self.frame.body.flash_reset()

    def status_message(self, text):
        self.frame.footer.message(text)
        self.frame.set_footer(self.frame.footer)

    def status_error_message(self, message):
        self.frame.footer.error_message(message)

    def status_info_message(self, message):
        self.frame.footer.info_message(
            "{}\N{HORIZONTAL ELLIPSIS}".format(message))

    def set_dashboard_url(self, ip, user, password):
        self.frame.footer.set_dashboard_url(ip, user, password)

    def set_jujugui_url(self, ip):
        self.frame.footer.set_jujugui_url(ip)

    def set_openstack_rel(self, text):
        self.frame.footer.set_openstack_rel(text)

    def clear_status(self):
        self.frame.footer = None
        self.frame.set_footer(self.frame.footer)

    def render_services_view(self, nodes, juju_state, maas_state, config,
                             **kwargs):
        if self.services_view is None:
            self.services_view = ServicesView(nodes, juju_state, maas_state,
                                              config)

        self.services_view.update(nodes)
        self.frame.set_body(self.services_view)
        self.header.set_show_add_units_hotkey(True)

    def render_node_install_wait(self, message=None, **kwargs):
        self.frame.body = NodeInstallWaitMode(message, **kwargs)
        self.frame.set_body(self.frame.body)

    def render_placement_view(self, loop, config, cb):
        """ render placement view

        :param cb: deploy callback trigger
        """
        if self.placement_view is None:
            assert self.controller is not None
            pc = self.controller.placement_controller
            self.placement_view = PlacementView(self, pc, loop, config, cb)
        self.placement_view.update()
        self.frame.body = self.placement_view

    def render_machine_wait_view(self, config):
        if self.machine_wait_view is None:
            self.machine_wait_view = MachineWaitView(self,
                                                     self.current_installer,
                                                     config)
        self.machine_wait_view.update()
        self.frame.body = self.machine_wait_view

    def render_add_services_dialog(self, deploy_cb, cancel_cb):
        def reset():
            self.add_services_dialog = None

        def cancel():
            reset()
            cancel_cb()

        def deploy():
            reset()
            deploy_cb()

        if self.add_services_dialog is None:
            self.add_services_dialog = AddServicesDialog(self.controller,
                                                         deploy_cb=deploy,
                                                         cancel_cb=cancel)
        self.add_services_dialog.update()
        self.frame.body = Filler(self.add_services_dialog)

    def show_exception_message(self,
                               ex,
                               logpath="~/.cloud-install/commands.log"):
        def handle_done(*args, **kwargs):
            raise urwid.ExitMainLoop()

        self.hide_widget_on_top()
        msg = ("A fatal error has occurred: {}\n"
               "See {} for further info.".format(ex.args[0], logpath))
        self.show_fatal_error_message(msg, handle_done)

    def select_install_type(self, install_types, cb):
        """ Dialog for selecting installation type
        """
        self.status_info_message("Choose your installation path")
        self.show_selector_with_desc('Install Type', install_types, cb)

    def select_maas_type(self, cb):
        """ Perform multi install based on existing
        MAAS or if a new MAAS will be installed
        """
        self.status_info_message(
            "Please enter the Server IP and your "
            "administrator's API Key of the existing MAAS server")
        self.show_maas_input("MAAS Setup", cb)

    def __repr__(self):
        return "<Ubuntu OpenStack Installer GUI Interface>"

    def tasker(self, loop, config):
        """ Interface with Tasker class

        :param loop: urwid.Mainloop
        :param dict config: config object
        """
        return Tasker(self, loop, config)

    def exit(self, loop=None):
        """ Provide exit loop helper

        :param loop: Just a placeholder, exit with urwid.
        """
        urwid.ExitMainLoop()
Example #7
0
class PegasusGUI(WidgetWrap):

    def __init__(self, header=None, body=None, footer=None):
        _check_encoding()  # Make sure terminal supports utf8
        self.header = header if header else Header()
        self.body = body if body else Banner()
        self.footer = footer if footer else StatusBar('')

        self.frame = Frame(self.body,
                           header=self.header,
                           footer=self.footer)

        self.placement_view = None
        super().__init__(self.frame)

    def _build_overlay_widget(self,
                              top_w,
                              align,
                              width,
                              valign,
                              height,
                              min_width,
                              min_height):
        return Overlay(top_w=Filler(top_w),
                       bottom_w=self.frame,
                       align=align,
                       width=width,
                       valign=valign,
                       height=height,
                       min_width=width,
                       min_height=height)

    def show_widget_on_top(self,
                           widget,
                           width,
                           height,
                           align='center',
                           valign='middle',
                           min_height=0,
                           min_width=0):
        """Show `widget` on top of :attr:`frame`."""
        self._w = self._build_overlay_widget(top_w=widget,
                                             align=align,
                                             width=width,
                                             valign=valign,
                                             height=height,
                                             min_width=min_width,
                                             min_height=min_height)

    def focus_next(self):
        self.frame.body.scroll_down()

    def focus_previous(self):
        self.frame.body.scroll_up()

    def focus_first(self):
        self.frame.body.scroll_top()

    def focus_last(self):
        self.frame.body.scroll_bottom()

    def hide_widget_on_top(self):
        """Hide the topmost widget (if any)."""
        self._w = self.frame

    def show_help_info(self):
        widget = HelpScreen()
        self.show_widget_on_top(widget, width=80, height=22,
                                align="center", valign="middle",
                                min_height=10)

    def hide_help_info(self):
        self.hide_widget_on_top()

    def show_step_info(self, msg, width=60, height=10):
        self.hide_step_info()
        widget = StepInfo(msg, height)
        self.show_widget_on_top(widget, width=width, height=height + 1,
                                align="center",
                                valign="middle", min_height=10)

    def hide_step_info(self):
        self.hide_widget_on_top()

    def show_selector_info(self, title, opts, cb):
        widget = Selector(title, opts, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_selector_info(self):
        self.hide_widget_on_top()

    def show_fatal_error_message(self, msg, cb):
        w = InfoDialog(msg, cb)
        self.show_widget_on_top(w, width=50, height=20)

    def show_password_input(self, title, cb):
        widget = PasswordInput(title, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_show_password_input(self):
        self.hide_widget_on_top()

    def show_maas_input(self, title, cb):
        widget = MaasServerInput(title, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_show_maas_input(self):
        self.hide_widget_on_top()

    def show_dhcp_range(self, range_low, range_high, title, cb):
        widget = DhcpRangeInput(range_low, range_high, title, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_show_dhcp_range(self):
        self.hide_widget_on_top()

    def show_landscape_input(self, title, cb):
        widget = LandscapeInput(title, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_show_landscape_input(self):
        self.hide_widget_on_top()

    def show_add_charm_info(self, charms, cb):
        widget = AddCharmDialog(charms, cb)
        self.show_widget_on_top(widget, width=50, height=10)

    def hide_add_charm_info(self):
        self.hide_widget_on_top()

    def set_pending_deploys(self, pending_charms):
        self.frame.footer.set_pending_deploys(pending_charms)

    def status_message(self, text):
        self.frame.footer.message(text)
        self.frame.set_footer(self.frame.footer)

    def status_error_message(self, message):
        self.frame.footer.error_message(message)

    def status_info_message(self, message):
        self.frame.footer.info_message(message)

    def status_dashboard_url(self, ip):
        self.frame.footer.set_dashboard_url(ip)

    def status_jujugui_url(self, ip):
        self.frame.footer.set_jujugui_url(ip)

    def status_openstack_rel(self, text):
        self.frame.footer.set_openstack_rel(text)

    def clear_status(self):
        self.frame.footer = None
        self.frame.set_footer(self.frame.footer)

    def render_nodes(self, nodes, juju_state, maas_state, **kwargs):
        self.frame.body = NodeViewMode(nodes, juju_state, maas_state)
        self.frame.set_body(self.frame.body)
        self.header.set_show_add_units_hotkey(True)

    def render_node_install_wait(self, **kwargs):
        self.frame.body = NodeInstallWaitMode(**kwargs)
        self.frame.set_body(self.frame.body)

    def render_placement_view(self, display_controller,
                              placement_controller):
        if self.placement_view is None:
            self.placement_view = PlacementView(display_controller,
                                                placement_controller)
        self.placement_view.update()
        self.frame.body = self.placement_view
Example #8
0
class PegasusGUI(WidgetWrap):
    key_conversion_map = {"tab": "down", "shift tab": "up"}

    def __init__(self, header=None, body=None, footer=None):
        _check_encoding()  # Make sure terminal supports utf8
        cb = self.show_exception_message
        utils.register_async_exception_callback(cb)
        self.header = header if header else Header()
        self.body = body if body else Banner()
        self.footer = footer if footer else StatusBar("")

        self.frame = Frame(self.body, header=self.header, footer=self.footer)

        self.services_view = None
        self.placement_view = None
        self.controller = None
        self.machine_wait_view = None
        self.add_services_dialog = None
        super().__init__(self.frame)

    def keypress(self, size, key):
        key = self.key_conversion_map.get(key, key)
        return super().keypress(size, key)

    def _build_overlay_widget(self, top_w, align, width, valign, height, min_width, min_height):
        return Overlay(
            top_w=Filler(top_w),
            bottom_w=self.frame,
            align=align,
            width=width,
            valign=valign,
            height=height,
            min_width=width,
            min_height=height,
        )

    def show_widget_on_top(self, widget, width, height, align="center", valign="middle", min_height=0, min_width=0):
        """Show `widget` on top of :attr:`frame`."""
        self._w = self._build_overlay_widget(
            top_w=widget,
            align=align,
            width=width,
            valign=valign,
            height=height,
            min_width=min_width,
            min_height=min_height,
        )

    def focus_next(self):
        if hasattr(self.frame.body, "scroll_down"):
            self.frame.body.scroll_down()

    def focus_previous(self):
        if hasattr(self.frame.body, "scroll_up"):
            self.frame.body.scroll_up()

    def focus_first(self):
        if hasattr(self.frame.body, "scroll_top"):
            self.frame.body.scroll_top()

    def focus_last(self):
        if hasattr(self.frame.body, "scroll_bottom"):
            self.frame.body.scroll_bottom()

    def hide_widget_on_top(self):
        """Hide the topmost widget (if any)."""
        self._w = self.frame

    def show_help_info(self):
        self.controller = self.frame.body
        self.frame.body = HelpScreen()

    def show_step_info(self, msg):
        self.frame.body = StepInfo(msg)

    def show_selector_with_desc(self, title, opts, cb):
        self.frame.body = SelectorWithDescription(title, opts, cb)

    def show_fatal_error_message(self, msg, cb):
        w = InfoDialog(msg, cb)
        self.show_widget_on_top(w, width=50, height=20)

    def show_password_input(self, title, cb):
        self.frame.body = PasswordInput(title, cb)

    def show_maas_input(self, title, cb):
        self.frame.body = MaasServerInput(title, cb)

    def show_landscape_input(self, title, cb):
        self.frame.body = LandscapeInput(title, cb)

    def set_pending_deploys(self, pending_charms):
        self.frame.footer.set_pending_deploys(pending_charms)

    def flash(self, msg):
        self.frame.body.flash("{}\N{HORIZONTAL ELLIPSIS}".format(msg))

    def flash_reset(self):
        self.frame.body.flash_reset()

    def status_message(self, text):
        self.frame.footer.message(text)
        self.frame.set_footer(self.frame.footer)

    def status_error_message(self, message):
        self.frame.footer.error_message(message)

    def status_info_message(self, message):
        self.frame.footer.info_message("{}\N{HORIZONTAL ELLIPSIS}".format(message))

    def set_dashboard_url(self, ip, user, password):
        self.frame.footer.set_dashboard_url(ip, user, password)

    def set_jujugui_url(self, ip):
        self.frame.footer.set_jujugui_url(ip)

    def set_openstack_rel(self, release):
        self.frame.header.set_openstack_rel(release)

    def clear_status(self):
        self.frame.footer = None
        self.frame.set_footer(self.frame.footer)

    def render_services_view(self, nodes, juju_state, maas_state, config, **kwargs):
        if self.services_view is None:
            self.services_view = ServicesView(nodes, juju_state, maas_state, config)

        self.services_view.update(nodes)
        self.frame.set_body(self.services_view)
        self.header.set_show_add_units_hotkey(True)
        dc = config.getopt("deploy_complete")
        dcstr = "complete" if dc else "pending"
        rc = config.getopt("relations_complete")
        rcstr = "complete" if rc else "pending"
        ppc = config.getopt("postproc_complete")
        ppcstr = "complete" if ppc else "pending"
        self.status_info_message(
            "Status: Deployments {}, " "Relations {}, " "Post-processing {} ".format(dcstr, rcstr, ppcstr)
        )

    def render_node_install_wait(self, message=None, **kwargs):
        self.frame.body = NodeInstallWaitMode(message, **kwargs)

    def render_placement_view(self, loop, config, cb):
        """ render placement view

        :param cb: deploy callback trigger
        """
        if self.placement_view is None:
            assert self.controller is not None
            pc = self.controller.placement_controller
            self.placement_view = PlacementView(self, pc, loop, config, cb)
        self.placement_view.update()
        self.frame.body = self.placement_view

    def render_machine_wait_view(self, config):
        if self.machine_wait_view is None:
            self.machine_wait_view = MachineWaitView(self, self.current_installer, config)
        self.machine_wait_view.update()
        self.frame.body = self.machine_wait_view

    def render_add_services_dialog(self, deploy_cb, cancel_cb):
        def reset():
            self.add_services_dialog = None

        def cancel():
            reset()
            cancel_cb()

        def deploy():
            reset()
            deploy_cb()

        if self.add_services_dialog is None:
            self.add_services_dialog = AddServicesDialog(self.controller, deploy_cb=deploy, cancel_cb=cancel)
        self.add_services_dialog.update()
        self.frame.body = Filler(self.add_services_dialog)

    def show_exception_message(self, ex):
        msg = "A fatal error has occurred: {}\n".format(ex.args[0])
        log.error(msg)
        self.frame.body = ErrorView(ex.args[0])
        AlarmMonitor.remove_all()

    def select_install_type(self, install_types, cb):
        """ Dialog for selecting installation type
        """
        self.show_selector_with_desc("Select the type of installation to perform", install_types, cb)

    def __repr__(self):
        return "<Ubuntu OpenStack Installer GUI Interface>"

    def tasker(self, loop, config):
        """ Interface with Tasker class

        :param loop: urwid.Mainloop
        :param dict config: config object
        """
        return Tasker(self, loop, config)

    def exit(self, loop=None):
        """ Provide exit loop helper

        :param loop: Just a placeholder, exit with urwid.
        """
        urwid.ExitMainLoop()
Example #9
0
class PegasusGUI(WidgetWrap):
    key_conversion_map = {'tab': 'down', 'shift tab': 'up'}

    def __init__(self, header=None, body=None, footer=None):
        self.header = header if header else Header()
        self.body = body if body else Banner()
        self.footer = footer if footer else StatusBarWidget()

        self.frame = Frame(self.body, header=self.header, footer=self.footer)

        self.services_view = None
        self.placement_view = None
        self.controller = None
        self.machine_wait_view = None
        self.node_install_wait_view = None
        self.add_services_dialog = None
        super().__init__(self.frame)

    def keypress(self, size, key):
        key = self.key_conversion_map.get(key, key)
        return super().keypress(size, key)

    def focus_next(self):
        if hasattr(self.frame.body, 'scroll_down'):
            self.frame.body.scroll_down()

    def focus_previous(self):
        if hasattr(self.frame.body, 'scroll_up'):
            self.frame.body.scroll_up()

    def focus_first(self):
        if hasattr(self.frame.body, 'scroll_top'):
            self.frame.body.scroll_top()

    def focus_last(self):
        if hasattr(self.frame.body, 'scroll_bottom'):
            self.frame.body.scroll_bottom()

    def show_help_info(self):
        self.controller = self.frame.body
        self.frame.body = HelpView()

    def show_step_info(self, msg):
        self.frame.body = StepInfoView(msg)

    def show_selector_with_desc(self, title, opts, cb):
        self.frame.body = SelectorWithDescriptionWidget(title, opts, cb)

    def show_password_input(self, title, cb):
        self.frame.body = PasswordInput(title, cb)

    def show_maas_input(self, title, cb):
        self.frame.body = MaasServerInput(title, cb)

    def show_landscape_input(self, title, cb):
        self.frame.body = LandscapeInput(title, cb)

    def set_pending_deploys(self, pending_charms):
        self.frame.footer.set_pending_deploys(pending_charms)

    def status_message(self, text):
        self.frame.footer.message(text)
        self.frame.set_footer(self.frame.footer)

    def status_error_message(self, message):
        self.frame.footer.error_message(message)

    def status_info_message(self, message):
        self.frame.footer.info_message(
            "{}\N{HORIZONTAL ELLIPSIS}".format(message))

    def set_openstack_rel(self, release):
        self.frame.header.set_openstack_rel(release)

    def clear_status(self):
        try:
            self.frame.footer.clear()
        except Exception as e:
            log.exception(e)

    def render_services_view(self, nodes, juju_state, maas_state, config):
        self.services_view = ServicesView(nodes, juju_state, maas_state,
                                          config)
        self.frame.body = self.services_view
        self.header.set_show_add_units_hotkey(True)
        self.update_phase_status(config)

    def refresh_services_view(self, nodes, config):
        self.services_view.refresh_nodes(nodes)
        self.update_phase_status(config)

    def update_phase_status(self, config):
        dc = config.getopt('deploy_complete')
        dcstr = "complete" if dc else "pending"
        rc = config.getopt('relations_complete')
        rcstr = "complete" if rc else "pending"
        ppc = config.getopt('postproc_complete')
        ppcstr = "complete" if ppc else "pending"
        self.status_info_message("Status: Deployments {}, "
                                 "Relations {}, "
                                 "Post-processing {} ".format(
                                     dcstr, rcstr, ppcstr))

    def render_node_install_wait(self, message):
        if self.node_install_wait_view is None:
            self.node_install_wait_view = NodeInstallWaitView(message)
        self.frame.body = self.node_install_wait_view

    def render_placement_view(self, loop, config, cb):
        """ render placement view

        :param cb: deploy callback trigger
        """
        if self.placement_view is None:
            assert self.controller is not None
            pc = self.controller.placement_controller
            self.placement_view = PlacementView(self, pc, loop, config, cb)
        self.placement_view.update()
        self.frame.body = self.placement_view

    def render_machine_wait_view(self, config):
        if self.machine_wait_view is None:
            self.machine_wait_view = MachineWaitView(self,
                                                     self.current_installer,
                                                     config)
        self.machine_wait_view.update()
        self.frame.body = self.machine_wait_view

    def render_add_services_dialog(self, deploy_cb, cancel_cb):
        def reset():
            self.add_services_dialog = None

        def cancel():
            reset()
            cancel_cb()

        def deploy():
            reset()
            deploy_cb()

        if self.add_services_dialog is None:
            self.add_services_dialog = AddServicesDialog(self.controller,
                                                         deploy_cb=deploy,
                                                         cancel_cb=cancel)
        self.add_services_dialog.update()
        self.frame.body = Filler(self.add_services_dialog)

    def show_exception_message(self, ex):
        if isinstance(ex, async .ThreadCancelledException):
            log.debug("Thread cancelled intentionally.")
        else:
Example #10
0
class PegasusGUI(WidgetWrap):
    key_conversion_map = {'tab': 'down', 'shift tab': 'up'}

    def __init__(self, header=None, body=None, footer=None):
        self.header = header if header else Header()
        self.body = body if body else Banner()
        self.footer = footer if footer else StatusBarWidget()

        self.frame = Frame(self.body,
                           header=self.header,
                           footer=self.footer)

        self.services_view = None
        self.placement_view = None
        self.controller = None
        self.machine_wait_view = None
        self.node_install_wait_view = None
        self.add_services_dialog = None
        super().__init__(self.frame)

    def keypress(self, size, key):
        key = self.key_conversion_map.get(key, key)
        return super().keypress(size, key)

    def focus_next(self):
        if hasattr(self.frame.body, 'scroll_down'):
            self.frame.body.scroll_down()

    def focus_previous(self):
        if hasattr(self.frame.body, 'scroll_up'):
            self.frame.body.scroll_up()

    def focus_first(self):
        if hasattr(self.frame.body, 'scroll_top'):
            self.frame.body.scroll_top()

    def focus_last(self):
        if hasattr(self.frame.body, 'scroll_bottom'):
            self.frame.body.scroll_bottom()

    def show_help_info(self):
        self.controller = self.frame.body
        self.frame.body = HelpView()

    def show_step_info(self, msg):
        self.frame.body = StepInfoView(msg)

    def show_selector_with_desc(self, title, opts, cb):
        self.frame.body = SelectorWithDescriptionWidget(title, opts, cb)

    def show_password_input(self, title, cb):
        self.frame.body = PasswordInput(title, cb)

    def show_maas_input(self, title, cb):
        self.frame.body = MaasServerInput(title, cb)

    def show_landscape_input(self, title, cb):
        self.frame.body = LandscapeInput(title, cb)

    def set_pending_deploys(self, pending_charms):
        self.frame.footer.set_pending_deploys(pending_charms)

    def status_message(self, text):
        self.frame.footer.message(text)
        self.frame.set_footer(self.frame.footer)

    def status_error_message(self, message):
        self.frame.footer.error_message(message)

    def status_info_message(self, message):
        self.frame.footer.info_message(
            "{}\N{HORIZONTAL ELLIPSIS}".format(message))

    def set_openstack_rel(self, release):
        self.frame.header.set_openstack_rel(release)

    def clear_status(self):
        self.frame.footer = None
        self.frame.set_footer(self.frame.footer)

    def render_services_view(self, nodes, juju_state, maas_state, config):
        self.services_view = ServicesView(nodes, juju_state, maas_state,
                                          config)
        self.frame.body = self.services_view
        self.header.set_show_add_units_hotkey(True)
        self.update_phase_status(config)

    def refresh_services_view(self, nodes, config):
        self.services_view.refresh_nodes(nodes)
        self.update_phase_status(config)

    def update_phase_status(self, config):
        dc = config.getopt('deploy_complete')
        dcstr = "complete" if dc else "pending"
        rc = config.getopt('relations_complete')
        rcstr = "complete" if rc else "pending"
        ppc = config.getopt('postproc_complete')
        ppcstr = "complete" if ppc else "pending"
        self.status_info_message("Status: Deployments {}, "
                                 "Relations {}, "
                                 "Post-processing {} ".format(dcstr,
                                                              rcstr,
                                                              ppcstr))

    def render_node_install_wait(self, message):
        if self.node_install_wait_view is None:
            self.node_install_wait_view = NodeInstallWaitView(message)
        self.frame.body = self.node_install_wait_view

    def render_placement_view(self, loop, config, cb):
        """ render placement view

        :param cb: deploy callback trigger
        """
        if self.placement_view is None:
            assert self.controller is not None
            pc = self.controller.placement_controller
            self.placement_view = PlacementView(self, pc, loop,
                                                config, cb)
        self.placement_view.update()
        self.frame.body = self.placement_view

    def render_machine_wait_view(self, config):
        if self.machine_wait_view is None:
            self.machine_wait_view = MachineWaitView(
                self, self.current_installer, config)
        self.machine_wait_view.update()
        self.frame.body = self.machine_wait_view

    def render_add_services_dialog(self, deploy_cb, cancel_cb):
        def reset():
            self.add_services_dialog = None

        def cancel():
            reset()
            cancel_cb()

        def deploy():
            reset()
            deploy_cb()

        if self.add_services_dialog is None:
            self.add_services_dialog = AddServicesDialog(self.controller,
                                                         deploy_cb=deploy,
                                                         cancel_cb=cancel)
        self.add_services_dialog.update()
        self.frame.body = Filler(self.add_services_dialog)

    def show_exception_message(self, ex):
        msg = ("A fatal error has occurred: {}\n".format(ex.args[0]))
        log.error(msg)
        self.frame.body = ErrorView(ex.args[0])
        AlarmMonitor.remove_all()

    def select_install_type(self, install_types, cb):
        """ Dialog for selecting installation type
        """
        self.show_selector_with_desc(
            'Select the type of installation to perform',
            install_types,
            cb)

    def __repr__(self):
        return "<Ubuntu OpenStack Installer GUI Interface>"

    def tasker(self, loop, config):
        """ Interface with Tasker class

        :param loop: urwid.Mainloop
        :param dict config: config object
        """
        return Tasker(self, loop, config)

    def exit(self, loop=None):
        """ Provide exit loop helper

        :param loop: Just a placeholder, exit with urwid.
        """
        urwid.ExitMainLoop()
Example #11
0
class PegasusGUI(WidgetWrap):
    key_conversion_map = {'tab': 'down', 'shift tab': 'up'}

    def __init__(self, header=None, body=None, footer=None):
        self.header = header if header else Header()
        self.body = body if body else Banner()
        self.footer = footer if footer else StatusBarWidget()

        self.frame = Frame(self.body,
                           header=self.header,
                           footer=self.footer)

        self.services_view = None
        self.placement_view = None
        self.controller = None
        self.machine_wait_view = None
        self.node_install_wait_view = None
        self.add_services_dialog = None
        super().__init__(self.frame)

    def keypress(self, size, key):
        key = self.key_conversion_map.get(key, key)
        return super().keypress(size, key)

    def focus_next(self):
        if hasattr(self.frame.body, 'scroll_down'):
            self.frame.body.scroll_down()

    def focus_previous(self):
        if hasattr(self.frame.body, 'scroll_up'):
            self.frame.body.scroll_up()

    def focus_first(self):
        if hasattr(self.frame.body, 'scroll_top'):
            self.frame.body.scroll_top()

    def focus_last(self):
        if hasattr(self.frame.body, 'scroll_bottom'):
            self.frame.body.scroll_bottom()

    def show_help_info(self):
        self.controller = self.frame.body
        self.frame.body = HelpView()

    def show_step_info(self, msg):
        self.frame.body = StepInfoView(msg)

    def show_selector_with_desc(self, title, opts, cb):
        self.frame.body = SelectorWithDescriptionWidget(title, opts, cb)

    def show_password_input(self, title, cb):
        self.frame.body = PasswordInput(title, cb)

    def show_maas_input(self, title, cb):
        self.frame.body = MaasServerInput(title, cb)

    def show_landscape_input(self, title, cb):
        self.frame.body = LandscapeInput(title, cb)

    def set_pending_deploys(self, pending_charms):
        self.frame.footer.set_pending_deploys(pending_charms)

    def status_message(self, text):
        self.frame.footer.message(text)
        self.frame.set_footer(self.frame.footer)

    def status_error_message(self, message):
        self.frame.footer.error_message(message)

    def status_info_message(self, message):
        self.frame.footer.info_message(
            "{}\N{HORIZONTAL ELLIPSIS}".format(message))

    def set_openstack_rel(self, release):
        self.frame.header.set_openstack_rel(release)

    def clear_status(self):
        self.frame.footer = None
        self.frame.set_footer(self.frame.footer)

    def render_services_view(self, nodes, juju_state, maas_state, config):
        self.services_view = ServicesView(nodes, juju_state, maas_state,
                                          config)
        self.frame.body = self.services_view
        self.header.set_show_add_units_hotkey(True)
        self.update_phase_status(config)

    def refresh_services_view(self, nodes, config):
        self.services_view.refresh_nodes(nodes)
        self.update_phase_status(config)

    def update_phase_status(self, config):
        dc = config.getopt('deploy_complete')
        dcstr = "complete" if dc else "pending"
        rc = config.getopt('relations_complete')
        rcstr = "complete" if rc else "pending"
        ppc = config.getopt('postproc_complete')
        ppcstr = "complete" if ppc else "pending"
        self.status_info_message("Status: Deployments {}, "
                                 "Relations {}, "
                                 "Post-processing {} ".format(dcstr,
                                                              rcstr,
                                                              ppcstr))

    def render_node_install_wait(self, message):
        if self.node_install_wait_view is None:
            self.node_install_wait_view = NodeInstallWaitView(message)
        self.frame.body = self.node_install_wait_view

    def render_placement_view(self, loop, config, cb):
        """ render placement view

        :param cb: deploy callback trigger
        """
        if self.placement_view is None:
            assert self.controller is not None
            pc = self.controller.placement_controller
            self.placement_view = PlacementView(self, pc, loop,
                                                config, cb)
        self.placement_view.update()
        self.frame.body = self.placement_view

    def render_machine_wait_view(self, config):
        if self.machine_wait_view is None:
            self.machine_wait_view = MachineWaitView(
                self, self.current_installer, config)
        self.machine_wait_view.update()
        self.frame.body = self.machine_wait_view

    def render_add_services_dialog(self, deploy_cb, cancel_cb):
        def reset():
            self.add_services_dialog = None

        def cancel():
            reset()
            cancel_cb()

        def deploy():
            reset()
            deploy_cb()

        if self.add_services_dialog is None:
            self.add_services_dialog = AddServicesDialog(self.controller,
                                                         deploy_cb=deploy,
                                                         cancel_cb=cancel)
        self.add_services_dialog.update()
        self.frame.body = Filler(self.add_services_dialog)

    def show_exception_message(self, ex):
        if isinstance(ex, async.ThreadCancelledException):
            log.debug("Thread cancelled intentionally.")
        else: