def build_widgets(self): self.machines_list = MachinesList(self.placement_controller, self.display_controller, None, show_hardware=True, show_assignments=False, show_placeholders=False, show_only_ready=True, title_widgets=[]) self.machines_list.update() self.machines_list_pile = Pile([self.machines_list, Divider()]) return self.machines_list_pile
def build_widgets(self): def has_services_p(m): pc = self.placement_controller n = sum([len(al) for at, al in pc.assignments_for_machine(m).items()]) return n > 0 clear_machine_func = self.placement_view.do_clear_machine show_chooser_func = self.placement_view.do_show_service_chooser self.open_maas_button = AttrMap(Button("Open in Browser", on_press=self.browse_maas), 'button_secondary', 'button_secondary focus') bc = self.placement_view.config.juju_env['bootstrap-config'] maasname = "'{}' <{}>".format(bc['name'], bc['maas-server']) maastitle = "Connected to MAAS {}".format(maasname) tw = Columns([Text(maastitle), Padding(self.open_maas_button, align='right', width=BUTTON_SIZE, right=2)]) self.machines_list = MachinesList(self.placement_controller, [(has_services_p, 'Clear All Services', clear_machine_func), (has_services_p, 'Remove Some Services', show_chooser_func)], show_hardware=True, title_widgets=tw) self.machines_list.update() self.machines_list_pile = Pile([self.machines_list, Divider()]) # placeholders replaced in update() with absolute indexes, so # if you change this list, check update(). pl = [Text(('body', "Machines {}".format(MetaScroll().get_text()[0])), align='center'), Divider(), Pile([]), # machines_list Divider()] self.main_pile = Pile(pl) return self.main_pile
def build_widgets(self): if self.charm_class.allow_multi_units: machine_string = "machines" plural_string = "s" else: machine_string = "a machine" plural_string = "" instructions = Text("Select {} to host {}".format( machine_string, self.charm_class.display_name)) self.service_widget = ServiceWidget(self.charm_class, self.controller, show_constraints=True, show_placements=True) all_actions = [(AssignmentType.BareMetal, 'Add as Bare Metal', self.do_select_baremetal), (AssignmentType.LXC, 'Add as LXC', self.do_select_lxc), (AssignmentType.KVM, 'Add as KVM', self.do_select_kvm)] actions = [(label, func) for atype, label, func in all_actions if atype in self.charm_class.allowed_assignment_types] constraints = self.charm_class.constraints # NOTE: show_assignments=False is a WORKAROUND for #194 self.machines_list = MachinesList(self.controller, actions, constraints=constraints, show_hardware=True, show_assignments=False) self.machines_list.update() close_button = AttrMap(Button('X', on_press=self.close_pressed), 'button_secondary', 'button_secondary focus') p = Pile([GridFlow([close_button], 5, 1, 0, 'right'), instructions, Divider(), self.service_widget, Divider(), self.machines_list]) return LineBox(p, title="Select Machine{}".format(plural_string))
class MachinesColumn(WidgetWrap): """Shows machines or a link to MAAS to add more""" def __init__(self, display_controller, placement_controller, placement_view): self.display_controller = display_controller self.placement_controller = placement_controller self.placement_view = placement_view w = self.build_widgets() super().__init__(w) self.update() def selectable(self): return True def build_widgets(self): def has_services_p(m): pc = self.placement_controller n = sum([len(al) for at, al in pc.assignments_for_machine(m).items()]) return n > 0 clear_machine_func = self.placement_view.do_clear_machine show_chooser_func = self.placement_view.do_show_service_chooser self.open_maas_button = AttrMap(Button("Open in Browser", on_press=self.browse_maas), 'button_secondary', 'button_secondary focus') bc = self.placement_view.config.juju_env['bootstrap-config'] maasname = "'{}' <{}>".format(bc['name'], bc['maas-server']) maastitle = "Connected to MAAS {}".format(maasname) tw = Columns([Text(maastitle), Padding(self.open_maas_button, align='right', width=BUTTON_SIZE, right=2)]) self.machines_list = MachinesList(self.placement_controller, [(has_services_p, 'Clear All Services', clear_machine_func), (has_services_p, 'Remove Some Services', show_chooser_func)], show_hardware=True, title_widgets=tw) self.machines_list.update() self.machines_list_pile = Pile([self.machines_list, Divider()]) # placeholders replaced in update() with absolute indexes, so # if you change this list, check update(). pl = [Text(('body', "Machines {}".format(MetaScroll().get_text()[0])), align='center'), Divider(), Pile([]), # machines_list Divider()] self.main_pile = Pile(pl) return self.main_pile def update(self): self.machines_list.update() bc = self.placement_view.config.juju_env['bootstrap-config'] empty_maas_msg = ("There are no available machines.\n" "Open {} to add machines to " "'{}':".format(bc['maas-server'], bc['name'])) self.empty_maas_widgets = Pile([Text([('error_icon', "\N{WARNING SIGN} "), empty_maas_msg], align='center'), Padding(self.open_maas_button, align='center', width=BUTTON_SIZE)]) # 1 machine is the subordinate placeholder: if len(self.placement_controller.machines()) == 1: self.main_pile.contents[2] = (self.empty_maas_widgets, self.main_pile.options()) else: self.main_pile.contents[2] = (self.machines_list_pile, self.main_pile.options()) def browse_maas(self, sender): bc = self.placement_view.config.juju_env['bootstrap-config'] try: p = Popen(["sensible-browser", bc['maas-server']], stdout=PIPE, stderr=PIPE) outs, errs = p.communicate(timeout=5) except TimeoutExpired: # went five seconds without an error, so we assume it's # OK. Don't kill it, just let it go: return e = errs.decode('utf-8') msg = "Error opening '{}' in a browser:\n{}".format(bc['name'], e) w = InfoDialogWidget(msg, self.placement_view.remove_overlay) self.placement_view.show_overlay(w)
class MachinesColumn(WidgetWrap): """Shows machines or a link to MAAS to add more""" def __init__(self, display_controller, placement_controller, placement_view): self.display_controller = display_controller self.placement_controller = placement_controller self.placement_view = placement_view w = self.build_widgets() super().__init__(w) self.update() def selectable(self): return True def build_widgets(self): self.machines_list = MachinesList(self.placement_controller, self.display_controller, None, show_hardware=True, show_assignments=False, show_placeholders=False, show_only_ready=True, title_widgets=[]) self.machines_list.update() self.machines_list_pile = Pile([self.machines_list, Divider()]) return self.machines_list_pile def update(self): self.machines_list.update() maasinfo = self.placement_controller.maasinfo empty_maas_msg = ("There are no available machines.\n" "Open {} to add machines to " "'{}':".format(maasinfo['server_name'], maasinfo['server_hostname'])) self.empty_maas_widgets = Pile([Text([('error_icon', "\N{WARNING SIGN} "), empty_maas_msg], align='center')]) # 2 machines is the subordinate placeholder + juju default: opts = self.machines_list_pile.options() if len(self.placement_controller.machines()) == 2: self.machines_list_pile.contents[0] = (self.empty_maas_widgets, opts) else: self.machines_list_pile.contents[0] = (self.machines_list, opts) def clear_selections(self): for mw in self.machines_list.machine_widgets: mw.is_selected = False def focus_prev_or_top(self): self.update() try: self.machines_list_pile.focus_position = 0 self.machines_list.focus_prev_or_top() except IndexError: log.debug("caught indexerror in machinesColumn focus_prev_or_top") pass
class MachineChooser(WidgetWrap): """Presents list of machines to assign a service to. Supports multiple selection if the service does. """ def __init__(self, controller, charm_class, parent_widget): self.controller = controller self.charm_class = charm_class self.parent_widget = parent_widget w = self.build_widgets() super().__init__(w) def build_widgets(self): if self.charm_class.allow_multi_units: machine_string = "machines" plural_string = "s" else: machine_string = "a machine" plural_string = "" instructions = Text("Select {} to host {}".format( machine_string, self.charm_class.display_name)) self.service_widget = ServiceWidget(self.charm_class, self.controller, show_constraints=True, show_placements=True) all_actions = [(AssignmentType.BareMetal, 'Add as Bare Metal', self.do_select_baremetal), (AssignmentType.LXC, 'Add as LXC', self.do_select_lxc), (AssignmentType.KVM, 'Add as KVM', self.do_select_kvm)] actions = [(label, func) for atype, label, func in all_actions if atype in self.charm_class.allowed_assignment_types] constraints = self.charm_class.constraints # NOTE: show_assignments=False is a WORKAROUND for #194 self.machines_list = MachinesList(self.controller, actions, constraints=constraints, show_hardware=True, show_assignments=False) self.machines_list.update() close_button = AttrMap(Button('X', on_press=self.close_pressed), 'button_secondary', 'button_secondary focus') p = Pile([GridFlow([close_button], 5, 1, 0, 'right'), instructions, Divider(), self.service_widget, Divider(), self.machines_list]) return LineBox(p, title="Select Machine{}".format(plural_string)) def do_select_baremetal(self, sender, machine): self.do_select(sender, machine, AssignmentType.BareMetal) def do_select_lxc(self, sender, machine): self.do_select(sender, machine, AssignmentType.LXC) def do_select_kvm(self, sender, machine): self.do_select(sender, machine, AssignmentType.KVM) def do_select(self, sender, machine, atype): self.controller.assign(machine, self.charm_class, atype) self.machines_list.update() self.service_widget.update() self.parent_widget.remove_overlay(self) def close_pressed(self, sender): self.parent_widget.remove_overlay(self)
class MachinesColumn(WidgetWrap): """Shows machines or a link to MAAS to add more""" def __init__(self, display_controller, placement_controller, placement_view): self.display_controller = display_controller self.placement_controller = placement_controller self.placement_view = placement_view w = self.build_widgets() super().__init__(w) self.update() def selectable(self): return True def build_widgets(self): self.machines_list = MachinesList(self.placement_controller, self.display_controller, None, show_hardware=True, show_assignments=False, show_placeholders=False, show_only_ready=True, title_widgets=[]) self.machines_list.update() self.machines_list_pile = Pile([self.machines_list, Divider()]) return self.machines_list_pile def update(self): self.machines_list.update() maasinfo = self.placement_controller.maasinfo empty_maas_msg = ("There are no available machines.\n" "Open {} to add machines to " "'{}':".format(maasinfo['server_name'], maasinfo['server_hostname'])) self.empty_maas_widgets = Pile([ Text([('error_icon', "\N{WARNING SIGN} "), empty_maas_msg], align='center') ]) # 2 machines is the subordinate placeholder + juju default: opts = self.machines_list_pile.options() if len(self.placement_controller.machines()) == 2: self.machines_list_pile.contents[0] = (self.empty_maas_widgets, opts) else: self.machines_list_pile.contents[0] = (self.machines_list, opts) def clear_selections(self): for mw in self.machines_list.machine_widgets: mw.is_selected = False def focus_prev_or_top(self): self.update() try: self.machines_list_pile.focus_position = 0 self.machines_list.focus_prev_or_top() except IndexError: log.debug("caught indexerror in machinesColumn focus_prev_or_top") pass