def enter(self): '''enter method for the progress screen''' toplevel = self.set_main_window_content("failurewindowtable") # Screen-specific configuration self.activate_stage_label("finishstagelabel") logbutton = self.builder.get_object("failurelogbutton") quitbutton = self.builder.get_object("quitbutton") self.nextbutton = self.builder.get_object("nextbutton") self.installbutton = self.builder.get_object("installbutton") if None in [ logbutton, quitbutton, self.nextbutton, self.installbutton ]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG) logbutton.connect("clicked", self.logbutton_callback, None) logbutton.grab_focus() quitbutton.set_sensitive(True) self.installbutton.hide_all() self.nextbutton.show_all() self.set_titles(_("Failure"), _(" "), None) self.set_back_next(back_sensitive=False, next_sensitive=False) toplevel.show_all() return False
def dhcp_autodiscovery_toggled(self, widget, user_data=None): ''' Signal handler for "toggled" event in self._discovery_dhcp_radio widget. ''' if widget.get_active(): if self._dhcp_ip is not None: try: segments = IPAddress.convert_address(self._dhcp_ip) except ValueError as error: title = INVALID_IP_MSG msg = self._dhcp_ip + ' : ' + str(error) LOGGER.error(title) LOGGER.error(msg) modal_dialog(title, msg) else: self._discovery_target_ip_1_entry.set_text(str( segments[0])) self._discovery_target_ip_2_entry.set_text(str( segments[1])) self._discovery_target_ip_3_entry.set_text(str( segments[2])) self._discovery_target_ip_4_entry.set_text(str( segments[3])) if self._dhcp_port is not None: self._discovery_port_entry.set_text(str(self._dhcp_port)) if self._dhcp_lun is not None: self._discovery_lun_entry.set_text(str(self._dhcp_lun)) if self._dhcp_target is not None: self._discovery_target_name_entry.set_text( str(self._dhcp_target)) # Gray out the criteria fields self._discovery_criteria_detail_table.set_sensitive(False)
def __init__(self, builder): super(ConfirmScreen, self).__init__(builder) self.name = "Confirmation Screen" self.logger = logging.getLogger(INSTALL_LOGGER_NAME) self.confirmviewport = self.builder.get_object("confirmviewport") self.nextbutton = self.builder.get_object("nextbutton") self.installbutton = self.builder.get_object("installbutton") self.licenseagreementlinkbutton = self.builder.get_object( "licenseagreementlinkbutton") self.licensecheck = self.builder.get_object("licensecheckbutton") self.diskvbox = self.builder.get_object("diskvbox") self.softwarevbox = self.builder.get_object("softwarevbox") self.timezonevbox = self.builder.get_object("timezonevbox") self.languagesvbox = self.builder.get_object("languagesvbox") self.accountvbox = self.builder.get_object("accountvbox") self.supportvbox = self.builder.get_object("supportvbox") if None in [ self.confirmviewport, self.nextbutton, self.installbutton, self.licenseagreementlinkbutton, self.licensecheck, self.diskvbox, self.softwarevbox, self.timezonevbox, self.languagesvbox, self.accountvbox, self.supportvbox ]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG)
def __init__(self, builder): global LOGGER LOGGER = logging.getLogger(INSTALL_LOGGER_NAME) super(TimeZoneScreen, self).__init__(builder) self.name = "TimeZone Screen" # Widgets from Glade XML file self.outervbox = self.builder.get_object("outervbox") self.yearspinner = self.builder.get_object("yearspinner") self.monthspinner = self.builder.get_object("monthspinner") self.dayspinner = self.builder.get_object("dayspinner") self.hourspinner = self.builder.get_object("hourspinner") self.minutespinner = self.builder.get_object("minutespinner") self.ampmcombobox = self.builder.get_object("ampmcombobox") self.datelabel = self.builder.get_object("datelabel") self.timelabel = self.builder.get_object("timelabel") if None in [ self.outervbox, self.yearspinner, self.monthspinner, self.dayspinner, self.hourspinner, self.minutespinner, self.ampmcombobox, self.datelabel, self.timelabel ]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG) # Custom Timer widget, created on first entry to screen self.timezone = None self.timer = None self.currentmin = None self.previndex_ampm = 2
def __init__(self, builder): '''initialize the helpdialog''' self.builder = builder self.helpdialog = self.builder.get_object("helpdialog") self.textview = self.builder.get_object("helptextview") closebutton = self.builder.get_object("helpclosebutton") if None in [self.helpdialog, self.textview, closebutton]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG) self.helpdialog.connect("delete_event", self.destroy_event) if self.helpdialog.window: self.helpdialog.window.set_functions(gtk.gdk.FUNC_CLOSE) # add bold and underline tags to the text buffer text_buffer = self.textview.get_buffer() if text_buffer: text_buffer.create_tag("bold", weight=pango.WEIGHT_BOLD) text_buffer.create_tag("underline", underline=pango.UNDERLINE_SINGLE) # setup the close button clicked callback if closebutton: closebutton.connect("clicked", self.closebutton_callback, None)
def __init__(self, builder, parent_screen): global LOGGER LOGGER = logging.getLogger(INSTALL_LOGGER_NAME) gtk.VBox.__init__(self) self.builder = builder # Save a reference to the TimeZoneScreen that contains this # Timezone object, so we can call its set_current_date_and_time() # when a different time zone is selected. self.parent_screen = parent_screen self.map = Map() self.map.load_timezones() self.map.modify_bg(gtk.STATE_NORMAL, COLOR_WHITE) self.map.show() self.pack_start(self.map, expand=False, fill=False, padding=0) gobject.GObject.connect(self, "button-press-event", self.on_button_pressed, self) gobject.GObject.connect(self, "button-release-event", self.on_button_released, self) gobject.GObject.connect(self, "motion-notify-event", self.on_motion_notify) # "has-tooltip" property is being set on Timezone, rather # than Map, so that event co-ords are consistent with # "motion-notify-event" co-ords. gobject.GObject.set_property(self, "has-tooltip", True) settings = self.get_settings() gobject.GObject.set_property(settings, "gtk-tooltip-timeout", 50) gobject.GObject.connect(self, "query-tooltip", self.on_query_tooltip) self.ctnt_store = None self.ctry_store = None self.tz_store = None self.combo = self.builder.get_object("timezonetoplevel") self.ctnt_combo = self.builder.get_object("regioncombobox") self.ctry_combo = self.builder.get_object("countrycombobox") self.tz_combo = self.builder.get_object("timezonecombobox") self.ctnt_label = self.builder.get_object("regionlabel") self.ctry_label = self.builder.get_object("countrylabel") self.tz_label = self.builder.get_object("timezonelabel") if None in [ self.combo, self.ctnt_combo, self.ctry_combo, self.tz_combo, self.ctnt_label, self.ctry_label, self.tz_label ]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG) self.combo_init() self.on_all_timezones_added() self.click_time = None
def __init__(self, builder): super(WelcomeScreen, self).__init__(builder) self.name = "Welcome Screen" self.widget = None self.releasenotesbutton = self.builder.get_object('releasenotesbutton') if None in [self.releasenotesbutton]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG)
def __init__(self, builder, finishapp): super(ProgressScreen, self).__init__(builder) self.name = "Progress Screen" self.finishapp = finishapp self.timer = None self.finish_timer = None self.success = False self.fraction = 0.0 self.message = None self.update_screen = False self.show_url = None self.logger = logging.getLogger(INSTALL_LOGGER_NAME) self.installationeventbox = self.builder.get_object( "installationeventbox") self.installationimage = self.builder.get_object("installationimage") self.installationprogressbar = self.builder.get_object( "installationprogressbar") self.installationinfolabel = self.builder.get_object( "installationinfolabel") self.installbutton = self.builder.get_object("installbutton") self.quitbutton = self.builder.get_object("quitbutton") if None in [ self.installationeventbox, self.installationimage, self.installationprogressbar, self.installationinfolabel, self.installbutton, self.quitbutton ]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG) # get the current locale locale_ops = g11nsvc.G11NSvcLocaleOperations() locale = locale_ops.getlocale() # check for a localized image directory path = os.path.join(IMAGE_DIR, locale) if not os.path.exists(path): path = os.path.join(IMAGE_DIR, 'C') if not os.path.exists(path): self.logger.debug("Unable to determine image directory") try: self.urlimage_dictionary = self.get_urlimage_dictionary(path) except IOError: self.urlimage_dictionary = dict() self.image_index = 0 self.image_pause = False self.installationprogressbar.modify_bg(gtk.STATE_NORMAL, COLOR_WHITE) self.installationeventbox.modify_bg(gtk.STATE_NORMAL, COLOR_WHITE) self.install_complete = False
def __init__(self, builder, logname, quitapp): '''initialize the textview dialog''' self.builder = builder self.logname = logname self.quitapp = quitapp self.textviewdialog = self.builder.get_object("textviewdialog") self.textview = self.builder.get_object("textview") quitbutton = self.builder.get_object("textviewclosebutton") if None in [self.textviewdialog, self.textview, quitbutton]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG) self.textviewdialog.set_title(_("Installation Log")) self.textviewdialog.connect("delete_event", self.destroy_event) # setup the close button clicked callback quitbutton.connect("clicked", self.textview_close_callback, None)
def __init__(self, builder): self.builder = builder self.screencontentvbox = self.builder.get_object("screencontentvbox") self.screentitlelabel = self.builder.get_object("screentitlelabel") self.screentitlesublabel1 = self.builder.get_object( "screentitlesublabel1") self.screentitlesublabel2 = self.builder.get_object( "screentitlesublabel2") self.backbutton = self.builder.get_object("backbutton") self.nextbutton = self.builder.get_object("nextbutton") if None in [ self.screencontentvbox, self.screentitlelabel, self.screentitlesublabel1, self.screentitlesublabel2, self.backbutton, self.nextbutton ]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG)
def __init__(self, builder, logname, quitapp): self.logger = logging.getLogger(INSTALL_LOGGER_NAME) super(FinishScreen, self).__init__(builder) self.name = "Finish Screen" self.textview_dialog = None self.logname = logname self.quitapp = quitapp self.logbutton = self.builder.get_object("finishlogbutton") self.quitbutton = self.builder.get_object("quitbutton") self.rebootbutton = self.builder.get_object("rebootbutton") self.installbutton = self.builder.get_object("installbutton") if None in [ self.logbutton, self.quitbutton, self.rebootbutton, self.installbutton ]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG)
def validate(self): ''' Validate the user selections before proceeding. Raises: NotOkToProceedError ''' LOGGER.info("Starting Disk Discovery validation.") iscsi = None doc = InstallEngine.get_instance().doc # error #1 - at least one disk type must be checked if not self._discovery_local_check.get_active() and \ not self._discovery_iscsi_check.get_active(): msg = "No disk types selected." LOGGER.error(NO_DISK_TYPE_SELECTED_MSG) modal_dialog(NO_DISK_TYPE_SELECTED_MSG, SELECT_DISK_TYPE_MSG) raise NotOkToProceedError(msg) if self._discovery_iscsi_check.get_active(): # Save the on-screen iSCSI criteria values self._target_ip = '' text = self._discovery_target_ip_1_entry.get_text() if len(text): self._target_ip += text self._target_ip += '.' text = self._discovery_target_ip_2_entry.get_text() if len(text): self._target_ip += text self._target_ip += '.' text = self._discovery_target_ip_3_entry.get_text() if len(text): self._target_ip += text self._target_ip += '.' text = self._discovery_target_ip_4_entry.get_text() if len(text): self._target_ip += text text = self._discovery_lun_entry.get_text() if len(text): self._target_lun = text else: self._target_lun = None text = self._discovery_target_name_entry.get_text() if len(text): self._target_name = text else: self._target_name = None text = self._discovery_port_entry.get_text() if len(text): self._target_port = text else: self._target_port = None text = self._discovery_initiator_name_entry.get_text() if len(text): self._initiator_name = text else: self._initiator_name = None if self._discovery_chap_check.get_active(): text = self._discovery_chap_name_entry.get_text() if len(text): self._chap_name = text else: self._chap_name = None text = self._discovery_chap_pass_entry.get_text() if len(text): self._chap_password = text else: self._chap_password = None else: self._chap_name = None self._chap_password = None LOGGER.info("iSCSI criteria") LOGGER.info("==============") LOGGER.info("Target IP: %s", self._target_ip) LOGGER.info("LUN: %s", self._target_lun) LOGGER.info("Target Name: %s", self._target_name) LOGGER.info("Port: %s", self._target_port) LOGGER.info("Initiator Name: %s", self._initiator_name) LOGGER.info("CHAP Name: %s", self._chap_name) if self._chap_password is not None: log_pw = '*' * len(self._chap_password) else: log_pw = None LOGGER.info("CHAP Password: %s", log_pw) # ERROR - required fields must be entered required_fields = { self._discovery_target_ip_1_entry: TARGET_IP_1_FIELD, self._discovery_target_ip_2_entry: TARGET_IP_2_FIELD, self._discovery_target_ip_3_entry: TARGET_IP_3_FIELD, self._discovery_target_ip_4_entry: TARGET_IP_4_FIELD, } # self._discovery_lun_entry: TARGET_LUN_FIELD, for field in required_fields: if not field.get_text(): msg = REQUIRED_FIELD_MISSING_MSG LOGGER.error(msg + " : " + required_fields[field]) modal_dialog( msg, ENTER_REQUIRED_FIELD_MSG + required_fields[field]) field.grab_focus() raise NotOkToProceedError(msg) # ERROR - IP must be proper IP address try: IPAddress.convert_address(self._target_ip) except ValueError as error: msg = INVALID_IP_MSG LOGGER.error(msg + " : " + str(error)) modal_dialog(msg, str(error)) self._discovery_target_ip_1_entry.grab_focus() raise NotOkToProceedError(msg) # ERROR - Initiator Name must match regular expression if self._initiator_name is not None: if IQN_RE.match(self._initiator_name) is None: msg = INVALID_INITIATOR_IQN_MSG LOGGER.error(msg) modal_dialog(msg, ENTER_VALID_VALUE_MSG) self._discovery_initiator_name_entry.grab_focus() raise NotOkToProceedError(msg) # ERROR - Target name name must match regular expression if self._target_name is not None: if IQN_RE.match(self._target_name) is None: msg = INVALID_TARGET_IQN_MSG LOGGER.error(msg) modal_dialog(msg, ENTER_VALID_VALUE_MSG) self._discovery_target_name_entry.grab_focus() raise NotOkToProceedError(msg) # ERROR - if CHAP name is given, password must also # be given, and vice versa if self._chap_name and not self._chap_password: msg = CHAP_PASSWORD_MISSING LOGGER.error(msg) modal_dialog(msg, ENTER_VALID_VALUE_MSG) self._discovery_chap_pass_entry.grab_focus() raise NotOkToProceedError(msg) if self._chap_password and not self._chap_name: msg = CHAP_USERNAME_MISSING LOGGER.error(msg) modal_dialog(msg, ENTER_VALID_VALUE_MSG) self._discovery_chap_name_entry.grab_focus() raise NotOkToProceedError(msg) # ERROR - CHAP password must be correct length if self._chap_password is not None: if not 12 <= len(self._chap_password) <= 16: msg = CHAP_PASSWORD_INVALID_LENGTH LOGGER.error(msg) modal_dialog(msg, ENTER_VALID_VALUE_MSG) self._discovery_chap_pass_entry.grab_focus() raise NotOkToProceedError(msg) # ERROR - must be able to connect to LUN to verify iSCSI disk # teardown any currently-configured Iscsis before trying # to connect to new LUN old_iscsis = doc.volatile.get_children(name=ISCSI_LABEL, class_type=Iscsi) for old_iscsi in old_iscsis: try: LOGGER.debug("teardown previous iSCSI: %s", old_iscsi) old_iscsi.teardown() except CalledProcessError as error: # Not a fatal error LOGGER.warn("Iscsi.teardown failed: " + str(error)) # remove from 'discovered targets' any Disks associated with # this iSCSI target if old_iscsi.ctd_list: discovered = doc.persistent.get_first_child( name=Target.DISCOVERED) for disk in discovered.get_descendants(class_type=Disk): if disk.ctd in old_iscsi.ctd_list: disk.delete() iscsi = Iscsi(ISCSI_LABEL) iscsi.target_ip = self._target_ip iscsi.target_lun = self._target_lun iscsi.target_name = self._target_name iscsi.target_port = self._target_port # Don't attempt to change the initiator node name if iSCSI booting if not is_iscsiboot(): iscsi.initiator_name = self._initiator_name iscsi.chap_name = self._chap_name iscsi.chap_password = self._chap_password # Depending on validity and location of IP, Iscsi.setup_iscsi() # can take a while, so show a status message and run setup_iscsi() # in a separate thread (otherwise the GUI would appear # unresponsive and the user may think it has hung). self.set_back_next(back_sensitive=False, next_sensitive=False) if iscsi.target_lun is not None: self._discovery_status_label.set_markup( '<span font_desc="Bold">%s</span>' % MAPPING_LUN_MSG) else: self._discovery_status_label.set_markup( '<span font_desc="Bold">%s</span>' % MAPPING_TARGET_MSG) self._discovery_status_label.show() thread = SetupIscsiThread(iscsi) # Keep passing control back to Gtk+ to process its event queue # until SetupIscsiThread has completed. while thread.is_alive(): while gtk.events_pending(): gtk.main_iteration(False) # allow the thread some time to do it's work time.sleep(0.1) self._discovery_status_label.hide() self.set_back_next(back_sensitive=True, next_sensitive=True) if thread.error is not None: msg = CANNOT_MAP_LUN_MSG LOGGER.error(msg) LOGGER.error(str(thread.error)) modal_dialog(msg, str(thread.error)) self._discovery_target_ip_1_entry.grab_focus() raise NotOkToProceedError(msg) # Validation is complete. Now: # - save user choices (Local disks, iSCSI) in user profile # if iSCSI option was checked: # - save Iscsi obj in DOC # - run TargetDiscovery(iSCSI), either right now or when # other TDs are finished profile = doc.volatile.get_first_child(name="GUI Install", class_type=InstallProfile) if profile is None: raise RuntimeError("INTERNAL ERROR: Unable to retrieve " "InstallProfile from DataObjectCache") profile.set_disk_selections( show_local=self._discovery_local_check.get_active(), show_iscsi=self._discovery_iscsi_check.get_active()) if self._discovery_iscsi_check.get_active(): # There should only be one Iscsi obj in DOC at a time for old_iscsi in old_iscsis: LOGGER.debug("Removing old Iscsi object from DOC: %s", old_iscsi) old_iscsi.delete() doc.volatile.insert_children(iscsi) # If other TargetDiscoveries (eg local disk) have already # completed, then run TD(iSCSI) now, otherwise queue it to # run later if is_discovery_complete(): LOGGER.debug("Starting TargetDiscovery(iSCSI) directly") start_td_iscsi() else: LOGGER.debug("Queueing TargetDiscovery(iSCSI) to run later") queue_td_iscsi() # Every time we progress from this screen, set a flag to tell # the Disk Screen that it must re-process the TD results set_td_results_state(False)
def __init__(self, builder): ''' Initializer method - called from constructor. Params: - builder, a gtk.Builder object, used to retrieve Gtk+ widgets from Glade XML files. Returns: Nothing ''' global LOGGER LOGGER = logging.getLogger(INSTALL_LOGGER_NAME) super(DiskDiscoveryScreen, self).__init__(builder) self.name = "Disk Discovery Screen" self._dhcp_ip = None self._dhcp_port = None self._dhcp_lun = None self._dhcp_target = None self._iscsi = None self._target_ip = None self._target_lun = None self._target_name = None self._target_port = None self._initiator_name = None self._chap_name = None self._chap_password = None self._toplevel = None # Fetch all the gtk.Builder widgets we need in this class self._discovery_top_level_vbox = self.builder.get_object( "discovery_top_level_vbox") self._discovery_local_check = self.builder.get_object( "discovery_local_check") self._discovery_iscsi_check = self.builder.get_object( "discovery_iscsi_check") self._discovery_iscsi_detail_vbox = self.builder.get_object( "discovery_iscsi_detail_vbox") self._discovery_dhcp_radio = self.builder.get_object( "discovery_dhcp_radio") self._discovery_dhcp_unavail_label = self.builder.get_object( "discovery_dhcp_unavail_label") self._discovery_criteria_radio = self.builder.get_object( "discovery_criteria_radio") self._discovery_criteria_detail_table = self.builder.get_object( "discovery_criteria_detail_table") self._discovery_target_ip_1_entry = self.builder.get_object( "discovery_target_ip_1_entry") self._discovery_target_ip_2_entry = self.builder.get_object( "discovery_target_ip_2_entry") self._discovery_target_ip_3_entry = self.builder.get_object( "discovery_target_ip_3_entry") self._discovery_target_ip_4_entry = self.builder.get_object( "discovery_target_ip_4_entry") self._discovery_lun_entry = self.builder.get_object( "discovery_lun_entry") self._discovery_target_name_entry = self.builder.get_object( "discovery_target_name_entry") self._discovery_port_entry = self.builder.get_object( "discovery_port_entry") self._discovery_initiator_name_label = self.builder.get_object( "discovery_initiator_name_label") self._discovery_initiator_name_entry = self.builder.get_object( "discovery_initiator_name_entry") self._discovery_iscsi_boot_label = self.builder.get_object( "discovery_iscsi_boot_label") self._discovery_chap_check = self.builder.get_object( "discovery_chap_check") self._discovery_chap_detail_table = self.builder.get_object( "discovery_chap_detail_table") self._discovery_chap_name_entry = self.builder.get_object( "discovery_chap_name_entry") self._discovery_chap_pass_entry = self.builder.get_object( "discovery_chap_pass_entry") self._discovery_status_label = self.builder.get_object( "discovery_status_label") if None in [ self._discovery_top_level_vbox, self._discovery_local_check, self._discovery_iscsi_check, self._discovery_iscsi_detail_vbox, self._discovery_dhcp_radio, self._discovery_dhcp_unavail_label, self._discovery_criteria_radio, self._discovery_criteria_detail_table, self._discovery_target_ip_1_entry, self._discovery_target_ip_2_entry, self._discovery_target_ip_3_entry, self._discovery_target_ip_4_entry, self._discovery_lun_entry, self._discovery_target_name_entry, self._discovery_port_entry, self._discovery_initiator_name_label, self._discovery_initiator_name_entry, self._discovery_iscsi_boot_label, self._discovery_chap_check, self._discovery_chap_detail_table, self._discovery_chap_name_entry, self._discovery_chap_pass_entry, self._discovery_status_label ]: modal_dialog(INTERNAL_ERROR_MSG, GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG)
def _first_time_init(self): ''' Screen initiatization tasks that are only to be performed on the first occasion this screen is brought up. ''' # Check if DHCP Autodiscovery is available. If it is, we will # pre-populate fields using the autodiscovery rootpath details. dhcp_params = Iscsi.get_dhcp() if dhcp_params is not None: self._dhcp_ip = dhcp_params[0] self._dhcp_port = dhcp_params[1] self._dhcp_lun = dhcp_params[2] self._dhcp_target = dhcp_params[3] # Set various form fields to their initial state of # grayed out/active, checked/unchecked, hidden/visible, etc self._discovery_local_check.set_active(True) if self._dhcp_ip is None: self._discovery_dhcp_radio.set_sensitive(False) else: self._discovery_dhcp_unavail_label.hide() self._discovery_criteria_radio.set_active(True) self._discovery_chap_detail_table.set_sensitive(False) self._discovery_iscsi_detail_vbox.hide() # Pre-populate the iSCSI Port field self._discovery_port_entry.set_text(Iscsi.ISCSI_DEFAULT_PORT) # Pre-populate initiator name with the for this host LOGGER.debug("Getting iSCSI Initiator Node Name for this system") cmd = [ISCSIADM, "list", "initiator-node"] try: popen = run(cmd) except CalledProcessError as error: title = NO_INITIATOR_NODE_MSG msg = cmd + " failed : " + str(error) LOGGER.error(title) LOGGER.error(msg) modal_dialog(title, msg) else: for line in popen.stdout.splitlines(): if line.startswith("Initiator node name:"): initiator_name = line.split(": ")[1] break if initiator_name is not None: self._discovery_initiator_name_entry.set_text(initiator_name) LOGGER.debug("iSCSI Initiator Name is: ", initiator_name) else: title = NO_INITIATOR_NODE_MSG msg = popen.stdout.splitlines() LOGGER.error(title) LOGGER.error(msg) modal_dialog(title, msg) # initiator-name is not changeable for iscsi booting, so disable # the field in this case if is_iscsiboot(): LOGGER.debug("iSCSI booting - disabling initiator node field") self._discovery_initiator_name_label.set_sensitive(False) self._discovery_initiator_name_entry.set_sensitive(False) else: self._discovery_iscsi_boot_label.hide()
def __init__(self, builder): ''' Initializer method - called from constructor. Params: - builder, a gtk.Builder object, used to retrieve Gtk+ widgets from Glade XML files. Returns: Nothing ''' global LOGGER LOGGER = logging.getLogger(INSTALL_LOGGER_NAME) super(SupportScreen, self).__init__(builder) self.name = "Support Screen" self._support_email_entry = None self._support_authenticate_checkbox = None self._support_authenticate_section = None self._support_password_entry = None self._support_net_access_section = None self._support_no_proxy_radio = None self._support_proxy_radio = None self._support_proxy_section = None self._support_proxy_hostname_entry = None self._support_proxy_port_entry = None self._support_proxy_username_entry = None self._support_proxy_password_entry = None self._support_aggregation_radio = None self._support_aggregation_section = None self._support_ocm_entry = None self._support_asr_entry = None self._support_status_label = None self._toplevel = None self._email = None self._mos_pass = None self._proxy_hostname = None self._proxy_port = None self._proxy_username = None self._proxy_pass = None self._ocm_url = None self._asr_url = None self._auth_chosen = None self._no_proxy_chosen = None self._proxy_chosen = None self._aggregation_chosen = None self._support_info = None self._last_validation_ok = False self._allow_error_override = False self._allow_no_reg_override = False # Fetch all the gtk.Builder widgets we need in this class self._support_email_entry = self.builder.get_object( "support_email_entry") self._support_authenticate_checkbox = self.builder.get_object( "support_authenticate_checkbox") self._support_authenticate_section = self.builder.get_object( "support_authenticate_section") self._support_password_entry = self.builder.get_object( "support_password_entry") self._support_net_access_section = self.builder.get_object( "support_net_access_section") self._support_no_proxy_radio = self.builder.get_object( "support_no_proxy_radio") self._support_proxy_radio = self.builder.get_object( "support_proxy_radio") self._support_proxy_section = self.builder.get_object( "support_proxy_section") self._support_proxy_hostname_entry = self.builder.get_object( "support_proxy_hostname_entry") self._support_proxy_port_entry = self.builder.get_object( "support_proxy_port_entry") self._support_proxy_username_entry = self.builder.get_object( "support_proxy_username_entry") self._support_proxy_password_entry = self.builder.get_object( "support_proxy_password_entry") self._support_aggregation_radio = self.builder.get_object( "support_aggregation_radio") self._support_aggregation_section = self.builder.get_object( "support_aggregation_section") self._support_ocm_entry = self.builder.get_object("support_ocm_entry") self._support_asr_entry = self.builder.get_object("support_asr_entry") self._support_status_label = self.builder.get_object( "support_status_label") if None in [ self._support_email_entry, self._support_authenticate_checkbox, self._support_authenticate_section, self._support_password_entry, self._support_net_access_section, self._support_no_proxy_radio, self._support_proxy_radio, self._support_proxy_section, self._support_proxy_hostname_entry, self._support_proxy_port_entry, self._support_proxy_username_entry, self._support_proxy_password_entry, self._support_aggregation_radio, self._support_aggregation_section, self._support_ocm_entry, self._support_asr_entry, self._support_status_label, ]: modal_dialog(INTERNAL_ERR_MSG, GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG)
def _do_authentication(self): ''' Setup and run a thread to call OCM/ASR authentication. Returns: nothing Raises: NotOkToProceedError ''' if self._no_proxy_chosen: net_mode = SupportInfo.DIRECT elif self._proxy_chosen: net_mode = SupportInfo.PROXY else: # must be Aggregation hub net_mode = SupportInfo.HUB # This operation can take more than a few seconds, so: # - disable the Back/Next buttons # - show a status message # - run authentication in a separate thread # - wait for thread to finish # (otherwise GUI would appear unresponsive) self.set_back_next(back_sensitive=False, next_sensitive=False) self._support_status_label.set_markup( '<span font_desc="Bold">%s</span>' % AUTHENTICATING_MSG) self._support_status_label.show() thread = AuthenticationThread(self._support_info, net_mode) # Keep passing control back to Gtk+ to process its event queue # until AuthenticationThread has completed. while thread.isAlive(): while gtk.events_pending(): gtk.main_iteration(False) # allow the thread some time to do it's work time.sleep(AUTH_SLEEP_INTERVAL) ocm_status = thread.ocm_status asr_status = thread.asr_status # Log the results LOGGER.debug("authentication return values") LOGGER.debug(" ocm_status [%s]", ocm_status) LOGGER.debug(" asr_status [%s]", asr_status) # Reset the screen self._support_status_label.hide() self.set_back_next(back_sensitive=True, next_sensitive=True) # Handle any errors returned by either OCM or ASR if (ocm_status != SupportInfo.OCM_SUCCESS or asr_status != SupportInfo.ASR_SUCCESS): LOGGER.error("Error returned by OCM and/or ASR:") self._last_validation_ok = False # Construct error messages for the failures reported # by OCM and/or ASR err_title = '' err_msg = '' if ocm_status != SupportInfo.OCM_SUCCESS: err_title += OCM_AUTH_FAILED_MSG if ocm_status == SupportInfo.PH_TIMEOUT: err_msg += SupportInfo.MSGS["ocm_timeout"] elif ocm_status == SupportInfo.OCM_BAD_CRED: err_msg += SupportInfo.MSGS["ocm_bad_cred"] elif ocm_status == SupportInfo.OCM_NET_ERR: err_msg += SupportInfo.MSGS["ocm_net_err"] else: err_msg += SupportInfo.MSGS["ocm_auth_err"] if asr_status != SupportInfo.ASR_SUCCESS: if err_title: err_title += "\n" if err_msg: err_msg += "\n" err_title += ASR_AUTH_FAILED_MSG if asr_status == SupportInfo.PH_TIMEOUT: err_msg += SupportInfo.MSGS["asr_timeout"] elif asr_status == SupportInfo.ASR_BAD_CRED: err_msg += SupportInfo.MSGS["asr_bad_cred"] elif asr_status == SupportInfo.ASR_NET_ERR: err_msg += SupportInfo.MSGS["asr_net_err"] else: err_msg += SupportInfo.MSGS["asr_auth_err"] # If both OCM and ASR returned BAD_CRED, then do not allow # error override; otherwise do. # (eg either the failure(s) were due to networking, etc, or # one returned BAD_CRED and other didn't - which indicates # a problem with the auth servers) if (ocm_status == SupportInfo.OCM_BAD_CRED and asr_status == SupportInfo.ASR_BAD_CRED): LOGGER.info("Both OCM and ASR returned BAD_CRED - not " "allowing error override") self._allow_error_override = False else: LOGGER.info("Failure(s) were either not due to BAD_CRED, " " or were inconsistent - allowing errror override") self._allow_error_override = True if self._allow_error_override: err_msg = err_msg + "\n\n" + OVERRIDE_ALLOWED_MSG self._support_email_entry.grab_focus() LOGGER.error(err_msg) modal_dialog(err_title, err_msg) raise NotOkToProceedError(err_msg) # Authentication was successful. # Set flag so we don't have to authenticate again if user doesn't # change anything LOGGER.info("Support authentication was successful.") self._last_validation_ok = True
def validate(self): ''' Validate the user selections before proceeding. Raises: NotOkToProceedError ''' LOGGER.info("Starting Support Registration validation.") # Gather user inputs from screen email = None if self._support_email_entry.get_text(): email = self._support_email_entry.get_text() auth_chosen = self._support_authenticate_checkbox.get_active() mos_pass = None if auth_chosen: if self._support_password_entry.get_text(): mos_pass = self._support_password_entry.get_text() no_proxy_chosen = self._support_no_proxy_radio.get_active() proxy_chosen = self._support_proxy_radio.get_active() proxy_hostname = None proxy_port = None proxy_username = None proxy_pass = None if proxy_chosen: if self._support_proxy_hostname_entry.get_text(): proxy_hostname = self._support_proxy_hostname_entry.get_text() if self._support_proxy_port_entry.get_text(): proxy_port = self._support_proxy_port_entry.get_text() if self._support_proxy_username_entry.get_text(): proxy_username = self._support_proxy_username_entry.get_text() if self._support_proxy_password_entry.get_text(): proxy_pass = self._support_proxy_password_entry.get_text() aggregation_chosen = self._support_aggregation_radio.get_active() ocm_url = None asr_url = None if aggregation_chosen: if self._support_ocm_entry.get_text(): ocm_url = self._support_ocm_entry.get_text() if self._support_asr_entry.get_text(): asr_url = self._support_asr_entry.get_text() LOGGER.debug("User inputs:") LOGGER.debug("Email [%s]", email) LOGGER.debug("Enter MOS password? [%s]", auth_chosen) if mos_pass is not None: log_pw = '*' * len(mos_pass) else: log_pw = None LOGGER.debug(" MOS Password [%s]", log_pw) LOGGER.debug("No proxy? [%s]", no_proxy_chosen) LOGGER.debug("Proxy? [%s]", proxy_chosen) LOGGER.debug(" Hostname [%s]", proxy_hostname) LOGGER.debug(" Port [%s]", proxy_port) LOGGER.debug(" Username [%s]", proxy_username) if proxy_pass is not None: log_pw = '*' * len(proxy_pass) else: log_pw = None LOGGER.debug(" Password [%s]", log_pw) LOGGER.debug("Aggregation Hubs? [%s]", aggregation_chosen) LOGGER.debug(" OCM Hub URL [%s]", ocm_url) LOGGER.debug(" ASR Manager URL [%s]", asr_url) # Validate user inputs: # ERROR - password entered, but no email if mos_pass and not email: self._support_email_entry.grab_focus() msg1 = SupportInfo.MSGS["pswd_no_email"] msg2 = ENTER_VALID_EMAIL_MSG LOGGER.error(VALIDATION_ERROR_MSG) LOGGER.error(msg1) modal_dialog(msg1, msg2) raise NotOkToProceedError(msg1) # ERROR - incorrectly formatted email address if email: if '@' not in email or email[-1] == '@': self._support_email_entry.grab_focus() msg1 = SupportInfo.MSGS["missing_@"] msg2 = ENTER_VALID_EMAIL_MSG LOGGER.error(VALIDATION_ERROR_MSG) LOGGER.error(msg1) modal_dialog(msg1, msg2) raise NotOkToProceedError(msg1) # ERROR - authentication requested, but no password given if auth_chosen and mos_pass is None: self._support_password_entry.grab_focus() msg1 = MISSING_PASSWD_ERROR msg2 = ENTER_VALID_PASSWD_MSG LOGGER.error(VALIDATION_ERROR_MSG) LOGGER.error(msg1) modal_dialog(msg1, msg2) raise NotOkToProceedError(msg1) # ERROR - Proxy chosen, but no proxy hostname given if proxy_chosen and not proxy_hostname: self._support_proxy_hostname_entry.grab_focus() msg1 = MISSING_PROXY_HOST_ERROR msg2 = ENTER_PROXY_HOST_MSG LOGGER.error(VALIDATION_ERROR_MSG) LOGGER.error(msg1) modal_dialog(msg1, msg2) raise NotOkToProceedError(msg1) # ERROR - only one of proxy password or username was given if proxy_chosen and (bool(proxy_username) != bool(proxy_pass)): self._support_proxy_username_entry.grab_focus() msg1 = PROXY_USER_PASS_ERROR msg2 = ENTER_PROXY_USER_PASS_MSG LOGGER.error(VALIDATION_ERROR_MSG) LOGGER.error(msg1) modal_dialog(msg1, msg2) raise NotOkToProceedError(msg1) # ERROR - Aggregation Hub chosen, but neither OCM nor ASR Hub given if aggregation_chosen and not ocm_url and not asr_url: self._support_ocm_entry.grab_focus() msg1 = NO_HUB_ERROR msg2 = ENTER_OCM_ASR_MSG LOGGER.error(VALIDATION_ERROR_MSG) LOGGER.error(msg1) modal_dialog(msg1, msg2) raise NotOkToProceedError(msg1) # WARNING - don't allow user to skip registration without # showing them a warning message if not email and not self._allow_no_reg_override: # set flag so we only show this once; next time just proceed self._allow_no_reg_override = True msg1 = SupportInfo.MSGS["no_email"] msg2 = NO_REG_WARN_MSG LOGGER.info("Validation Warning:") LOGGER.info(msg1) ok_to_proceed = modal_dialog(msg1, msg2, two_buttons=True, yes_no=True) if ok_to_proceed: self._clear_sc_profile() return self._support_email_entry.grab_focus() raise NotOkToProceedError(msg1) # Determine if user inputs have changed in any material way from # last time authentication was attempted any_changes = False if self._support_info is None: # First time through sc_profile = from_engine() if sc_profile.support is None: sc_profile.support = SupportInfo() self._support_info = sc_profile.support any_changes = True else: if email != self._email: any_changes = True elif auth_chosen != self._auth_chosen: any_changes = True elif auth_chosen and mos_pass != self._mos_pass: any_changes = True # Note: only one of no_proxy_chosen, proxy_chosen, # aggregation_chosen can be True at a time. elif no_proxy_chosen != self._no_proxy_chosen: any_changes = True elif proxy_chosen != self._proxy_chosen: any_changes = True elif proxy_chosen: if proxy_hostname != self._proxy_hostname: any_changes = True elif proxy_port != self._proxy_port: any_changes = True elif proxy_username != self._proxy_username: any_changes = True elif proxy_pass != self._proxy_pass: any_changes = True elif aggregation_chosen: if ocm_url != self._ocm_url: any_changes = True elif asr_url != self._asr_url: any_changes = True # Save values entered for comparison next time around self._email = email self._auth_chosen = auth_chosen self._mos_pass = mos_pass self._no_proxy_chosen = no_proxy_chosen self._proxy_chosen = proxy_chosen self._proxy_hostname = proxy_hostname self._proxy_port = proxy_port self._proxy_username = proxy_username self._proxy_pass = proxy_pass self._aggregation_chosen = aggregation_chosen self._ocm_url = ocm_url self._asr_url = asr_url # Handle situations where we can proceed without doing authentication # User still authenticated from last time and hasn't changed anything if not any_changes and self._last_validation_ok: LOGGER.debug("No need to repeat validation - continuing") return # User explicitly does not wish to register if not self._email and not self._auth_chosen \ and self._allow_no_reg_override: # Ensure no previous values are saved in SC Profile and proceed LOGGER.info("No email or MOS password given - not registering") self._clear_sc_profile() return # User overriding failed authentication and wishes to proceed anyway if not any_changes and self._allow_error_override: LOGGER.debug("Allowing override of auth error - continuing") return # User didn't provide a password, so no point trying to authenticate if not self._mos_pass: # Save what we have to SC Profile in DOC and proceed LOGGER.debug("Allowing override of auth error - continuing") self._update_sc_profile() return # Save what we have to SC Profile in DOC and perform authentication self._update_sc_profile() self._do_authentication()
def __init__(self, builder): '''Initialize the User Screen class''' super(UserScreen, self).__init__(builder) self.name = "User Screen" self.saved_msg = None self.validation_occurring = False self.saved_msg_type = None self.user_name = self.builder.get_object("usernameentry") self.login_name = self.builder.get_object("loginnameentry") self.password = self.builder.get_object("userpassword1entry") self.verify = self.builder.get_object("userpassword2entry") self.hostname = self.builder.get_object("hostnameentry") self.loginnameinfoimage = self.builder.get_object("loginnameinfoimage") self.loginnameinfolabel = self.builder.get_object("loginnameinfolabel") self.userpasswordinfoimage = self.builder.get_object( "userpasswordinfoimage") self.userpasswordinfolabel = self.builder.get_object( "userpasswordinfolabel") self.hostnameinfoimage = self.builder.get_object("hostnameinfoimage") self.hostnameinfolabel = self.builder.get_object("hostnameinfolabel") loginnamelabel = self.builder.get_object("loginnamelabel") userpasswordlabel1 = self.builder.get_object("userpassword1label") userpasswordlabel2 = self.builder.get_object("userpassword2label") userpasswordentry = self.builder.get_object("userpassword2entry") hostnamelabel = self.builder.get_object("hostnamelabel") if None in [ self.user_name, self.login_name, self.password, self.verify, self.hostname, self.loginnameinfoimage, self.loginnameinfolabel, self.userpasswordinfoimage, self.userpasswordinfolabel, self.hostnameinfoimage, self.hostnameinfolabel, loginnamelabel, userpasswordlabel1, userpasswordlabel2, userpasswordentry, hostnamelabel ]: modal_dialog(_("Internal error"), GLADE_ERROR_MSG) raise RuntimeError(GLADE_ERROR_MSG) # Setup Accessibility relationship for the loginname atk_loginnamelabel = loginnamelabel.get_accessible() self.atk_loginnameinfolabel = self.loginnameinfolabel.get_accessible() atk_parent = self.login_name.get_accessible() relation_set = atk_parent.ref_relation_set() relation = atk.Relation(( atk_loginnamelabel, self.atk_loginnameinfolabel, ), atk.RELATION_LABELLED_BY) relation_set.add(relation) # Setup Accessibility relationship for the password self.atk_passwordinfolabel = \ self.userpasswordinfolabel.get_accessible() atk_userpasswordlabel = userpasswordlabel1.get_accessible() atk_parent = self.password.get_accessible() relation_set = atk_parent.ref_relation_set() relation = atk.Relation(( atk_userpasswordlabel, self.atk_passwordinfolabel, ), atk.RELATION_LABELLED_BY) relation_set.add(relation) atk_userpasswordlabel = userpasswordlabel2.get_accessible() atk_parent = userpasswordentry.get_accessible() relation_set = atk_parent.ref_relation_set() relation = atk.Relation(( atk_userpasswordlabel, self.atk_passwordinfolabel, ), atk.RELATION_LABELLED_BY) relation_set.add(relation) # Setup Accessibility relationship for the hostname self.atk_hostnameinfolabel = self.hostnameinfolabel.get_accessible() atk_hostnamelabel = hostnamelabel.get_accessible() atk_parent = self.hostname.get_accessible() relation_set = atk_parent.ref_relation_set() relation = atk.Relation(( atk_hostnamelabel, self.atk_hostnameinfolabel, ), atk.RELATION_LABELLED_BY) relation_set.add(relation)
def main(): '''Main routine for the gui-install-er''' _init_locale() # This is needed or InstallEngine threading won't work gtk.gdk.threads_init() # check we are running as root if os.getuid() != 0: sys.exit( _("The %s installer must be run as " "root. Quitting.") % RELEASE) if other_instance_is_running(): modal_dialog( _("Installer Startup Terminated"), _("Only one instance of this Installer is allowed. " "Another instance is already running.")) sys.exit( _("Only one instance of this Installer is allowed. " "Another instance is already running.")) write_pid_file() usage = "usage: %prog [-l FILE] [-v LEVEL] [-d]" parser = OptionParser(usage=usage, version="%prog 1.1") parser.add_option("-l", "--log-location", dest="logname", help=_("Set log location to FILE (default: %default)"), metavar="FILE", default=DEFAULT_LOG_LOCATION) parser.add_option("-v", "--log-level", dest="log_level", default=None, help=_("Set log verbosity to LEVEL. In order of " "increasing verbosity, valid values are 'error' " "'warn' 'info' 'debug' or 'input'\n[default:" " %default]"), choices=["error", "warn", "info", "debug", "input"], metavar="LEVEL") parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False, help=_("Enable debug mode. Sets " "logging level to 'input' and enables CTRL-C for " "killing the program\n")) options, args = parser.parse_args() if options.log_level is None: if options.debug: options.log_level = "debug" else: options.log_level = DEFAULT_LOG_LEVEL engine = InstallEngine(loglevel=options.log_level, debug=True) try: logger = setup_logging(options.logname, options.log_level) except IOError, err: parser.error("%s '%s'" % (err.strerror, err.filename))