示例#1
0
 def _show(self):
     super(NSLDAPProxyBindInfo, self)._show()
     if self.nameservice.nameservice != 'LDAP':
         raise SkipException
     if self.nameservice.ldap_proxy_bind == \
             NameServiceInfo.LDAP_CHOICE_NO_PROXY_BIND:
         raise SkipException
     y_loc = self._paint_opening()
     y_loc += 1  # blank line
     self.center_win.add_text(self.title, y_loc, INDENT)
     y_loc += 1  # edit field on following line since it should be big
     cols = self.win_size_x - INDENT - 2
     area = WindowArea(1, cols, y_loc, INDENT + 2,
                       scrollable_columns=MAXDNLEN + 1)
     self.ldap_pb_dn = EditField(area, window=self.center_win,
                                 text=self.nameservice.ldap_pb_dn,
                                 error_win=self.main_win.error_line)
     # in case of error, tell user what is being validated
     self.ldap_pb_dn.validate_kwargs['etext'] = _('distinguished name')
     y_loc += 2  # blank line
     titlelen = textwidth(self.title2)
     self.center_win.add_text(self.title2, y_loc, NameService.SCROLL_SIZE)
     cols = self.win_size_x - titlelen - INDENT - 1
     area = WindowArea(1, cols, y_loc, titlelen + INDENT + 1)
     self.ldap_pb_psw = EditField(area, window=self.center_win,
                                  text=self.nameservice.ldap_pb_psw,
                                  error_win=self.main_win.error_line,
                                  masked=True)
     self.main_win.do_update()
     self.center_win.activate_object(self.ldap_pb_dn)
示例#2
0
    def _show(self):
        # This will be used (and re-used) later. It defines a subwindow's
        # location at 1, 1, with width 20 and height 1
        win_area = WindowArea(y_loc=1, x_loc=1, lines=1, columns=20)

        # Creating an empty editable field is just as simple as creating
        # a list item: define a location, and a parent window.
        field_one = EditField(win_area, window=self.center_win)

        # Side trick - a WindowArea can be reused. In this case, the y-coord
        # is updated, and then win_area is used for the next EditField.
        win_area.y_loc = 2

        # Setting default text for a field is also simple:
        field_two = EditField(win_area, window=self.center_win, text="default")

        # For the Text Installer and SCI tool, however, an extra step must
        # be taken. To help with labeling and highlighting, each EditField
        # should be wrapped in a ListItem, like so:
        win_area.y_loc = 3
        list_three = ListItem(win_area, window=self.center_win, text="3: ")
        edit_area = WindowArea(y_loc=0, x_loc=5, lines=1, columns=10)
        field_three = EditField(edit_area, window=list_three)
        # Note that the 'window' parameter for field_three is 'list_three',
        # and that edit_area is a position relative to list_three.

        win_area.y_loc = 4
        list_four = ListItem(win_area, window=self.center_win, text="4: ")
        # Since WindowAreas are relative to their parent, edit_area can
        # be reused with no modifications
        field_four = EditField(edit_area, window=list_four, text="default")

        # As with lists, edit fields must be explicitly given focus. Note that
        # focus can be given by index, or by reference.
        self.center_win.activate_object(field_two)
示例#3
0
class NSNISIP(NameService):

    HEADER_TEXT = _("NIS Name Server Information")
    HELP_DATA = (SCI_HELP + "/%s/nis.txt", HEADER_TEXT)

    def __init__(self, main_win):
        super(NSNISIP, self).__init__(main_win)

    def _show(self):
        super(NSNISIP, self)._show()
        LOGGER.info("self.nameservice: %s" % self.nameservice)
        if self.nameservice.nameservice != 'NIS':
            raise SkipException
        if self.nameservice.nis_auto == NameServiceInfo.NIS_CHOICE_AUTO:
            raise SkipException
        if self.nameservice.dns:
            self.intro = \
                _("Enter the host name or IP address of the name server.  "
                  "A host name must have at least 2 characters and can be "
                  "alphanumeric and can contain hyphens.  IP "
                  "addresses must contain four sets of numbers separated "
                  "by periods (for example, 129.200.9.1).")
            self.title = _("Server's host name or IP address:")
        else:
            self.intro = \
                _("Enter the IP address of the name server.  IP "
                  "addresses must contain four sets of numbers separated "
                  "by periods (for example, 129.200.9.1).")
            self.title = _("Server's IP address:")
        y_loc = self._paint_opening()
        self.center_win.add_text(self.title, y_loc, INDENT)
        aligned_x_loc = textwidth(self.title) + INDENT + 1
        cols = self.win_size_x - aligned_x_loc
        area = WindowArea(1, cols, y_loc, aligned_x_loc)
        self.center_win.add_text(self.title, y_loc, INDENT)
        area = WindowArea(1, cols, y_loc, aligned_x_loc,
                        scrollable_columns=NameService.HOSTNAME_SCREEN_LEN + 1)
        # create edit field, validating for host name or IP address depending
        # on whether DNS was selected
        self.nis_ip = EditField(area, window=self.center_win,
                                text=self.nameservice.nis_ip,
                                error_win=self.main_win.error_line,
                                validate=(incremental_validate_host
                                          if self.nameservice.dns
                                          else incremental_validate_ip))
        self.main_win.do_update()
        self.center_win.activate_object(self.nis_ip)

    def validate(self):
        nis_ip = self.nis_ip.get_text()
        if self.nameservice.dns:
            validate_host_or_ip(nis_ip)
        else:
            validate_ip(nis_ip)
        if not nis_ip:
            raise UIMessage(_("The NIS server IP address cannot be blank."))

    def on_change_screen(self):
        self.nameservice.nis_ip = self.nis_ip.get_text()
示例#4
0
class NSLDAPProxyBindInfo(NameService):

    HEADER_TEXT = _("Specify LDAP Profile Proxy Bind Information")
    HELP_DATA = (SCI_HELP + "/%s/ldap_proxy.txt", HEADER_TEXT)

    def __init__(self, main_win, screen=None):
        super(NSLDAPProxyBindInfo, self).__init__(main_win)
        self.intro = \
                _("Specify the LDAP proxy bind distinguished name and the "
                  "LDAP proxy bind password.  The network administrator "
                  "can provide this information.")
        self.title = _("Proxy bind distinguished name:")
        self.title2 = _("Proxy bind password:"******"The LDAP proxy server distinguished name cannot be blank."))
        validate_ldap_proxy_bind_psw(self.ldap_pb_psw.get_text())

    def on_change_screen(self):
        self.nameservice.ldap_pb_dn = self.ldap_pb_dn.get_text()
        self.nameservice.ldap_pb_psw = self.ldap_pb_psw.get_text()
示例#5
0
 def _show(self):
     super(NSDNSServer, self)._show()
     # check dictionary of screens associated with name service selections
     if not self.nameservice.dns:
         raise SkipException
     y_loc = self._paint_opening()
     self.dns_server_list = []
     find_1st_nonblank = None
     find_last_nonblank = -1
     for i in range(NameServiceInfo.MAXDNSSERV):
         self.center_win.add_text(self.title, y_loc, INDENT)
         area = WindowArea(1, MAXIP, y_loc,
                           textwidth(self.title) + INDENT + 1)
         y_loc += 1
         if i < len(self.nameservice.dns_server) and \
                 self.nameservice.dns_server[i] is not None:
             text = self.nameservice.dns_server[i]
         else:
             text = ''
         # find first blank field or last non-blank field
         if text:
             find_last_nonblank = i
         elif find_1st_nonblank is None:
             find_1st_nonblank = i
         self.dns_server_list += [EditField(area, window=self.center_win,
                                        text=text,
                                        validate=incremental_validate_ip,
                                        error_win=self.main_win.error_line)]
     self.main_win.do_update()
     # position cursor on first blank or after last field
     if find_1st_nonblank is None:
         idx = min(find_last_nonblank + 1, NameServiceInfo.MAXDNSSERV - 1)
     else:
         idx = find_1st_nonblank
     self.center_win.activate_object(self.dns_server_list[idx])
    def _show(self):
        # The _show method will not only create the four desired EditFields,
        # but restore saved state as well.
        win_area = WindowArea(lines=1, columns=40, y_loc=1, x_loc=1)
        edit_area = WindowArea(lines=1, columns=20, y_loc=0, x_loc=10)
        for field_num in range(4):
            win_area.y_loc += 1
            field_label = "%s: " % field_num
            list_item = ListItem(win_area,
                                 window=self.center_win,
                                 text=field_label)
            # Grab the saved text for the field (assume it's been saved for
            # now; *how* to go about saving it is below)
            field_text = self.saved_text[field_num]
            # And then set that as the text for the field
            edit_field = EditField(edit_area,
                                   window=list_item,
                                   text=field_text)
            # Save a reference to the field so other methods can access
            # their data:
            self.fields[field_num] = edit_field

        # Since this series of fields also acts as a selectable list,
        # the current selection can be restored as well by changing which
        # object is active:
        self.center_win.activate_object(self.current_selection)
示例#7
0
 def _show(self):
     super(NSNISIP, self)._show()
     LOGGER.info("self.nameservice: %s" % self.nameservice)
     if self.nameservice.nameservice != 'NIS':
         raise SkipException
     if self.nameservice.nis_auto == NameServiceInfo.NIS_CHOICE_AUTO:
         raise SkipException
     if self.nameservice.dns:
         self.intro = \
             _("Enter the host name or IP address of the name server.  "
               "A host name must have at least 2 characters and can be "
               "alphanumeric and can contain hyphens.  IP "
               "addresses must contain four sets of numbers separated "
               "by periods (for example, 129.200.9.1).")
         self.title = _("Server's host name or IP address:")
     else:
         self.intro = \
             _("Enter the IP address of the name server.  IP "
               "addresses must contain four sets of numbers separated "
               "by periods (for example, 129.200.9.1).")
         self.title = _("Server's IP address:")
     y_loc = self._paint_opening()
     self.center_win.add_text(self.title, y_loc, INDENT)
     aligned_x_loc = textwidth(self.title) + INDENT + 1
     cols = self.win_size_x - aligned_x_loc
     area = WindowArea(1, cols, y_loc, aligned_x_loc)
     self.center_win.add_text(self.title, y_loc, INDENT)
     area = WindowArea(1,
                       cols,
                       y_loc,
                       aligned_x_loc,
                       scrollable_columns=NameService.HOSTNAME_SCREEN_LEN +
                       1)
     # create edit field, validating for host name or IP address depending
     # on whether DNS was selected
     self.nis_ip = EditField(
         area,
         window=self.center_win,
         text=self.nameservice.nis_ip,
         error_win=self.main_win.error_line,
         validate=(incremental_validate_host
                   if self.nameservice.dns else incremental_validate_ip))
     self.main_win.do_update()
     self.center_win.activate_object(self.nis_ip)
示例#8
0
 def _show(self):
     ''' show domain '''
     super(NSDomain, self)._show()
     if not _has_name_service():
         raise SkipException
     if not self.nameservice.nameservice:
         raise SkipException
     y_loc = self._paint_opening()
     cols = min(MAXDOMAINLEN + 1,
                self.win_size_x - textwidth(self.title) - INDENT - 1)
     self.center_win.add_text(self.title, y_loc, INDENT)
     area = WindowArea(1, cols, y_loc, textwidth(self.title) + INDENT + 1,
                       scrollable_columns=MAXDOMAINLEN + 1)
     self.domain = EditField(area, window=self.center_win,
                             text=self.nameservice.domain,
                             validate=incremental_validate_domain,
                             error_win=self.main_win.error_line)
     self.main_win.do_update()
     self.center_win.activate_object(self.domain)
示例#9
0
    def create_list_item(self, next_part, win, list_area):
        '''Add an entry for next_part (a Partition or Slice) to
        the DiskWindow

        '''
        list_item = ListItem(list_area, window=win, data_obj=next_part)
        list_item.key_dict.update(DiskWindow.ADD_KEYS)
        edit_field = EditField(self.edit_area, window=list_item,
                               numeric_pad=" ",
                               validate=decimal_valid,
                               on_exit=on_exit_edit,
                               error_win=self.error_win,
                               add_obj=False,
                               data_obj=next_part)
        edit_field.right_justify = True
        edit_field.validate_kwargs["disk_win"] = self
        edit_field.on_exit_kwargs["disk_win"] = self
        edit_field.key_dict.update(DiskWindow.ADD_KEYS)
        self.update_part(part_field=list_item)
        return list_item
示例#10
0
 def _show(self):
     super(NSLDAPProfile, self)._show()
     if self.nameservice.nameservice != 'LDAP':
         raise SkipException
     if self.nameservice.dns:
         self.intro = \
             _("Specify the name of the LDAP profile to be used to "
               "configure this system and the host name or IP address of "
               "the server that contains the profile.")
         self.title2 = _("Profile server host name or IP address:")
     else:
         self.intro = \
             _("Specify the name of the LDAP profile to be used to "
               "configure this system and the IP address of the "
               "server that contains the profile.")
         self.title2 = _("Profile server IP address:")
     self.intro += _("  Enter the LDAP search base.")
     y_loc = self._paint_opening()
     maxtitlelen = max(textwidth(self.title), textwidth(self.title2),
                       textwidth(self.title3))
     aligned_x_loc = maxtitlelen + INDENT + 1
     cols = self.win_size_x - aligned_x_loc
     self.center_win.add_text(self.title.rjust(maxtitlelen), y_loc, INDENT)
     area = WindowArea(1, cols, y_loc, aligned_x_loc)
     self.ldap_profile = EditField(area, window=self.center_win,
                                   text=self.nameservice.ldap_profile,
                                   error_win=self.main_win.error_line,
                                   validate=inc_validate_nowhite_nospecial)
     # in case of error, tell user what is being validated
     self.ldap_profile.validate_kwargs['etext'] = _('profile name')
     y_loc += 1
     area = WindowArea(1, cols, y_loc, aligned_x_loc,
                     scrollable_columns=NameService.HOSTNAME_SCREEN_LEN + 1)
     self.center_win.add_text(self.title2.rjust(maxtitlelen), y_loc, INDENT)
     # create edit field, validating for host name or IP address depending
     # on whether DNS was selected
     self.ldap_ip = EditField(area, window=self.center_win,
                              text=self.nameservice.ldap_ip,
                              error_win=self.main_win.error_line,
                              validate=(incremental_validate_host
                                        if self.nameservice.dns
                                        else incremental_validate_ip))
     # search base
     y_loc += 1
     self.center_win.add_text(self.title3.rjust(maxtitlelen), y_loc, INDENT)
     area = WindowArea(1, cols, y_loc, aligned_x_loc,
                       scrollable_columns=MAXDNLEN + 1)
     self.ldap_search_base = EditField(area, window=self.center_win,
                                     text=self.nameservice.ldap_search_base,
                                     error_win=self.main_win.error_line)
     self.main_win.do_update()
     self.center_win.activate_object(self.ldap_ip)
示例#11
0
 def _show(self):
     ''' show DNS search list '''
     super(NSDNSSearch, self)._show()
     # check dictionary of screens associated with name service selections
     if not self.nameservice.dns:
         raise SkipException
     y_loc = self._paint_opening()
     cols = min(MAXDOMAINLEN + 1,
                self.win_size_x - textwidth(self.title) - INDENT - 1)
     self.dns_search_list = []
     find_1st_nonblank = None
     find_last_nonblank = -1
     LOGGER.info(self.nameservice.dns_search)
     for i in range(MAXDNSSEARCH):
         self.center_win.add_text(text=self.title,
                                  start_y=y_loc,
                                  start_x=INDENT)
         area = WindowArea(1, cols, y_loc,
                           textwidth(self.title) + INDENT + 1)
         y_loc += 1
         if i < len(self.nameservice.dns_search) and \
                 self.nameservice.dns_search[i] is not None:
             text = self.nameservice.dns_search[i]
         else:
             text = ''
         # find first blank field or last non-blank field
         if text:
             find_last_nonblank = i
         elif find_1st_nonblank is None:
             find_1st_nonblank = i
         edf = EditField(area,
                         window=self.center_win,
                         text=text,
                         validate=incremental_validate_domain,
                         error_win=self.main_win.error_line)
         self.dns_search_list += [edf]
     self.main_win.do_update()
     # position cursor on first blank or after last field
     if find_1st_nonblank is None:
         idx = min(find_last_nonblank + 1, MAXDNSSEARCH - 1)
     else:
         idx = find_1st_nonblank
     self.center_win.activate_object(self.dns_search_list[idx])
 def make_field(self,
                label,
                description,
                y_loc,
                max_y,
                max_x,
                description_start,
                default_val,
                is_ip=True,
                selectable=True):
     '''Create a list item with 'label', add an editable field with
     'default_val', and add additional 'description' text following it
     
     '''
     self.list_area.y_loc = y_loc
     list_item = ListItem(self.list_area,
                          text=label,
                          data_obj=label,
                          window=self.center_win,
                          add_obj=selectable)
     if is_ip:
         validate = incremental_validate_ip
     else:
         validate = None
     edit_field = EditField(self.edit_area,
                            window=list_item,
                            text=default_val,
                            validate=validate,
                            error_win=self.main_win.error_line,
                            data_obj=label.rstrip(":"))
     self.center_win.add_paragraph(description,
                                   y_loc,
                                   description_start,
                                   max_y=(y_loc + max_y),
                                   max_x=max_x)
     return edit_field
class NetworkTypeScreen(BaseScreen):
    '''
    Let the user:
    - Choose the hostname
    - Select network type (Automatic, Manual, or None)
    '''
    
    HEADER_TEXT = _("Network")
    PARAGRAPH = _("Enter a name for this computer that identifies it on "
                  "the network. It must be at least two characters. It "
                  "can contain letters, numbers, and minus signs (-).")
    HOSTNAME_TEXT = _("Computer Name: ")
    NET_TYPE_TEXT = _("Select how the wired ethernet network "
                      "connection is configured.")
    AUTO_TEXT = _("Automatically")
    AUTO_DETAIL = _("Automatically configure the connection")
    MANUAL_TEXT = _("Manually")
    MANUAL_DETAIL = _("Enter the information on the following screen")
    NONE_TEXT = _("None")
    NONE_DETAIL = _("Do not configure the network at this time")
    NO_NICS_FOUND = _("No wired network interfaces found. Additional "
                      "device drivers may be needed.")
    ALL_NICS_FROMGZ = _("No configurable network interfaces found. They are "
                        "all controlled from global zone.")
    
    ITEM_OFFSET = 2
    ITEM_MAX_WIDTH = 17
    ITEM_DESC_OFFSET = ITEM_MAX_WIDTH + ITEM_OFFSET + 1
    HOSTNAME_SCREEN_LEN = 25
    
    HELP_DATA = (SCI_HELP + "/%s/network.txt", _("Network"))
    
    def __init__(self, main_win, configure_network=False):
        global LOGGER
        if LOGGER is None:
            LOGGER = logging.getLogger(INSTALL_LOGGER_NAME + ".sysconfig")
        
        super(NetworkTypeScreen, self).__init__(main_win)
        self.hostfield_offset = textwidth(NetworkTypeScreen.HOSTNAME_TEXT)
        self.menu_item_desc_max = (self.win_size_x -
                                   NetworkTypeScreen.ITEM_DESC_OFFSET)
        
        self.net_type_dict = {}
        self.sys_info = None
        self.automatic = None
        self.manual = None
        self.none_option = None
        self.hostname = None
        self.nic_info = NetworkInfo()

        # find_links() returns tuple containing
        #  * dictionary of configurable NICs
        #  * number of NICs mandated from global zone.
        #
        # Taking that information into account, initialize type
        # of network configuration:
        #  * FROMGZ - One or more link found, but all found links are
        #             controlled from global zone.
        #  * None - otherwise
        #
        # Set 'have_nic' flag to True if there is at least one configurable
        # link, otherwise set the flag to False.
        #
        self.ether_nics, self.fromgz_num = NetworkInfo.find_links()
        self.nic_info.type = NetworkInfo.NONE
        self.have_nic = True
        if len(self.ether_nics) == 0:
            self.have_nic = False
            if self.fromgz_num > 0:
                self.nic_info.type = NetworkInfo.FROMGZ

        self.configure_network = configure_network
    
    def _show(self):
        '''Create an EditField for entering hostname, and list items
        for each of the network types
        
        '''
        sc_profile = solaris_install.sysconfig.profile.from_engine()
        
        if sc_profile.system is None:
            sc_profile.system = SystemInfo()
        self.sys_info = sc_profile.system
        if sc_profile.nic is None:
            sc_profile.nic = self.nic_info
        
        y_loc = 1
        
        y_loc += self.center_win.add_paragraph(NetworkTypeScreen.PARAGRAPH,
                                               y_loc)
        
        y_loc += 1
        self.center_win.add_text(NetworkTypeScreen.HOSTNAME_TEXT, y_loc)
        
        max_cols = self.win_size_x - self.hostfield_offset
        cols = min(max_cols, NetworkTypeScreen.HOSTNAME_SCREEN_LEN)
        scrollable_columns = SystemInfo.MAX_HOSTNAME_LEN + 1
        hostname_area = WindowArea(1, cols, y_loc, self.hostfield_offset,
                                   scrollable_columns=scrollable_columns)
        self.hostname = EditField(hostname_area, 
                                  window=self.center_win,
                                  text=self.sys_info.hostname,
                                  validate=hostname_is_valid,
                                  error_win=self.main_win.error_line)
        self.hostname.item_key = None

        # Display network configuration part of screen only if applicable.
        if self.configure_network:
            y_loc += 3

            # If there are no configurable links, there is no point to let
            # user select type of network configuration.
            if not self.have_nic:
                # Inform user that no network interfaces were found
                # on the system.
                # If this is the case of non-global zone with all links
                # mandated from global zone, be more specific.
                if self.nic_info.type == NetworkInfo.FROMGZ:
                    self.center_win.add_paragraph(
                        NetworkTypeScreen.ALL_NICS_FROMGZ, y_loc, 1)
                else:
                    self.center_win.add_paragraph(
                        NetworkTypeScreen.NO_NICS_FOUND, y_loc, 1)

                self.main_win.do_update()
                activate = self.net_type_dict.get(self.nic_info.type,
                                                  self.hostname)
                self.center_win.activate_object(activate)
                return
        
        self.main_win.do_update()
        activate = self.net_type_dict.get(self.nic_info.type,
                                          self.hostname)
        self.center_win.activate_object(activate)
    
    def on_change_screen(self):
        '''Save hostname and selected network type on change screen'''
        if self.configure_network and self.have_nic:
            self.nic_info.type = self.center_win.get_active_object().item_key
        if self.nic_info.type is None:
            self.nic_info.type = NetworkInfo.NONE
        LOGGER.info("Configuring NIC as: %s", self.nic_info.type)
        self.sys_info.hostname = self.hostname.get_text()
    
    def validate(self):
        '''Ensure hostname is set and a network type is chosen (unless no
        NICs are present)
        
        '''
        hostname_text = self.hostname.get_text()
        if not hostname_text:
            raise UIMessage(_("A Hostname is required."))
        if len(hostname_text) < 2:
            raise UIMessage(_("A Hostname must be at least two characters."))
        if self.configure_network and self.have_nic and self.nic_info.type is None:
            item_key = self.center_win.get_active_object().item_key
            if item_key not in self.net_type_dict:
                raise UIMessage(_("Select the wired network configuration: "
                                   "Automatically, Manually, or None."))
    def _show(self):
        '''Create an EditField for entering hostname, and list items
        for each of the network types
        
        '''
        sc_profile = solaris_install.sysconfig.profile.from_engine()
        
        if sc_profile.system is None:
            sc_profile.system = SystemInfo()
        self.sys_info = sc_profile.system
        if sc_profile.nic is None:
            sc_profile.nic = self.nic_info
        
        y_loc = 1
        
        y_loc += self.center_win.add_paragraph(NetworkTypeScreen.PARAGRAPH,
                                               y_loc)
        
        y_loc += 1
        self.center_win.add_text(NetworkTypeScreen.HOSTNAME_TEXT, y_loc)
        
        max_cols = self.win_size_x - self.hostfield_offset
        cols = min(max_cols, NetworkTypeScreen.HOSTNAME_SCREEN_LEN)
        scrollable_columns = SystemInfo.MAX_HOSTNAME_LEN + 1
        hostname_area = WindowArea(1, cols, y_loc, self.hostfield_offset,
                                   scrollable_columns=scrollable_columns)
        self.hostname = EditField(hostname_area, 
                                  window=self.center_win,
                                  text=self.sys_info.hostname,
                                  validate=hostname_is_valid,
                                  error_win=self.main_win.error_line)
        self.hostname.item_key = None

        # Display network configuration part of screen only if applicable.
        if self.configure_network:
            y_loc += 3

            # If there are no configurable links, there is no point to let
            # user select type of network configuration.
            if not self.have_nic:
                # Inform user that no network interfaces were found
                # on the system.
                # If this is the case of non-global zone with all links
                # mandated from global zone, be more specific.
                if self.nic_info.type == NetworkInfo.FROMGZ:
                    self.center_win.add_paragraph(
                        NetworkTypeScreen.ALL_NICS_FROMGZ, y_loc, 1)
                else:
                    self.center_win.add_paragraph(
                        NetworkTypeScreen.NO_NICS_FOUND, y_loc, 1)

                self.main_win.do_update()
                activate = self.net_type_dict.get(self.nic_info.type,
                                                  self.hostname)
                self.center_win.activate_object(activate)
                return
        
        self.main_win.do_update()
        activate = self.net_type_dict.get(self.nic_info.type,
                                          self.hostname)
        self.center_win.activate_object(activate)
示例#15
0
class UserScreen(BaseScreen):
    '''Allow user to set:
    - root password
    - user real name
    - user login
    - user password
    
    '''

    HEADER_TEXT = _("Users")
    INTRO_SHOW_USER = _("Define a root password for the system and user "
                        "account for yourself.")
    INTRO_HIDE_USER = _("Define a root password for the system. Creation "
                        "of user account is disabled. See Help for "
                        "additional information.")
    ROOT_TEXT = _("System Root Password")
    ROOT_LABEL = _("Root password:"******"Confirm password:"******"Create a user account")
    NAME_LABEL = _("Your real name:")
    USERNAME_LABEL = _("Username:"******"User password:"******"/%s/users.txt", _("Users"))

    PASS_SCREEN_LEN = 16  # also used as column width for user input
    ITEM_OFFSET = 2

    def __init__(self, main_win, show_user_account=None):
        global LOGGER
        if LOGGER is None:
            LOGGER = logging.getLogger(INSTALL_LOGGER_NAME + ".sysconfig")

        super(UserScreen, self).__init__(main_win)
        self.max_text_len = (self.win_size_x - UserScreen.PASS_SCREEN_LEN -
                             UserScreen.ITEM_OFFSET) / 2
        max_field = max(textwidth(UserScreen.ROOT_LABEL),
                        textwidth(UserScreen.CONFIRM_LABEL),
                        textwidth(UserScreen.NAME_LABEL),
                        textwidth(UserScreen.USERNAME_LABEL),
                        textwidth(UserScreen.USER_PASS_LABEL))
        self.text_len = min(max_field + 1, self.max_text_len)
        self.list_area = WindowArea(1, self.text_len, 0,
                                    UserScreen.ITEM_OFFSET)
        scrollable_columns = UserInfo.MAX_PASS_LEN + 1
        self.edit_area = WindowArea(1,
                                    UserScreen.PASS_SCREEN_LEN + 1,
                                    0,
                                    self.text_len,
                                    scrollable_columns=scrollable_columns)
        self.username_edit_area = WindowArea(
            1,
            UserScreen.PASS_SCREEN_LEN + 1,
            0,
            self.text_len,
            scrollable_columns=UserInfo.MAX_USERNAME_LEN + 1)
        err_x_loc = 2 * self.max_text_len - self.text_len
        err_width = (self.text_len + UserScreen.PASS_SCREEN_LEN)
        self.error_area = WindowArea(1, err_width, 0, err_x_loc)
        self.root = None
        self.user = None
        self.root_pass_list = None
        self.root_pass_edit = None
        self.root_pass_err = None
        self.root_confirm_err = None
        self.root_confirm_list = None
        self.root_confirm_edit = None
        self.real_name_err = None
        self.real_name_list = None
        self.real_name_edit = None
        self.username_err = None
        self.username_list = None
        self.username_edit = None
        self.user_pass_err = None
        self.user_pass_list = None
        self.user_pass_edit = None
        self.user_confirm_err = None
        self.user_confirm_list = None
        self.user_confirm_edit = None

        #
        # If show_user_account is True, complete Users screen will be
        # displayed (root password edit fields as well as widgets related
        # to creating initial user account). Otherwise, widgets for initial
        # user account are hidden.
        #
        # If not initialized explicitly by caller (e.g. text installer),
        # show_user_account is set to True only if all conditions needed
        # for successful creation of user account are met.
        #
        # In particular, existence of parent of home ZFS dataset is checked,
        # since if parent of home ZFS dataset was missing, then
        # svc:/system/config-user smf service (responsible for configuring
        # root and user accounts) would fail to create user account. As
        # a result of that, the whole system would end up in maintenance mode.
        #
        self.show_user_account = show_user_account
        if self.show_user_account is None:
            self.show_user_account = self.home_zfs_parent_exists()

    def _show(self):
        '''Display the user name, real name, and password fields'''

        sc_profile = solaris_install.sysconfig.profile.from_engine()

        #
        # Create UserInfo instances holding information about root and user
        # accounts.
        #
        if sc_profile.users is None:
            #
            # Assume root is a normal account. It will be changed to a role
            # if the user account is created.
            #
            root = UserInfo(login_name="root", is_role=False)

            #
            # Initialize attributes of user account which can't be configured
            # on screens.
            #
            user = UserInfo(gid=10,
                            shell="/usr/bin/bash",
                            roles="root",
                            profiles="System Administrator",
                            sudoers="ALL=(ALL) ALL")
            sc_profile.users = UserInfoContainer(root, user)

        self.root = sc_profile.users.root
        self.user = sc_profile.users.user

        LOGGER.debug("Root: %s", self.root)
        LOGGER.debug("User: %s", self.user)

        root_set = (self.root.passlen != 0)
        user_set = (self.user.passlen != 0)

        y_loc = 1

        if self.show_user_account:
            intro_text = UserScreen.INTRO_SHOW_USER
        else:
            intro_text = UserScreen.INTRO_HIDE_USER

        self.center_win.add_paragraph(intro_text, y_loc, 1, y_loc + 2,
                                      self.win_size_x - 1)

        y_loc += 3
        self.center_win.add_text(UserScreen.ROOT_TEXT, y_loc, 1,
                                 self.win_size_x - 1)

        y_loc += 2
        self.error_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        self.root_pass_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.root_pass_list = ListItem(self.list_area,
                                       window=self.center_win,
                                       text=UserScreen.ROOT_LABEL)
        self.root_pass_edit = PasswordField(self.edit_area,
                                            window=self.root_pass_list,
                                            error_win=self.root_pass_err,
                                            fill=root_set)

        y_loc += 1
        self.error_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        self.root_confirm_err = ErrorWindow(self.error_area,
                                            window=self.center_win)
        self.root_confirm_list = ListItem(self.list_area,
                                          window=self.center_win,
                                          text=UserScreen.CONFIRM_LABEL)
        self.root_confirm_edit = PasswordField(self.edit_area,
                                               window=self.root_confirm_list,
                                               fill=root_set,
                                               on_exit=pass_match,
                                               error_win=self.root_confirm_err)
        rc_edit_kwargs = {"linked_win": self.root_pass_edit}
        self.root_confirm_edit.on_exit_kwargs = rc_edit_kwargs

        # User account disabled, do not display related widgets.
        if not self.show_user_account:
            self.main_win.do_update()
            self.center_win.activate_object(self.root_pass_list)
            return

        y_loc += 2
        self.center_win.add_text(UserScreen.USER_TEXT, y_loc, 1,
                                 self.win_size_x - 1)

        y_loc += 2
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.real_name_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.real_name_list = ListItem(self.list_area,
                                       window=self.center_win,
                                       text=UserScreen.NAME_LABEL)
        self.real_name_edit = EditField(self.edit_area,
                                        window=self.real_name_list,
                                        error_win=self.real_name_err,
                                        text=self.user.real_name)

        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.username_err = ErrorWindow(self.error_area,
                                        window=self.center_win)
        self.username_list = ListItem(self.list_area,
                                      window=self.center_win,
                                      text=UserScreen.USERNAME_LABEL)
        self.username_edit = EditField(self.username_edit_area,
                                       window=self.username_list,
                                       validate=username_valid,
                                       error_win=self.username_err,
                                       on_exit=login_valid,
                                       text=self.user.login_name)

        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.user_pass_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.user_pass_list = ListItem(self.list_area,
                                       window=self.center_win,
                                       text=UserScreen.USER_PASS_LABEL)
        self.user_pass_edit = PasswordField(self.edit_area,
                                            window=self.user_pass_list,
                                            error_win=self.user_pass_err,
                                            fill=user_set)

        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.user_confirm_err = ErrorWindow(self.error_area,
                                            window=self.center_win)
        self.user_confirm_list = ListItem(self.list_area,
                                          window=self.center_win,
                                          text=UserScreen.CONFIRM_LABEL)
        self.user_confirm_edit = PasswordField(self.edit_area,
                                               window=self.user_confirm_list,
                                               on_exit=pass_match,
                                               error_win=self.user_confirm_err,
                                               fill=user_set)
        uc_edit_kwargs = {"linked_win": self.user_pass_edit}
        self.user_confirm_edit.on_exit_kwargs = uc_edit_kwargs

        self.main_win.do_update()
        self.center_win.activate_object(self.root_pass_list)

    def on_change_screen(self):
        '''Store entered information into data object cache.'''

        if self.root_pass_edit.modified:
            if self.root_pass_edit.compare(self.root_confirm_edit):
                self.root.password = self.root_pass_edit.get_text()
            else:
                self.root.password = ""

        if self.root.password is None:
            self.root.password = ""

        self.root_pass_edit.clear_text()
        self.root_confirm_edit.clear_text()

        #
        # User account disabled, do not store related info into data object
        # cache.
        #
        if not self.show_user_account:
            return

        self.user.real_name = self.real_name_edit.get_text()
        self.user.login_name = self.username_edit.get_text()

        # If user account is to be created, configure root account as a role.
        self.root.is_role = bool(self.user.login_name)

        if self.user_pass_edit.modified:
            if self.user_pass_edit.compare(self.user_confirm_edit):
                self.user.password = self.user_pass_edit.get_text()
            else:
                self.user.password = ""

        if self.user.password is None:
            self.user.password = ""

        self.user_pass_edit.clear_text()
        self.user_confirm_edit.clear_text()

    def validate(self):
        '''Check for mismatched passwords, bad login names, etc.'''
        # Note: the Root and User password fields may be filled with
        # asterisks if the user previously invoked this screen.  Therefore,
        # if not empty we check their modified flags before validating the
        # contents.

        if self.root_pass_edit.modified:
            root_pass_set = bool(self.root_pass_edit.get_text())
        else:
            root_pass_set = (self.root.passlen != 0)

        # Root password is mandatory and, if modified, must be valid
        if not root_pass_set or self.root_pass_edit.modified:
            pass_valid(self.root_pass_edit,
                       msg_prefix=UserScreen.ROOT_LABEL + " ")
        # Root password confirmation must match original Root password
        if not self.root_pass_edit.compare(self.root_confirm_edit):
            raise UIMessage(_("Root passwords don't match"))

        # User account disabled, skip related validation steps.
        if not self.show_user_account:
            return

        if self.user_pass_edit.modified:
            user_pass_set = bool(self.user_pass_edit.get_text())
        else:
            user_pass_set = (self.user.passlen != 0)

        login_name = self.username_edit.get_text()
        LOGGER.debug("login_name=%s", login_name)
        real_name = self.real_name_edit.get_text()
        LOGGER.debug("real_name=%s", real_name)

        # Username (if specified) must be valid
        login_valid(self.username_edit)

        if login_name:
            # If Username was entered then:
            # - User password is mandatory and, if modified, must be valid
            # - User password confirmation must match original User password
            if not user_pass_set or self.user_pass_edit.modified:
                pass_valid(self.user_pass_edit,
                           msg_prefix=UserScreen.USER_PASS_LABEL + " ")
            if not self.user_pass_edit.compare(self.user_confirm_edit):
                raise UIMessage(_("User passwords don't match"))
        else:
            # If either Real name or User password are specified then
            # Username must also be specified
            if real_name or user_pass_set:
                raise UIMessage(
                    _("Enter username or clear all user "
                      "account fields"))

    def home_zfs_parent_exists(self):
        '''Return True if parent of to-be-created home ZFS dataset exists.
        Otherwise, return False.

        Home ZFS dataset is created in form of <root_pool>/export/home/<login>
        with mountpoint /export/home/<login> inherited from parent dataset.

        The check verifies that ZFS dataset with to-be-inherited /export/home
        mountpoint exists.
        '''

        # obtain mountpoints for all existing ZFS datasets
        cmd = [ZFS, "list", "-H", "-o", "mountpoint"]
        try:
            mountpoint_list = run(cmd, logger=LOGGER)
        except CalledProcessError:
            LOGGER.warn("Could not determine if parent of home ZFS dataset "
                        "exists.")
            return False

        if "/export/home" not in mountpoint_list.stdout.splitlines():
            LOGGER.debug("Parent of home ZFS dataset does not exist, creation "
                         "of user account disabled.")
            return False

        LOGGER.debug("Parent of home ZFS dataset exists, creation of user "
                     "account enabled.")
        return True
示例#16
0
文件: iscsi.py 项目: alhazred/caiman
    def _show(self):
        """ create the screen to collect user input
        """

        # look in the DOC for an Iscsi object
        eng = InstallEngine.get_instance()
        iscsi_obj = eng.doc.volatile.get_children(name=ISCSI_LABEL,
                                                  class_type=Iscsi)

        # If there's no iscsi object in the DOC, skip this screen
        if not iscsi_obj:
            raise SkipException
        else:
            self.iscsi_obj = iscsi_obj[0]
            LOGGER.debug("show Iscsi object:  %s" % str(self.iscsi_obj))

        y_loc = 1
        self.center_win.add_paragraph(IscsiScreen.INTRO, start_y=y_loc)

        # look to see if DHCP is providing information
        if self.check_dhcp():
            y_loc += 2
            self.center_win.add_paragraph(IscsiScreen.FOUND_DHCP_LABEL,
                                          start_y=y_loc)

        # Target IP
        y_loc += 2

        # Mark this field required
        self.center_win.window.addch(y_loc, 2, IscsiScreen.REQUIRED_MARK,
            self.center_win.color_theme.inactive)

        edit_start = textwidth(IscsiScreen.TARGET_IP_LABEL) + \
                     IscsiScreen.ITEM_OFFSET
        ip_area = WindowArea(y_loc=y_loc, x_loc=1, lines=1,
            columns=edit_start + IscsiScreen.MAX_IP_LEN + 1)

        self.target_ip_list = ListItem(ip_area,
                                       window=self.center_win,
                                       text=IscsiScreen.TARGET_IP_LABEL)
        self.target_ip_list.key_dict.update(self.add_keys)

        self.default_edit.x_loc = edit_start
        self.default_edit.columns = IscsiScreen.MAX_IP_LEN + 1
        self.target_ip_edit = EditField(self.default_edit,
                                        window=self.target_ip_list,
                                        validate=incremental_validate_ip,
                                        error_win=self.main_win.error_line)
        self.target_ip_edit.key_dict.update(self.add_keys)
        if self.target_ip is not None:
            self.target_ip_edit.set_text(self.target_ip)

        # Target Port
        edit_start = ip_area.x_loc + \
                     textwidth(IscsiScreen.TARGET_PORT_LABEL) + \
                     IscsiScreen.ITEM_OFFSET
        port_area = WindowArea(y_loc=y_loc,
            x_loc=self.half_win_width + IscsiScreen.DEAD_ZONE,
            lines=1, columns=edit_start + IscsiScreen.MAX_PORT_LEN + 1)

        self.target_port_list = ListItem(port_area,
                                         window=self.center_win,
                                         text=IscsiScreen.TARGET_PORT_LABEL)
        self.target_port_list.key_dict.update(self.add_keys)

        self.right_edit.x_loc = edit_start
        self.right_edit.columns = IscsiScreen.MAX_PORT_LEN + 1
        self.target_port_edit = EditField(self.right_edit,
                                          window=self.target_port_list,
                                          validate=incremental_validate_digits,
                                          error_win=self.main_win.error_line,
                                          text=Iscsi.ISCSI_DEFAULT_PORT)
        self.target_port_edit.key_dict.update(self.add_keys)
        if self.target_port is not None:
            self.target_port_edit.set_text(self.target_port)

        # Target LUN
        y_loc += 1

        edit_start = textwidth(IscsiScreen.TARGET_LUN_LABEL) + \
                     IscsiScreen.ITEM_OFFSET
        lun_area = WindowArea(y_loc=y_loc, x_loc=1, lines=1,
            columns=edit_start + IscsiScreen.MAX_LUN_LEN + 1)

        self.target_lun_list = ListItem(lun_area,
                                        window=self.center_win,
                                        text=IscsiScreen.TARGET_LUN_LABEL)
        self.target_lun_list.key_dict.update(self.add_keys)

        self.default_edit.x_loc = edit_start
        self.default_edit.columns = IscsiScreen.MAX_LUN_LEN + 1
        self.target_lun_edit = EditField(self.default_edit,
                                         window=self.target_lun_list,
                                         validate=incremental_validate_hex,
                                         error_win=self.main_win.error_line)
        self.target_lun_edit.key_dict.update(self.add_keys)
        if self.target_lun is not None:
            self.target_lun_edit.set_text(self.target_lun)

        # Target Name
        y_loc += 2
        name_area = WindowArea(y_loc=y_loc, x_loc=1, lines=1,
            columns=self.full_win_width)

        name_area.y_loc = y_loc
        target_name_list = ListItem(name_area, window=self.center_win,
                                    text=IscsiScreen.TARGET_NAME_LABEL)

        self.name_edit.x_loc = textwidth(IscsiScreen.TARGET_NAME_LABEL) + \
                                         IscsiScreen.ITEM_OFFSET
        self.name_edit.columns = self.full_win_width - \
                                 textwidth(IscsiScreen.TARGET_NAME_LABEL) - \
                                 IscsiScreen.ITEM_OFFSET
        self.target_name_edit = EditField(self.name_edit,
                                          window=target_name_list)
        if self.target_name is not None:
            self.target_name_edit.set_text(self.target_name)

        # Horizontal line
        y_loc += 1
        self.center_win.window.hline(y_loc, 3, curses.ACS_HLINE,
                                     self.full_win_width)

        # Initiator Name
        y_loc += 1

        if self.is_iscsiboot:
            # the system BIOS is configured for iSCSI boot.  This means the
            # user will be unable to change the initiator-name.  Display the
            # name, but don't allow it to be changed.
            text = "%s  %s" % \
                (IscsiScreen.INITIATOR_NAME_LABEL, self.initiator_name)
            self.center_win.add_text(text, start_y=y_loc, start_x=1)
            y_loc += 1
            self.center_win.add_text(IscsiScreen.ISCSI_BOOT_LABEL,
                                     start_y=y_loc, start_x=1)
        else:
            # display the edit field as normal
            name_area.y_loc = y_loc
            initiator_name_list = ListItem(name_area, window=self.center_win,
                text=IscsiScreen.INITIATOR_NAME_LABEL)

            self.name_edit.x_loc = \
                textwidth(IscsiScreen.INITIATOR_NAME_LABEL) + \
                IscsiScreen.ITEM_OFFSET
            self.name_edit.columns = self.full_win_width - \
                textwidth(IscsiScreen.INITIATOR_NAME_LABEL) - \
                IscsiScreen.ITEM_OFFSET
            self.initiator_name_edit = EditField(self.name_edit,
                                                 window=initiator_name_list,
                                                 text=self.initiator_name)

        y_loc += 2
        self.center_win.add_text(IscsiScreen.USE_CHAP_LABEL, y_loc, 1)

        # CHAP username
        y_loc += 1
        edit_start = textwidth(IscsiScreen.CHAP_NAME_LABEL) + \
                               IscsiScreen.ITEM_OFFSET
        chapname_area = WindowArea(y_loc=y_loc, x_loc=15, lines=1,
            columns=edit_start + IscsiScreen.CHAP_LEN)

        chap_name_list = ListItem(chapname_area, window=self.center_win,
                                  text=IscsiScreen.CHAP_NAME_LABEL)

        self.chap_edit.x_loc = edit_start
        self.chap_edit.columns = IscsiScreen.CHAP_LEN + 1
        self.chap_edit.scrollable_columns = IscsiScreen.MAX_NAME_LEN + 1
        self.chap_name_edit = EditField(self.chap_edit, window=chap_name_list)
        if self.chap_name is not None:
            self.chap_name_edit.set_text(self.chap_name)

        # CHAP password
        y_loc += 1
        edit_start = textwidth(IscsiScreen.CHAP_PASSWORD_LABEL) + \
                     IscsiScreen.ITEM_OFFSET
        chapname_area.y_loc = y_loc
        chap_password_list = ListItem(chapname_area, window=self.center_win,
                                      text=IscsiScreen.CHAP_PASSWORD_LABEL)

        self.chap_edit.x_loc = textwidth(IscsiScreen.CHAP_PASSWORD_LABEL) + \
                               IscsiScreen.ITEM_OFFSET
        self.chap_edit.scrollable_columns = None
        self.chap_password_edit = PasswordField(self.chap_edit,
                                                window=chap_password_list)
        if self.chap_password is not None:
            self.chap_password_edit.set_text(self.chap_password)

        # Legend
        y_loc += 2
        self.center_win.window.addch(y_loc, 1, IscsiScreen.REQUIRED_MARK,
            self.center_win.color_theme.inactive)
        self.center_win.add_text(IscsiScreen.REQUIRED_FIELD_LABEL, y_loc, 1)

        self.main_win.do_update()
        self.center_win.activate_object()
示例#17
0
class UserScreen(BaseScreen):
    '''Allow user to set:
    - root password
    - user real name
    - user login
    - user password
    
    '''
    
    HEADER_TEXT = _("Users")
    INTRO_SHOW_USER = _("Define a root password for the system and user "
                        "account for yourself.")
    INTRO_HIDE_USER = _("Define a root password for the system. Creation "
                        "of user account is disabled. See Help for "
                        "additional information.")
    ROOT_TEXT = _("System Root Password")
    ROOT_LABEL = _("Root password:"******"Confirm password:"******"Create a user account")
    NAME_LABEL = _("Your real name:")
    USERNAME_LABEL = _("Username:"******"User password:"******"/%s/users.txt", _("Users"))
    
    PASS_SCREEN_LEN = 16  # also used as column width for user input
    ITEM_OFFSET = 2
    
    def __init__(self, main_win, show_user_account=None):
        global LOGGER
        if LOGGER is None:
            LOGGER = logging.getLogger(INSTALL_LOGGER_NAME + ".sysconfig")
        
        super(UserScreen, self).__init__(main_win)
        self.max_text_len = (self.win_size_x - UserScreen.PASS_SCREEN_LEN -
                             UserScreen.ITEM_OFFSET) / 2
        max_field = max(textwidth(UserScreen.ROOT_LABEL),
                        textwidth(UserScreen.CONFIRM_LABEL),
                        textwidth(UserScreen.NAME_LABEL),
                        textwidth(UserScreen.USERNAME_LABEL),
                        textwidth(UserScreen.USER_PASS_LABEL))
        self.text_len = min(max_field + 1, self.max_text_len)
        self.list_area = WindowArea(1, self.text_len, 0,
                                    UserScreen.ITEM_OFFSET)
        scrollable_columns = UserInfo.MAX_PASS_LEN + 1
        self.edit_area = WindowArea(1, UserScreen.PASS_SCREEN_LEN + 1,
                                    0, self.text_len,
                                    scrollable_columns=scrollable_columns)
        self.username_edit_area = WindowArea(1, UserScreen.PASS_SCREEN_LEN + 1,
                              0, self.text_len,
                              scrollable_columns=UserInfo.MAX_USERNAME_LEN + 1)
        err_x_loc = 2 * self.max_text_len - self.text_len
        err_width = (self.text_len + UserScreen.PASS_SCREEN_LEN)
        self.error_area = WindowArea(1, err_width, 0, err_x_loc)
        self.root = None
        self.user = None
        self.root_pass_list = None
        self.root_pass_edit = None
        self.root_pass_err = None
        self.root_confirm_err = None
        self.root_confirm_list = None
        self.root_confirm_edit = None
        self.real_name_err = None
        self.real_name_list = None
        self.real_name_edit = None
        self.username_err = None
        self.username_list = None
        self.username_edit = None
        self.user_pass_err = None
        self.user_pass_list = None
        self.user_pass_edit = None
        self.user_confirm_err = None
        self.user_confirm_list = None
        self.user_confirm_edit = None

        #
        # If show_user_account is True, complete Users screen will be
        # displayed (root password edit fields as well as widgets related
        # to creating initial user account). Otherwise, widgets for initial
        # user account are hidden.
        #
        # If not initialized explicitly by caller (e.g. text installer),
        # show_user_account is set to True only if all conditions needed
        # for successful creation of user account are met.
        #
        # In particular, existence of parent of home ZFS dataset is checked,
        # since if parent of home ZFS dataset was missing, then
        # svc:/system/config-user smf service (responsible for configuring
        # root and user accounts) would fail to create user account. As
        # a result of that, the whole system would end up in maintenance mode.
        #
        self.show_user_account = show_user_account
        if self.show_user_account is None:
            self.show_user_account = self.home_zfs_parent_exists()

    def _show(self):
        '''Display the user name, real name, and password fields'''
        
        sc_profile = solaris_install.sysconfig.profile.from_engine()

        #
        # Create UserInfo instances holding information about root and user
        # accounts.
        #
        if sc_profile.users is None:
            #
            # Assume root is a normal account. It will be changed to a role
            # if the user account is created.
            #
            root = UserInfo(login_name="root", is_role=False)

            #
            # Initialize attributes of user account which can't be configured
            # on screens.
            #
            user = UserInfo(gid=10, shell="/usr/bin/bash", roles="root",
                            profiles="System Administrator",
                            sudoers="ALL=(ALL) ALL")
            sc_profile.users = UserInfoContainer(root, user)

        self.root = sc_profile.users.root
        self.user = sc_profile.users.user
        
        LOGGER.debug("Root: %s", self.root)
        LOGGER.debug("User: %s", self.user)
        
        root_set = (self.root.passlen != 0)
        user_set = (self.user.passlen != 0)
        
        y_loc = 1
        
        if self.show_user_account:
            intro_text = UserScreen.INTRO_SHOW_USER
        else:
            intro_text = UserScreen.INTRO_HIDE_USER

        self.center_win.add_paragraph(intro_text, y_loc, 1,
                                      y_loc + 2, self.win_size_x - 1)
        
        y_loc += 3
        self.center_win.add_text(UserScreen.ROOT_TEXT, y_loc, 1,
                                 self.win_size_x - 1)
        
        y_loc += 2
        self.error_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        self.root_pass_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.root_pass_list = ListItem(self.list_area, window=self.center_win,
                                       text=UserScreen.ROOT_LABEL)
        self.root_pass_edit = PasswordField(self.edit_area,
                                            window=self.root_pass_list,
                                            error_win=self.root_pass_err,
                                            fill=root_set)
        
        y_loc += 1
        self.error_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        self.root_confirm_err = ErrorWindow(self.error_area,
                                            window=self.center_win)
        self.root_confirm_list = ListItem(self.list_area,
                                          window=self.center_win,
                                          text=UserScreen.CONFIRM_LABEL)
        self.root_confirm_edit = PasswordField(self.edit_area,
                                               window=self.root_confirm_list,
                                               fill=root_set,
                                               on_exit=pass_match,
                                               error_win=self.root_confirm_err)
        rc_edit_kwargs = {"linked_win": self.root_pass_edit}
        self.root_confirm_edit.on_exit_kwargs = rc_edit_kwargs

        # User account disabled, do not display related widgets.
        if not self.show_user_account:
            self.main_win.do_update()
            self.center_win.activate_object(self.root_pass_list)
            return

        y_loc += 2
        self.center_win.add_text(UserScreen.USER_TEXT, y_loc, 1,
                                 self.win_size_x - 1)
        
        y_loc += 2
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.real_name_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.real_name_list = ListItem(self.list_area, window=self.center_win,
                                       text=UserScreen.NAME_LABEL)
        self.real_name_edit = EditField(self.edit_area,
                                        window=self.real_name_list,
                                        error_win=self.real_name_err,
                                        text=self.user.real_name)
        
        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.username_err = ErrorWindow(self.error_area,
                                        window=self.center_win)
        self.username_list = ListItem(self.list_area,
                                      window=self.center_win,
                                      text=UserScreen.USERNAME_LABEL)
        self.username_edit = EditField(self.username_edit_area,
                                       window=self.username_list,
                                       validate=username_valid,
                                       error_win=self.username_err,
                                       on_exit=login_valid,
                                       text=self.user.login_name)
        
        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.user_pass_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.user_pass_list = ListItem(self.list_area, window=self.center_win,
                                       text=UserScreen.USER_PASS_LABEL)
        self.user_pass_edit = PasswordField(self.edit_area,
                                            window=self.user_pass_list,
                                            error_win=self.user_pass_err,
                                            fill=user_set)
        
        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.user_confirm_err = ErrorWindow(self.error_area,
                                            window=self.center_win)
        self.user_confirm_list = ListItem(self.list_area,
                                          window=self.center_win,
                                          text=UserScreen.CONFIRM_LABEL)
        self.user_confirm_edit = PasswordField(self.edit_area,
                                               window=self.user_confirm_list,
                                               on_exit=pass_match,
                                               error_win=self.user_confirm_err,
                                               fill=user_set)
        uc_edit_kwargs = {"linked_win": self.user_pass_edit}
        self.user_confirm_edit.on_exit_kwargs = uc_edit_kwargs
        
        self.main_win.do_update()
        self.center_win.activate_object(self.root_pass_list)
    
    def on_change_screen(self):
        '''Store entered information into data object cache.'''

        if self.root_pass_edit.modified:
            if self.root_pass_edit.compare(self.root_confirm_edit):
                self.root.password = self.root_pass_edit.get_text()
            else:
                self.root.password = ""
        
        if self.root.password is None:
            self.root.password = ""
        
        self.root_pass_edit.clear_text()
        self.root_confirm_edit.clear_text()

        #
        # User account disabled, do not store related info into data object
        # cache.
        #
        if not self.show_user_account:
            return

        self.user.real_name = self.real_name_edit.get_text()
        self.user.login_name = self.username_edit.get_text()

        # If user account is to be created, configure root account as a role.
        self.root.is_role = bool(self.user.login_name)
        
        if self.user_pass_edit.modified:
            if self.user_pass_edit.compare(self.user_confirm_edit):
                self.user.password = self.user_pass_edit.get_text()
            else:
                self.user.password = ""
        
        if self.user.password is None:
            self.user.password = ""
        
        self.user_pass_edit.clear_text()
        self.user_confirm_edit.clear_text()
    
    def validate(self):
        '''Check for mismatched passwords, bad login names, etc.'''
        # Note: the Root and User password fields may be filled with
        # asterisks if the user previously invoked this screen.  Therefore,
        # if not empty we check their modified flags before validating the
        # contents.

        if self.root_pass_edit.modified:
            root_pass_set = bool(self.root_pass_edit.get_text())
        else:
            root_pass_set = (self.root.passlen != 0)      

        # Root password is mandatory and, if modified, must be valid
        if not root_pass_set or self.root_pass_edit.modified:
            pass_valid(self.root_pass_edit,
                msg_prefix=UserScreen.ROOT_LABEL + " ")
        # Root password confirmation must match original Root password
        if not self.root_pass_edit.compare(self.root_confirm_edit):
            raise UIMessage(_("Root passwords don't match"))

        # User account disabled, skip related validation steps.
        if not self.show_user_account:
            return

        if self.user_pass_edit.modified:
            user_pass_set = bool(self.user_pass_edit.get_text())
        else:
            user_pass_set = (self.user.passlen != 0)
        
        login_name = self.username_edit.get_text()
        LOGGER.debug("login_name=%s", login_name)
        real_name = self.real_name_edit.get_text()
        LOGGER.debug("real_name=%s", real_name)
        
        # Username (if specified) must be valid
        login_valid(self.username_edit)

        if login_name:
            # If Username was entered then:
            # - User password is mandatory and, if modified, must be valid
            # - User password confirmation must match original User password
            if not user_pass_set or self.user_pass_edit.modified:
                pass_valid(self.user_pass_edit,
                    msg_prefix=UserScreen.USER_PASS_LABEL + " ")
            if not self.user_pass_edit.compare(self.user_confirm_edit):
                raise UIMessage(_("User passwords don't match"))
        else:
            # If either Real name or User password are specified then
            # Username must also be specified
            if real_name or user_pass_set:
                raise UIMessage(_("Enter username or clear all user "
                                  "account fields"))

    def home_zfs_parent_exists(self):
        '''Return True if parent of to-be-created home ZFS dataset exists.
        Otherwise, return False.

        Home ZFS dataset is created in form of <root_pool>/export/home/<login>
        with mountpoint /export/home/<login> inherited from parent dataset.

        The check verifies that ZFS dataset with to-be-inherited /export/home
        mountpoint exists.
        '''

        # obtain mountpoints for all existing ZFS datasets
        cmd = [ZFS, "list", "-H", "-o", "mountpoint"]
        try:
            mountpoint_list = run(cmd, logger=LOGGER)
        except CalledProcessError:
            LOGGER.warn("Could not determine if parent of home ZFS dataset "
                        "exists.")
            return False

        if "/export/home" not in mountpoint_list.stdout.splitlines():
            LOGGER.debug("Parent of home ZFS dataset does not exist, creation "
                         "of user account disabled.")
            return False

        LOGGER.debug("Parent of home ZFS dataset exists, creation of user "
                     "account enabled.")
        return True
示例#18
0
class NetworkTypeScreen(BaseScreen):
    '''
    Let the user:
    - Choose the hostname
    - Select network type (Automatic, Manual, or None)
    '''

    HEADER_TEXT = _("Network")
    PARAGRAPH = _("Enter a name for this computer that identifies it on "
                  "the network. It must be at least two characters. It "
                  "can contain letters, numbers, and minus signs (-).")
    HOSTNAME_TEXT = _("Computer Name: ")
    NET_TYPE_TEXT = _("Select how the wired ethernet network "
                      "connection is configured.")
    AUTO_TEXT = _("Automatically")
    AUTO_DETAIL = _("Automatically configure the connection")
    MANUAL_TEXT = _("Manually")
    MANUAL_DETAIL = _("Enter the information on the following screen")
    NONE_TEXT = _("None")
    NONE_DETAIL = _("Do not configure the network at this time")
    NO_NICS_FOUND = _("No wired network interfaces found. Additional "
                      "device drivers may be needed.")
    ALL_NICS_FROMGZ = _("No configurable network interfaces found. They are "
                        "all controlled from global zone.")

    ITEM_OFFSET = 2
    ITEM_MAX_WIDTH = 17
    ITEM_DESC_OFFSET = ITEM_MAX_WIDTH + ITEM_OFFSET + 1
    HOSTNAME_SCREEN_LEN = 25

    HELP_DATA = (SCI_HELP + "/%s/network.txt", _("Network"))

    def __init__(self, main_win, configure_network=False):
        global LOGGER
        if LOGGER is None:
            LOGGER = logging.getLogger(INSTALL_LOGGER_NAME + ".sysconfig")

        super(NetworkTypeScreen, self).__init__(main_win)
        self.hostfield_offset = textwidth(NetworkTypeScreen.HOSTNAME_TEXT)
        self.menu_item_desc_max = (self.win_size_x -
                                   NetworkTypeScreen.ITEM_DESC_OFFSET)

        self.net_type_dict = {}
        self.sys_info = None
        self.automatic = None
        self.manual = None
        self.none_option = None
        self.hostname = None
        self.nic_info = NetworkInfo()

        # find_links() returns tuple containing
        #  * dictionary of configurable NICs
        #  * number of NICs mandated from global zone.
        #
        # Taking that information into account, initialize type
        # of network configuration:
        #  * FROMGZ - One or more link found, but all found links are
        #             controlled from global zone.
        #  * None - otherwise
        #
        # Set 'have_nic' flag to True if there is at least one configurable
        # link, otherwise set the flag to False.
        #
        self.ether_nics, self.fromgz_num = NetworkInfo.find_links()
        self.nic_info.type = NetworkInfo.NONE
        self.have_nic = True
        if len(self.ether_nics) == 0:
            self.have_nic = False
            if self.fromgz_num > 0:
                self.nic_info.type = NetworkInfo.FROMGZ

        self.configure_network = configure_network

    def _show(self):
        '''Create an EditField for entering hostname, and list items
        for each of the network types
        
        '''
        sc_profile = solaris_install.sysconfig.profile.from_engine()

        if sc_profile.system is None:
            sc_profile.system = SystemInfo()
        self.sys_info = sc_profile.system
        if sc_profile.nic is None:
            sc_profile.nic = self.nic_info

        y_loc = 1

        y_loc += self.center_win.add_paragraph(NetworkTypeScreen.PARAGRAPH,
                                               y_loc)

        y_loc += 1
        self.center_win.add_text(NetworkTypeScreen.HOSTNAME_TEXT, y_loc)

        max_cols = self.win_size_x - self.hostfield_offset
        cols = min(max_cols, NetworkTypeScreen.HOSTNAME_SCREEN_LEN)
        scrollable_columns = SystemInfo.MAX_HOSTNAME_LEN + 1
        hostname_area = WindowArea(1,
                                   cols,
                                   y_loc,
                                   self.hostfield_offset,
                                   scrollable_columns=scrollable_columns)
        self.hostname = EditField(hostname_area,
                                  window=self.center_win,
                                  text=self.sys_info.hostname,
                                  validate=hostname_is_valid,
                                  error_win=self.main_win.error_line)
        self.hostname.item_key = None

        # Display network configuration part of screen only if applicable.
        if self.configure_network:
            y_loc += 3

            # If there are no configurable links, there is no point to let
            # user select type of network configuration.
            if not self.have_nic:
                # Inform user that no network interfaces were found
                # on the system.
                # If this is the case of non-global zone with all links
                # mandated from global zone, be more specific.
                if self.nic_info.type == NetworkInfo.FROMGZ:
                    self.center_win.add_paragraph(
                        NetworkTypeScreen.ALL_NICS_FROMGZ, y_loc, 1)
                else:
                    self.center_win.add_paragraph(
                        NetworkTypeScreen.NO_NICS_FOUND, y_loc, 1)

                self.main_win.do_update()
                activate = self.net_type_dict.get(self.nic_info.type,
                                                  self.hostname)
                self.center_win.activate_object(activate)
                return

        self.main_win.do_update()
        activate = self.net_type_dict.get(self.nic_info.type, self.hostname)
        self.center_win.activate_object(activate)

    def on_change_screen(self):
        '''Save hostname and selected network type on change screen'''
        if self.configure_network and self.have_nic:
            self.nic_info.type = self.center_win.get_active_object().item_key
        if self.nic_info.type is None:
            self.nic_info.type = NetworkInfo.NONE
        LOGGER.info("Configuring NIC as: %s", self.nic_info.type)
        self.sys_info.hostname = self.hostname.get_text()

    def validate(self):
        '''Ensure hostname is set and a network type is chosen (unless no
        NICs are present)
        
        '''
        hostname_text = self.hostname.get_text()
        if not hostname_text:
            raise UIMessage(_("A Hostname is required."))
        if len(hostname_text) < 2:
            raise UIMessage(_("A Hostname must be at least two characters."))
        if self.configure_network and self.have_nic and self.nic_info.type is None:
            item_key = self.center_win.get_active_object().item_key
            if item_key not in self.net_type_dict:
                raise UIMessage(
                    _("Select the wired network configuration: "
                      "Automatically, Manually, or None."))
class DateTimeScreen(BaseScreen):
    '''
    Allow user to select year, month, day, hour, and minute to be
    used to set system clock.
    '''
    
    HEADER_TEXT = _("Date and Time")
    
    YEAR_TEXT = _("Year:")
    MONTH_TEXT = _("Month:")
    DAY_TEXT = _("Day:")
    HOUR_TEXT = _("Hour:")
    MINUTE_TEXT = _("Minute:")
    YEAR_FORMAT = _("(YYYY)")
    
    PARAGRAPH = _("Edit the date and time as necessary.\n"
                  "The time is in 24 hour format.")
    
    HELP_DATA = (SCI_HELP + "/%s/date_time.txt",
                 _("Date and Time"))
    
    YEAR_DIGITS = 4
    TWO_DIGITS = 2
    YEAR_LEN = len(YEAR_TEXT)
    MONTH_LEN = len(MONTH_TEXT)
    DAY_LEN = len(DAY_TEXT)
    HOUR_LEN = len(HOUR_TEXT)
    MINUTE_LEN = len(MINUTE_TEXT)
    MAX_LEN = max(YEAR_LEN, MONTH_LEN, DAY_LEN, HOUR_LEN, MINUTE_LEN) + 1
    
    ITEM_OFFSET = 2
    
    def __init__(self, main_win):
        global LOGGER
        if LOGGER is None:
            LOGGER = logging.getLogger(INSTALL_LOGGER_NAME + ".sysconfig")
        
        super(DateTimeScreen, self).__init__(main_win)
        
        year_edit_width = DateTimeScreen.YEAR_DIGITS + 1
        list_width = DateTimeScreen.MAX_LEN + year_edit_width
        self.list_area = WindowArea(1, list_width, 0,
                                    DateTimeScreen.ITEM_OFFSET)
        self.year_edit_area = WindowArea(1, year_edit_width, 0,
                                         DateTimeScreen.MAX_LEN + 1)
        other_edit_width = DateTimeScreen.TWO_DIGITS + 1
        other_edit_offset = (DateTimeScreen.MAX_LEN +
                             (DateTimeScreen.YEAR_DIGITS -
                              DateTimeScreen.TWO_DIGITS) + 1)
        self.edit_area = WindowArea(1, other_edit_width, 0, other_edit_offset)
        self.info_offset = (DateTimeScreen.ITEM_OFFSET +
                            self.list_area.columns + 1)
        self.info_width = len(DateTimeScreen.YEAR_FORMAT)
        err_offset = self.info_offset + self.info_width + 2
        err_width = self.win_size_x - err_offset
        self.err_area = WindowArea(1, err_width, 0, err_offset)
        
        self.year_edit = None
        self.year_err = None
        self.year_list = None
        self.month_edit = None
        self.month_err = None
        self.month_list = None
        self.day_edit = None
        self.day_err = None
        self.day_list = None
        self.hour_edit = None
        self.hour_err = None
        self.hour_list = None
        self.minute_edit = None
        self.minute_err = None
        self.minute_list = None
        self.year_is_valid = True
        self.month_is_valid = True
        self.date_range_loc = None
        self.saved_year = None
        self.saved_month = None
        self.saved_day = None
        self.saved_hour = None
        self.saved_minute = None
        self.saved_days_in_month = None
    
    def _show(self):
        '''
        Prepare the editable fields for day, month, year, hour and minute
        
        '''
        y_loc = 1
        
        y_loc += self.center_win.add_paragraph(DateTimeScreen.PARAGRAPH, y_loc)
        
        sc_profile = solaris_install.sysconfig.profile.from_engine()
        
        os.environ["TZ"] = sc_profile.system.tz_timezone
        now = datetime.datetime.now()
        LOGGER.log(LOG_LEVEL_INPUT, "Current date (year-month-day hour:minute)"
                   ": %s-%s-%s %s:%s", now.year, now.month, now.day, now.hour,
                   now.minute)
        
        # Only update saved values if this is first time on screen or
        # if we have saved offset in profile (F2, return to screen)
        #
        update_vals = False
        if self.saved_year is None:
            update_vals = True
            showtime = now
        elif sc_profile.system.time_offset != 0:
            showtime = now + sc_profile.system.time_offset
            update_vals = True
            sc_profile.system.time_offset = 0
        
        if update_vals:
            self.saved_year = str(showtime.year)
            self.saved_month = str(showtime.month)
            self.saved_day = str(showtime.day)
            self.saved_hour = str(showtime.hour)
            self.saved_minute = str(showtime.minute)
            self.saved_days_in_month = calendar.monthrange(showtime.year,
                                                           showtime.month)[1]
            
        LOGGER.debug("starting year month day hour minute:_%s_%s_%s_%s_%s",
                      self.saved_year, self.saved_month, self.saved_day,
                      self.saved_hour, self.saved_minute)
        LOGGER.debug("starting days_in_month: %s", self.saved_days_in_month)
        
        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        
        self.year_err = ErrorWindow(self.err_area, window=self.center_win,
                                    centered=False)
        self.year_list = ListItem(self.list_area,
                                  window=self.center_win,
                                  text=DateTimeScreen.YEAR_TEXT)
        self.year_edit = EditField(self.year_edit_area, window=self.year_list,
                                   validate=year_valid,
                                   error_win=self.year_err,
                                   on_exit=year_on_exit,
                                   text=self.saved_year)
        self.year_edit.clear_on_enter = True
        
        self.center_win.add_text(DateTimeScreen.YEAR_FORMAT, y_loc,
                                 self.info_offset)
        
        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        
        self.month_err = ErrorWindow(self.err_area, window=self.center_win,
                                    centered=False)
        self.month_list = ListItem(self.list_area, window=self.center_win,
                                   text=DateTimeScreen.MONTH_TEXT)
        self.month_edit = EditField(self.edit_area, window=self.month_list,
                                    validate=month_valid,
                                    error_win=self.month_err,
                                    on_exit=month_on_exit,
                                    text=self.saved_month,
                                    numeric_pad="0")
        self.month_edit.clear_on_enter = True
        self.month_edit.right_justify = True
        self.center_win.add_text("(1-12)", y_loc, self.info_offset)
        
        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        
        self.day_err = ErrorWindow(self.err_area, window=self.center_win,
                                   centered=False)
        self.day_list = ListItem(self.list_area,
                                 window=self.center_win,
                                 text=DateTimeScreen.DAY_TEXT)
        self.day_edit = EditField(self.edit_area, window=self.day_list,
                                  validate=day_valid,
                                  error_win=self.day_err,
                                  on_exit=day_on_exit,
                                  text=self.saved_day,
                                  numeric_pad="0")
        self.day_edit.clear_on_enter = True
        self.day_edit.right_justify = True
        
        self.month_edit.validate_kwargs["date_time"] = self
        self.month_edit.validate_kwargs["year_edit"] = self.year_edit
        self.month_edit.validate_kwargs["day_edit"] = self.day_edit
        
        self.year_edit.validate_kwargs["date_time"] = self
        self.year_edit.validate_kwargs["month_edit"] = self.month_edit
        self.year_edit.validate_kwargs["day_edit"] = self.day_edit
        
        self.day_edit.validate_kwargs["date_time"] = self
        self.day_edit.validate_kwargs["year_edit"] = self.year_edit
        self.day_edit.validate_kwargs["month_edit"] = self.month_edit
        self.date_range_loc = (y_loc, self.info_offset)
        self.update_day_range(self.saved_days_in_month)
        
        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        
        self.hour_err = ErrorWindow(self.err_area, window=self.center_win,
                                    centered=False)
        self.hour_list = ListItem(self.list_area, window=self.center_win,
                                  text=DateTimeScreen.HOUR_TEXT)
        self.hour_edit = EditField(self.edit_area, window=self.hour_list,
                                   validate=hour_valid,
                                   error_win=self.hour_err,
                                   on_exit=hour_on_exit,
                                   text=self.saved_hour,
                                   numeric_pad="0")
        self.hour_edit.clear_on_enter = True
        self.hour_edit.right_justify = True
        self.center_win.add_text("(0-23)", y_loc, self.info_offset)
        
        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        
        self.minute_err = ErrorWindow(self.err_area, window=self.center_win,
                                      centered=False)
        self.minute_list = ListItem(self.list_area, window=self.center_win,
                                    text=DateTimeScreen.MINUTE_TEXT)
        self.minute_edit = EditField(self.edit_area,
                                     window=self.minute_list,
                                     validate=minute_valid,
                                     error_win=self.minute_err,
                                     on_exit=minute_on_exit,
                                     text=self.saved_minute,
                                     numeric_pad="0")
        self.minute_edit.clear_on_enter = True
        self.minute_edit.right_justify = True
        self.center_win.add_text("(0-59)", y_loc, self.info_offset)
        
        self.main_win.do_update()
        self.center_win.activate_object(self.year_list)
    
    def validate(self):
        '''Verify each of the edit fields'''
        year_value = self.year_edit.get_text()
        month_value = self.month_edit.get_text()
        day_value = self.day_edit.get_text()
        hour_value = self.hour_edit.get_text()
        minute_value = self.minute_edit.get_text()
        LOGGER.debug("year_value=%s", year_value)
        LOGGER.debug("month_value=%s", month_value)
        LOGGER.debug("day_value=%s", day_value)
        LOGGER.debug("hour_value=%s", hour_value)
        LOGGER.debug("minute_value=%s", minute_value)
        had_err = False
        if not self.year_edit.run_on_exit(): 
            had_err = True
        if not self.month_edit.run_on_exit(): 
            had_err = True
        if not self.day_edit.run_on_exit(): 
            had_err = True
        if not self.hour_edit.run_on_exit(): 
            had_err = True
        if not self.minute_edit.run_on_exit(): 
            had_err = True
        if had_err:
            raise UIMessage(_("Invalid date/time. See errors above."))

    def update_day_range(self, maxday=31):
        '''
        Update the day range displayed. The max number of days can vary
        depending on the month, so calling functions can update appropriately.
        
        '''
        self.center_win.add_text("(1-%d)" % maxday,
                                 self.date_range_loc[0],
                                 self.date_range_loc[1],
                                 self.win_size_x - 3)
        self.saved_days_in_month = maxday

    def on_change_screen(self):
        '''Save current user input for return to screen'''
        self.saved_year = self.year_edit.get_text()
        self.saved_month = self.month_edit.get_text()
        self.saved_day = self.day_edit.get_text()
        self.saved_hour = self.hour_edit.get_text()
        self.saved_minute = self.minute_edit.get_text()

    def on_continue(self):
        '''Save time offset to profile'''
        saved_time = datetime.datetime(int(self.year_edit.get_text()),
                                       int(self.month_edit.get_text()),
                                       int(self.day_edit.get_text()),
                                       int(self.hour_edit.get_text()),
                                       int(self.minute_edit.get_text()))
        userdelta = saved_time - datetime.datetime.now()
        LOGGER.debug("delta time=%s", userdelta)
        sc_profile = solaris_install.sysconfig.profile.from_engine()
        sc_profile.system.time_offset = userdelta
        install_datetime = datetime.datetime.now() + userdelta
        LOGGER.debug("date command would be: /usr/bin/date %s",
                      install_datetime.strftime("%m%d%H%M%y"))
示例#20
0
class DateTimeScreen(BaseScreen):
    '''
    Allow user to select year, month, day, hour, and minute to be
    used to set system clock.
    '''

    HEADER_TEXT = _("Date and Time")

    YEAR_TEXT = _("Year:")
    MONTH_TEXT = _("Month:")
    DAY_TEXT = _("Day:")
    HOUR_TEXT = _("Hour:")
    MINUTE_TEXT = _("Minute:")
    YEAR_FORMAT = _("(YYYY)")

    PARAGRAPH = _("Edit the date and time as necessary.\n"
                  "The time is in 24 hour format.")

    HELP_DATA = (SCI_HELP + "/%s/date_time.txt", _("Date and Time"))

    YEAR_DIGITS = 4
    TWO_DIGITS = 2
    YEAR_LEN = len(YEAR_TEXT)
    MONTH_LEN = len(MONTH_TEXT)
    DAY_LEN = len(DAY_TEXT)
    HOUR_LEN = len(HOUR_TEXT)
    MINUTE_LEN = len(MINUTE_TEXT)
    MAX_LEN = max(YEAR_LEN, MONTH_LEN, DAY_LEN, HOUR_LEN, MINUTE_LEN) + 1

    ITEM_OFFSET = 2

    def __init__(self, main_win):
        global LOGGER
        if LOGGER is None:
            LOGGER = logging.getLogger(INSTALL_LOGGER_NAME + ".sysconfig")

        super(DateTimeScreen, self).__init__(main_win)

        year_edit_width = DateTimeScreen.YEAR_DIGITS + 1
        list_width = DateTimeScreen.MAX_LEN + year_edit_width
        self.list_area = WindowArea(1, list_width, 0,
                                    DateTimeScreen.ITEM_OFFSET)
        self.year_edit_area = WindowArea(1, year_edit_width, 0,
                                         DateTimeScreen.MAX_LEN + 1)
        other_edit_width = DateTimeScreen.TWO_DIGITS + 1
        other_edit_offset = (
            DateTimeScreen.MAX_LEN +
            (DateTimeScreen.YEAR_DIGITS - DateTimeScreen.TWO_DIGITS) + 1)
        self.edit_area = WindowArea(1, other_edit_width, 0, other_edit_offset)
        self.info_offset = (DateTimeScreen.ITEM_OFFSET +
                            self.list_area.columns + 1)
        self.info_width = len(DateTimeScreen.YEAR_FORMAT)
        err_offset = self.info_offset + self.info_width + 2
        err_width = self.win_size_x - err_offset
        self.err_area = WindowArea(1, err_width, 0, err_offset)

        self.year_edit = None
        self.year_err = None
        self.year_list = None
        self.month_edit = None
        self.month_err = None
        self.month_list = None
        self.day_edit = None
        self.day_err = None
        self.day_list = None
        self.hour_edit = None
        self.hour_err = None
        self.hour_list = None
        self.minute_edit = None
        self.minute_err = None
        self.minute_list = None
        self.year_is_valid = True
        self.month_is_valid = True
        self.date_range_loc = None
        self.saved_year = None
        self.saved_month = None
        self.saved_day = None
        self.saved_hour = None
        self.saved_minute = None
        self.saved_days_in_month = None

    def _show(self):
        '''
        Prepare the editable fields for day, month, year, hour and minute
        
        '''
        y_loc = 1

        y_loc += self.center_win.add_paragraph(DateTimeScreen.PARAGRAPH, y_loc)

        sc_profile = solaris_install.sysconfig.profile.from_engine()

        os.environ["TZ"] = sc_profile.system.tz_timezone
        now = datetime.datetime.now()
        LOGGER.log(
            LOG_LEVEL_INPUT, "Current date (year-month-day hour:minute)"
            ": %s-%s-%s %s:%s", now.year, now.month, now.day, now.hour,
            now.minute)

        # Only update saved values if this is first time on screen or
        # if we have saved offset in profile (F2, return to screen)
        #
        update_vals = False
        if self.saved_year is None:
            update_vals = True
            showtime = now
        elif sc_profile.system.time_offset != 0:
            showtime = now + sc_profile.system.time_offset
            update_vals = True
            sc_profile.system.time_offset = 0

        if update_vals:
            self.saved_year = str(showtime.year)
            self.saved_month = str(showtime.month)
            self.saved_day = str(showtime.day)
            self.saved_hour = str(showtime.hour)
            self.saved_minute = str(showtime.minute)
            self.saved_days_in_month = calendar.monthrange(
                showtime.year, showtime.month)[1]

        LOGGER.debug("starting year month day hour minute:_%s_%s_%s_%s_%s",
                     self.saved_year, self.saved_month, self.saved_day,
                     self.saved_hour, self.saved_minute)
        LOGGER.debug("starting days_in_month: %s", self.saved_days_in_month)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.year_err = ErrorWindow(self.err_area,
                                    window=self.center_win,
                                    centered=False)
        self.year_list = ListItem(self.list_area,
                                  window=self.center_win,
                                  text=DateTimeScreen.YEAR_TEXT)
        self.year_edit = EditField(self.year_edit_area,
                                   window=self.year_list,
                                   validate=year_valid,
                                   error_win=self.year_err,
                                   on_exit=year_on_exit,
                                   text=self.saved_year)
        self.year_edit.clear_on_enter = True

        self.center_win.add_text(DateTimeScreen.YEAR_FORMAT, y_loc,
                                 self.info_offset)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.month_err = ErrorWindow(self.err_area,
                                     window=self.center_win,
                                     centered=False)
        self.month_list = ListItem(self.list_area,
                                   window=self.center_win,
                                   text=DateTimeScreen.MONTH_TEXT)
        self.month_edit = EditField(self.edit_area,
                                    window=self.month_list,
                                    validate=month_valid,
                                    error_win=self.month_err,
                                    on_exit=month_on_exit,
                                    text=self.saved_month,
                                    numeric_pad="0")
        self.month_edit.clear_on_enter = True
        self.month_edit.right_justify = True
        self.center_win.add_text("(1-12)", y_loc, self.info_offset)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.day_err = ErrorWindow(self.err_area,
                                   window=self.center_win,
                                   centered=False)
        self.day_list = ListItem(self.list_area,
                                 window=self.center_win,
                                 text=DateTimeScreen.DAY_TEXT)
        self.day_edit = EditField(self.edit_area,
                                  window=self.day_list,
                                  validate=day_valid,
                                  error_win=self.day_err,
                                  on_exit=day_on_exit,
                                  text=self.saved_day,
                                  numeric_pad="0")
        self.day_edit.clear_on_enter = True
        self.day_edit.right_justify = True

        self.month_edit.validate_kwargs["date_time"] = self
        self.month_edit.validate_kwargs["year_edit"] = self.year_edit
        self.month_edit.validate_kwargs["day_edit"] = self.day_edit

        self.year_edit.validate_kwargs["date_time"] = self
        self.year_edit.validate_kwargs["month_edit"] = self.month_edit
        self.year_edit.validate_kwargs["day_edit"] = self.day_edit

        self.day_edit.validate_kwargs["date_time"] = self
        self.day_edit.validate_kwargs["year_edit"] = self.year_edit
        self.day_edit.validate_kwargs["month_edit"] = self.month_edit
        self.date_range_loc = (y_loc, self.info_offset)
        self.update_day_range(self.saved_days_in_month)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.hour_err = ErrorWindow(self.err_area,
                                    window=self.center_win,
                                    centered=False)
        self.hour_list = ListItem(self.list_area,
                                  window=self.center_win,
                                  text=DateTimeScreen.HOUR_TEXT)
        self.hour_edit = EditField(self.edit_area,
                                   window=self.hour_list,
                                   validate=hour_valid,
                                   error_win=self.hour_err,
                                   on_exit=hour_on_exit,
                                   text=self.saved_hour,
                                   numeric_pad="0")
        self.hour_edit.clear_on_enter = True
        self.hour_edit.right_justify = True
        self.center_win.add_text("(0-23)", y_loc, self.info_offset)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.minute_err = ErrorWindow(self.err_area,
                                      window=self.center_win,
                                      centered=False)
        self.minute_list = ListItem(self.list_area,
                                    window=self.center_win,
                                    text=DateTimeScreen.MINUTE_TEXT)
        self.minute_edit = EditField(self.edit_area,
                                     window=self.minute_list,
                                     validate=minute_valid,
                                     error_win=self.minute_err,
                                     on_exit=minute_on_exit,
                                     text=self.saved_minute,
                                     numeric_pad="0")
        self.minute_edit.clear_on_enter = True
        self.minute_edit.right_justify = True
        self.center_win.add_text("(0-59)", y_loc, self.info_offset)

        self.main_win.do_update()
        self.center_win.activate_object(self.year_list)

    def validate(self):
        '''Verify each of the edit fields'''
        year_value = self.year_edit.get_text()
        month_value = self.month_edit.get_text()
        day_value = self.day_edit.get_text()
        hour_value = self.hour_edit.get_text()
        minute_value = self.minute_edit.get_text()
        LOGGER.debug("year_value=%s", year_value)
        LOGGER.debug("month_value=%s", month_value)
        LOGGER.debug("day_value=%s", day_value)
        LOGGER.debug("hour_value=%s", hour_value)
        LOGGER.debug("minute_value=%s", minute_value)
        had_err = False
        if not self.year_edit.run_on_exit():
            had_err = True
        if not self.month_edit.run_on_exit():
            had_err = True
        if not self.day_edit.run_on_exit():
            had_err = True
        if not self.hour_edit.run_on_exit():
            had_err = True
        if not self.minute_edit.run_on_exit():
            had_err = True
        if had_err:
            raise UIMessage(_("Invalid date/time. See errors above."))

    def update_day_range(self, maxday=31):
        '''
        Update the day range displayed. The max number of days can vary
        depending on the month, so calling functions can update appropriately.
        
        '''
        self.center_win.add_text("(1-%d)" % maxday, self.date_range_loc[0],
                                 self.date_range_loc[1], self.win_size_x - 3)
        self.saved_days_in_month = maxday

    def on_change_screen(self):
        '''Save current user input for return to screen'''
        self.saved_year = self.year_edit.get_text()
        self.saved_month = self.month_edit.get_text()
        self.saved_day = self.day_edit.get_text()
        self.saved_hour = self.hour_edit.get_text()
        self.saved_minute = self.minute_edit.get_text()

    def on_continue(self):
        '''Save time offset to profile'''
        saved_time = datetime.datetime(int(self.year_edit.get_text()),
                                       int(self.month_edit.get_text()),
                                       int(self.day_edit.get_text()),
                                       int(self.hour_edit.get_text()),
                                       int(self.minute_edit.get_text()))
        userdelta = saved_time - datetime.datetime.now()
        LOGGER.debug("delta time=%s", userdelta)
        sc_profile = solaris_install.sysconfig.profile.from_engine()
        sc_profile.system.time_offset = userdelta
        install_datetime = datetime.datetime.now() + userdelta
        LOGGER.debug("date command would be: /usr/bin/date %s",
                     install_datetime.strftime("%m%d%H%M%y"))
class ValidSample(BaseScreen):
    HEADER_TEXT = "Validation - Sample"
    
    def __init__(self, main_win):
        super(ValidSample, self).__init__(main_win)
        
        # Boilerplate; for storing references to the created ListItems,
        # EditFields, and ErrorWindows
        self.char_list = None
        self.char_field = None
        
        self.char2_list = None
        self.char2_field = None
        self.char2_err = None
        
        self.focus_list = None
        self.focus_field = None
        self.focus_err = None
    
    def _show(self):
        # WindowArea boilerplate
        list_area = WindowArea(lines=1, columns=40, y_loc=1, x_loc=1)
        edit_area = WindowArea(lines=1, columns=20, y_loc=0, x_loc=15)
        
        # EditFields support per-character validation by passing in
        # a callback function as the "validate" keyword argument. The function
        # is called after each keypress with a single parameter, the EditField
        # in question (from which one can grab the current text). If the
        # current value is valid, the function should do nothing. If invalid,
        # a UIMessage exception should be raised.
        
        # For the sake of 'flow', the validation functions for this sample
        # will be defined inline; in general, they should be defined elsewhere
        # in the file. Finally, remember that, since these functions are
        # called after each keystroke, they need to be able to handle partially
        # correct values as well. For example, "2", "25", "255", "255.",
        # "255.2", "255.25", ..., "255.255.255.0" all would need to be accepted
        # by a netmask validation function.
        def digits_only(edit_field):
            text = edit_field.get_text()
            if text and not text.isdigit():
                raise UIMessage("Only digits allowed!")
        
        list_area.y_loc = 1
        self.char_list = ListItem(list_area, window=self.center_win,
                                  text="validate:")
        self.char_edit = EditField(edit_area,
                                   window=self.char_list,
                                   validate=digits_only,
                                   error_win=self.main_win.error_line)
        # The error_win parameter is required to make anything meaningful
        # display to the user; it should be a reference to an ErrorWindow
        # object in which to display the message. (self.main_win.error_line
        # is used here as filler; a more appropriate example follows)
        
        list_area.y_loc = 2
        # There's nothing too special about creating an ErrorWindow;
        # it's much like a ListItem or EditField:
        error_area = WindowArea(lines=1, columns=30, y_loc=2, x_loc=40)
        self.char2_err = ErrorWindow(error_area, self.center_win)
        self.char2_list = ListItem(list_area, window=self.center_win,
                                  text="validate(2):")
        self.char2_edit = EditField(edit_area,
                                    window=self.char2_list,
                                    validate=digits_only,
                                    error_win=self.char2_err)
        
        
        # An EditField can also be checked for validity on loss of focus,
        # by passing a function to the "on_exit" argument
        # (though care must be taken to also check validity when changing
        #  screens; screen changes don't trigger loss-of-focus checks in the
        #  same way)
        # The following EditField illustrates such a thing. (An on_exit
        # function would be an appropriate place to ensure that a user
        # entered "255.255.255.0" for a netmask, and not just "255.")
        list_area.y_loc = 3
        error_area.y_loc = 3
        self.focus_err = ErrorWindow(error_area, self.center_win)
        self.focus_list = ListItem(list_area, window=self.center_win,
                                  text="on_exit:")
        self.focus_edit = EditField(edit_area,
                                    window=self.focus_list,
                                    on_exit=digits_only,
                                    error_win=self.focus_err)
        
        self.center_win.activate_object()
    
    def validate(self):
        # As a final (and perhaps, most important) form of validation, when
        # a subclass of BaseScreen attempts to move *forward* to the next
        # screen, it will call its "validate()" function, if any. Like the
        # callback functions for EditFields, this function should raise a
        # UIMessage if there are any conditions which fail validation.
        # 
        # validate() is not called if the user decides to go backwards; the
        # user is never locked out of reversing their direction
        # 
        # Note: validate() is always called prior to "on_continue()"; thus,
        # any code in the on_continue function, if defined, can be certain
        # that the values for this screen are valid.
        
        # For this sample, the first two fields will be required to have
        # identical text.
        if self.char_edit.get_text() != self.char2_edit.get_text():
            raise UIMessage("First 2 fields must have identical text!")
 def _show(self):
     # WindowArea boilerplate
     list_area = WindowArea(lines=1, columns=40, y_loc=1, x_loc=1)
     edit_area = WindowArea(lines=1, columns=20, y_loc=0, x_loc=15)
     
     # EditFields support per-character validation by passing in
     # a callback function as the "validate" keyword argument. The function
     # is called after each keypress with a single parameter, the EditField
     # in question (from which one can grab the current text). If the
     # current value is valid, the function should do nothing. If invalid,
     # a UIMessage exception should be raised.
     
     # For the sake of 'flow', the validation functions for this sample
     # will be defined inline; in general, they should be defined elsewhere
     # in the file. Finally, remember that, since these functions are
     # called after each keystroke, they need to be able to handle partially
     # correct values as well. For example, "2", "25", "255", "255.",
     # "255.2", "255.25", ..., "255.255.255.0" all would need to be accepted
     # by a netmask validation function.
     def digits_only(edit_field):
         text = edit_field.get_text()
         if text and not text.isdigit():
             raise UIMessage("Only digits allowed!")
     
     list_area.y_loc = 1
     self.char_list = ListItem(list_area, window=self.center_win,
                               text="validate:")
     self.char_edit = EditField(edit_area,
                                window=self.char_list,
                                validate=digits_only,
                                error_win=self.main_win.error_line)
     # The error_win parameter is required to make anything meaningful
     # display to the user; it should be a reference to an ErrorWindow
     # object in which to display the message. (self.main_win.error_line
     # is used here as filler; a more appropriate example follows)
     
     list_area.y_loc = 2
     # There's nothing too special about creating an ErrorWindow;
     # it's much like a ListItem or EditField:
     error_area = WindowArea(lines=1, columns=30, y_loc=2, x_loc=40)
     self.char2_err = ErrorWindow(error_area, self.center_win)
     self.char2_list = ListItem(list_area, window=self.center_win,
                               text="validate(2):")
     self.char2_edit = EditField(edit_area,
                                 window=self.char2_list,
                                 validate=digits_only,
                                 error_win=self.char2_err)
     
     
     # An EditField can also be checked for validity on loss of focus,
     # by passing a function to the "on_exit" argument
     # (though care must be taken to also check validity when changing
     #  screens; screen changes don't trigger loss-of-focus checks in the
     #  same way)
     # The following EditField illustrates such a thing. (An on_exit
     # function would be an appropriate place to ensure that a user
     # entered "255.255.255.0" for a netmask, and not just "255.")
     list_area.y_loc = 3
     error_area.y_loc = 3
     self.focus_err = ErrorWindow(error_area, self.center_win)
     self.focus_list = ListItem(list_area, window=self.center_win,
                               text="on_exit:")
     self.focus_edit = EditField(edit_area,
                                 window=self.focus_list,
                                 on_exit=digits_only,
                                 error_win=self.focus_err)
     
     self.center_win.activate_object()
示例#23
0
 def _show(self):
     # WindowArea boilerplate
     list_area = WindowArea(lines=1, columns=40, y_loc=1, x_loc=1)
     edit_area = WindowArea(lines=1, columns=20, y_loc=0, x_loc=15)
     
     # EditFields support per-character validation by passing in
     # a callback function as the "validate" keyword argument. The function
     # is called after each keypress with a single parameter, the EditField
     # in question (from which one can grab the current text). If the
     # current value is valid, the function should do nothing. If invalid,
     # a UIMessage exception should be raised.
     
     # For the sake of 'flow', the validation functions for this sample
     # will be defined inline; in general, they should be defined elsewhere
     # in the file. Finally, remember that, since these functions are
     # called after each keystroke, they need to be able to handle partially
     # correct values as well. For example, "2", "25", "255", "255.",
     # "255.2", "255.25", ..., "255.255.255.0" all would need to be accepted
     # by a netmask validation function.
     def digits_only(edit_field):
         text = edit_field.get_text()
         if text and not text.isdigit():
             raise UIMessage("Only digits allowed!")
     
     list_area.y_loc = 1
     self.char_list = ListItem(list_area, window=self.center_win,
                               text="validate:")
     self.char_edit = EditField(edit_area,
                                window=self.char_list,
                                validate=digits_only,
                                error_win=self.main_win.error_line)
     # The error_win parameter is required to make anything meaningful
     # display to the user; it should be a reference to an ErrorWindow
     # object in which to display the message. (self.main_win.error_line
     # is used here as filler; a more appropriate example follows)
     
     list_area.y_loc = 2
     # There's nothing too special about creating an ErrorWindow;
     # it's much like a ListItem or EditField:
     error_area = WindowArea(lines=1, columns=30, y_loc=2, x_loc=40)
     self.char2_err = ErrorWindow(error_area, self.center_win)
     self.char2_list = ListItem(list_area, window=self.center_win,
                               text="validate(2):")
     self.char2_edit = EditField(edit_area,
                                 window=self.char2_list,
                                 validate=digits_only,
                                 error_win=self.char2_err)
     
     
     # An EditField can also be checked for validity on loss of focus,
     # by passing a function to the "on_exit" argument
     # (though care must be taken to also check validity when changing
     #  screens; screen changes don't trigger loss-of-focus checks in the
     #  same way)
     # The following EditField illustrates such a thing. (An on_exit
     # function would be an appropriate place to ensure that a user
     # entered "255.255.255.0" for a netmask, and not just "255.")
     list_area.y_loc = 3
     error_area.y_loc = 3
     self.focus_err = ErrorWindow(error_area, self.center_win)
     self.focus_list = ListItem(list_area, window=self.center_win,
                               text="on_exit:")
     self.focus_edit = EditField(edit_area,
                                 window=self.focus_list,
                                 on_exit=digits_only,
                                 error_win=self.focus_err)
     
     self.center_win.activate_object()
示例#24
0
class ValidSample(BaseScreen):
    HEADER_TEXT = "Validation - Sample"
    
    def __init__(self, main_win):
        super(ValidSample, self).__init__(main_win)
        
        # Boilerplate; for storing references to the created ListItems,
        # EditFields, and ErrorWindows
        self.char_list = None
        self.char_field = None
        
        self.char2_list = None
        self.char2_field = None
        self.char2_err = None
        
        self.focus_list = None
        self.focus_field = None
        self.focus_err = None
    
    def _show(self):
        # WindowArea boilerplate
        list_area = WindowArea(lines=1, columns=40, y_loc=1, x_loc=1)
        edit_area = WindowArea(lines=1, columns=20, y_loc=0, x_loc=15)
        
        # EditFields support per-character validation by passing in
        # a callback function as the "validate" keyword argument. The function
        # is called after each keypress with a single parameter, the EditField
        # in question (from which one can grab the current text). If the
        # current value is valid, the function should do nothing. If invalid,
        # a UIMessage exception should be raised.
        
        # For the sake of 'flow', the validation functions for this sample
        # will be defined inline; in general, they should be defined elsewhere
        # in the file. Finally, remember that, since these functions are
        # called after each keystroke, they need to be able to handle partially
        # correct values as well. For example, "2", "25", "255", "255.",
        # "255.2", "255.25", ..., "255.255.255.0" all would need to be accepted
        # by a netmask validation function.
        def digits_only(edit_field):
            text = edit_field.get_text()
            if text and not text.isdigit():
                raise UIMessage("Only digits allowed!")
        
        list_area.y_loc = 1
        self.char_list = ListItem(list_area, window=self.center_win,
                                  text="validate:")
        self.char_edit = EditField(edit_area,
                                   window=self.char_list,
                                   validate=digits_only,
                                   error_win=self.main_win.error_line)
        # The error_win parameter is required to make anything meaningful
        # display to the user; it should be a reference to an ErrorWindow
        # object in which to display the message. (self.main_win.error_line
        # is used here as filler; a more appropriate example follows)
        
        list_area.y_loc = 2
        # There's nothing too special about creating an ErrorWindow;
        # it's much like a ListItem or EditField:
        error_area = WindowArea(lines=1, columns=30, y_loc=2, x_loc=40)
        self.char2_err = ErrorWindow(error_area, self.center_win)
        self.char2_list = ListItem(list_area, window=self.center_win,
                                  text="validate(2):")
        self.char2_edit = EditField(edit_area,
                                    window=self.char2_list,
                                    validate=digits_only,
                                    error_win=self.char2_err)
        
        
        # An EditField can also be checked for validity on loss of focus,
        # by passing a function to the "on_exit" argument
        # (though care must be taken to also check validity when changing
        #  screens; screen changes don't trigger loss-of-focus checks in the
        #  same way)
        # The following EditField illustrates such a thing. (An on_exit
        # function would be an appropriate place to ensure that a user
        # entered "255.255.255.0" for a netmask, and not just "255.")
        list_area.y_loc = 3
        error_area.y_loc = 3
        self.focus_err = ErrorWindow(error_area, self.center_win)
        self.focus_list = ListItem(list_area, window=self.center_win,
                                  text="on_exit:")
        self.focus_edit = EditField(edit_area,
                                    window=self.focus_list,
                                    on_exit=digits_only,
                                    error_win=self.focus_err)
        
        self.center_win.activate_object()
    
    def validate(self):
        # As a final (and perhaps, most important) form of validation, when
        # a subclass of BaseScreen attempts to move *forward* to the next
        # screen, it will call its "validate()" function, if any. Like the
        # callback functions for EditFields, this function should raise a
        # UIMessage if there are any conditions which fail validation.
        # 
        # validate() is not called if the user decides to go backwards; the
        # user is never locked out of reversing their direction
        # 
        # Note: validate() is always called prior to "on_continue()"; thus,
        # any code in the on_continue function, if defined, can be certain
        # that the values for this screen are valid.
        
        # For this sample, the first two fields will be required to have
        # identical text.
        if self.char_edit.get_text() != self.char2_edit.get_text():
            raise UIMessage("First 2 fields must have identical text!")
示例#25
0
    def _show(self):
        '''Display the user name, real name, and password fields'''

        sc_profile = solaris_install.sysconfig.profile.from_engine()

        #
        # Create UserInfo instances holding information about root and user
        # accounts.
        #
        if sc_profile.users is None:
            #
            # Assume root is a normal account. It will be changed to a role
            # if the user account is created.
            #
            root = UserInfo(login_name="root", is_role=False)

            #
            # Initialize attributes of user account which can't be configured
            # on screens.
            #
            user = UserInfo(gid=10,
                            shell="/usr/bin/bash",
                            roles="root",
                            profiles="System Administrator",
                            sudoers="ALL=(ALL) ALL")
            sc_profile.users = UserInfoContainer(root, user)

        self.root = sc_profile.users.root
        self.user = sc_profile.users.user

        LOGGER.debug("Root: %s", self.root)
        LOGGER.debug("User: %s", self.user)

        root_set = (self.root.passlen != 0)
        user_set = (self.user.passlen != 0)

        y_loc = 1

        if self.show_user_account:
            intro_text = UserScreen.INTRO_SHOW_USER
        else:
            intro_text = UserScreen.INTRO_HIDE_USER

        self.center_win.add_paragraph(intro_text, y_loc, 1, y_loc + 2,
                                      self.win_size_x - 1)

        y_loc += 3
        self.center_win.add_text(UserScreen.ROOT_TEXT, y_loc, 1,
                                 self.win_size_x - 1)

        y_loc += 2
        self.error_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        self.root_pass_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.root_pass_list = ListItem(self.list_area,
                                       window=self.center_win,
                                       text=UserScreen.ROOT_LABEL)
        self.root_pass_edit = PasswordField(self.edit_area,
                                            window=self.root_pass_list,
                                            error_win=self.root_pass_err,
                                            fill=root_set)

        y_loc += 1
        self.error_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        self.root_confirm_err = ErrorWindow(self.error_area,
                                            window=self.center_win)
        self.root_confirm_list = ListItem(self.list_area,
                                          window=self.center_win,
                                          text=UserScreen.CONFIRM_LABEL)
        self.root_confirm_edit = PasswordField(self.edit_area,
                                               window=self.root_confirm_list,
                                               fill=root_set,
                                               on_exit=pass_match,
                                               error_win=self.root_confirm_err)
        rc_edit_kwargs = {"linked_win": self.root_pass_edit}
        self.root_confirm_edit.on_exit_kwargs = rc_edit_kwargs

        # User account disabled, do not display related widgets.
        if not self.show_user_account:
            self.main_win.do_update()
            self.center_win.activate_object(self.root_pass_list)
            return

        y_loc += 2
        self.center_win.add_text(UserScreen.USER_TEXT, y_loc, 1,
                                 self.win_size_x - 1)

        y_loc += 2
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.real_name_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.real_name_list = ListItem(self.list_area,
                                       window=self.center_win,
                                       text=UserScreen.NAME_LABEL)
        self.real_name_edit = EditField(self.edit_area,
                                        window=self.real_name_list,
                                        error_win=self.real_name_err,
                                        text=self.user.real_name)

        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.username_err = ErrorWindow(self.error_area,
                                        window=self.center_win)
        self.username_list = ListItem(self.list_area,
                                      window=self.center_win,
                                      text=UserScreen.USERNAME_LABEL)
        self.username_edit = EditField(self.username_edit_area,
                                       window=self.username_list,
                                       validate=username_valid,
                                       error_win=self.username_err,
                                       on_exit=login_valid,
                                       text=self.user.login_name)

        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.user_pass_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.user_pass_list = ListItem(self.list_area,
                                       window=self.center_win,
                                       text=UserScreen.USER_PASS_LABEL)
        self.user_pass_edit = PasswordField(self.edit_area,
                                            window=self.user_pass_list,
                                            error_win=self.user_pass_err,
                                            fill=user_set)

        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.user_confirm_err = ErrorWindow(self.error_area,
                                            window=self.center_win)
        self.user_confirm_list = ListItem(self.list_area,
                                          window=self.center_win,
                                          text=UserScreen.CONFIRM_LABEL)
        self.user_confirm_edit = PasswordField(self.edit_area,
                                               window=self.user_confirm_list,
                                               on_exit=pass_match,
                                               error_win=self.user_confirm_err,
                                               fill=user_set)
        uc_edit_kwargs = {"linked_win": self.user_pass_edit}
        self.user_confirm_edit.on_exit_kwargs = uc_edit_kwargs

        self.main_win.do_update()
        self.center_win.activate_object(self.root_pass_list)
示例#26
0
class NSLDAPProfile(NameService):

    HEADER_TEXT = _("LDAP Profile")
    HELP_DATA = (SCI_HELP + "/%s/ldap_profile.txt", HEADER_TEXT)

    def __init__(self, main_win):
        super(NSLDAPProfile, self).__init__(main_win)
        self.title = _("Profile name:")
        self.title3 = _("Search base:")

    def _show(self):
        super(NSLDAPProfile, self)._show()
        if self.nameservice.nameservice != 'LDAP':
            raise SkipException
        if self.nameservice.dns:
            self.intro = \
                _("Specify the name of the LDAP profile to be used to "
                  "configure this system and the host name or IP address of "
                  "the server that contains the profile.")
            self.title2 = _("Profile server host name or IP address:")
        else:
            self.intro = \
                _("Specify the name of the LDAP profile to be used to "
                  "configure this system and the IP address of the "
                  "server that contains the profile.")
            self.title2 = _("Profile server IP address:")
        self.intro += _("  Enter the LDAP search base.")
        y_loc = self._paint_opening()
        maxtitlelen = max(textwidth(self.title), textwidth(self.title2),
                          textwidth(self.title3))
        aligned_x_loc = maxtitlelen + INDENT + 1
        cols = self.win_size_x - aligned_x_loc
        self.center_win.add_text(self.title.rjust(maxtitlelen), y_loc, INDENT)
        area = WindowArea(1, cols, y_loc, aligned_x_loc)
        self.ldap_profile = EditField(area, window=self.center_win,
                                      text=self.nameservice.ldap_profile,
                                      error_win=self.main_win.error_line,
                                      validate=inc_validate_nowhite_nospecial)
        # in case of error, tell user what is being validated
        self.ldap_profile.validate_kwargs['etext'] = _('profile name')
        y_loc += 1
        area = WindowArea(1, cols, y_loc, aligned_x_loc,
                        scrollable_columns=NameService.HOSTNAME_SCREEN_LEN + 1)
        self.center_win.add_text(self.title2.rjust(maxtitlelen), y_loc, INDENT)
        # create edit field, validating for host name or IP address depending
        # on whether DNS was selected
        self.ldap_ip = EditField(area, window=self.center_win,
                                 text=self.nameservice.ldap_ip,
                                 error_win=self.main_win.error_line,
                                 validate=(incremental_validate_host
                                           if self.nameservice.dns
                                           else incremental_validate_ip))
        # search base
        y_loc += 1
        self.center_win.add_text(self.title3.rjust(maxtitlelen), y_loc, INDENT)
        area = WindowArea(1, cols, y_loc, aligned_x_loc,
                          scrollable_columns=MAXDNLEN + 1)
        self.ldap_search_base = EditField(area, window=self.center_win,
                                        text=self.nameservice.ldap_search_base,
                                        error_win=self.main_win.error_line)
        self.main_win.do_update()
        self.center_win.activate_object(self.ldap_ip)

    def validate(self):
        validate_ldap_profile(self.ldap_profile.get_text())
        ldap_ip = self.ldap_ip.get_text()
        if self.nameservice.dns:
            validate_host_or_ip(ldap_ip)
        else:
            validate_ip(ldap_ip)
        if not self.ldap_profile.get_text():
            raise UIMessage(_("The LDAP profile name cannot be blank."))
        if not ldap_ip:
            raise UIMessage(_("The LDAP server IP address cannot be blank."))

    def on_change_screen(self):
        self.nameservice.ldap_profile = self.ldap_profile.get_text()
        self.nameservice.ldap_ip = self.ldap_ip.get_text()
        new_search_base = self.ldap_search_base.get_text()
        if new_search_base != self.nameservice.ldap_search_base:
            self.nameservice.ldap_search_base = new_search_base
            # update DN with any changes in search_base from user
            fixedbase = _ldap_domain_fixup(self.nameservice.ldap_pb_dn,
                                           new_search_base)
            if fixedbase:
                self.nameservice.ldap_pb_dn = fixedbase
 def _show(self):
     '''
     Prepare the editable fields for day, month, year, hour and minute
     
     '''
     y_loc = 1
     
     y_loc += self.center_win.add_paragraph(DateTimeScreen.PARAGRAPH, y_loc)
     
     sc_profile = solaris_install.sysconfig.profile.from_engine()
     
     os.environ["TZ"] = sc_profile.system.tz_timezone
     now = datetime.datetime.now()
     LOGGER.log(LOG_LEVEL_INPUT, "Current date (year-month-day hour:minute)"
                ": %s-%s-%s %s:%s", now.year, now.month, now.day, now.hour,
                now.minute)
     
     # Only update saved values if this is first time on screen or
     # if we have saved offset in profile (F2, return to screen)
     #
     update_vals = False
     if self.saved_year is None:
         update_vals = True
         showtime = now
     elif sc_profile.system.time_offset != 0:
         showtime = now + sc_profile.system.time_offset
         update_vals = True
         sc_profile.system.time_offset = 0
     
     if update_vals:
         self.saved_year = str(showtime.year)
         self.saved_month = str(showtime.month)
         self.saved_day = str(showtime.day)
         self.saved_hour = str(showtime.hour)
         self.saved_minute = str(showtime.minute)
         self.saved_days_in_month = calendar.monthrange(showtime.year,
                                                        showtime.month)[1]
         
     LOGGER.debug("starting year month day hour minute:_%s_%s_%s_%s_%s",
                   self.saved_year, self.saved_month, self.saved_day,
                   self.saved_hour, self.saved_minute)
     LOGGER.debug("starting days_in_month: %s", self.saved_days_in_month)
     
     y_loc += 1
     self.err_area.y_loc = y_loc
     self.list_area.y_loc = y_loc
     
     self.year_err = ErrorWindow(self.err_area, window=self.center_win,
                                 centered=False)
     self.year_list = ListItem(self.list_area,
                               window=self.center_win,
                               text=DateTimeScreen.YEAR_TEXT)
     self.year_edit = EditField(self.year_edit_area, window=self.year_list,
                                validate=year_valid,
                                error_win=self.year_err,
                                on_exit=year_on_exit,
                                text=self.saved_year)
     self.year_edit.clear_on_enter = True
     
     self.center_win.add_text(DateTimeScreen.YEAR_FORMAT, y_loc,
                              self.info_offset)
     
     y_loc += 1
     self.err_area.y_loc = y_loc
     self.list_area.y_loc = y_loc
     
     self.month_err = ErrorWindow(self.err_area, window=self.center_win,
                                 centered=False)
     self.month_list = ListItem(self.list_area, window=self.center_win,
                                text=DateTimeScreen.MONTH_TEXT)
     self.month_edit = EditField(self.edit_area, window=self.month_list,
                                 validate=month_valid,
                                 error_win=self.month_err,
                                 on_exit=month_on_exit,
                                 text=self.saved_month,
                                 numeric_pad="0")
     self.month_edit.clear_on_enter = True
     self.month_edit.right_justify = True
     self.center_win.add_text("(1-12)", y_loc, self.info_offset)
     
     y_loc += 1
     self.err_area.y_loc = y_loc
     self.list_area.y_loc = y_loc
     
     self.day_err = ErrorWindow(self.err_area, window=self.center_win,
                                centered=False)
     self.day_list = ListItem(self.list_area,
                              window=self.center_win,
                              text=DateTimeScreen.DAY_TEXT)
     self.day_edit = EditField(self.edit_area, window=self.day_list,
                               validate=day_valid,
                               error_win=self.day_err,
                               on_exit=day_on_exit,
                               text=self.saved_day,
                               numeric_pad="0")
     self.day_edit.clear_on_enter = True
     self.day_edit.right_justify = True
     
     self.month_edit.validate_kwargs["date_time"] = self
     self.month_edit.validate_kwargs["year_edit"] = self.year_edit
     self.month_edit.validate_kwargs["day_edit"] = self.day_edit
     
     self.year_edit.validate_kwargs["date_time"] = self
     self.year_edit.validate_kwargs["month_edit"] = self.month_edit
     self.year_edit.validate_kwargs["day_edit"] = self.day_edit
     
     self.day_edit.validate_kwargs["date_time"] = self
     self.day_edit.validate_kwargs["year_edit"] = self.year_edit
     self.day_edit.validate_kwargs["month_edit"] = self.month_edit
     self.date_range_loc = (y_loc, self.info_offset)
     self.update_day_range(self.saved_days_in_month)
     
     y_loc += 1
     self.err_area.y_loc = y_loc
     self.list_area.y_loc = y_loc
     
     self.hour_err = ErrorWindow(self.err_area, window=self.center_win,
                                 centered=False)
     self.hour_list = ListItem(self.list_area, window=self.center_win,
                               text=DateTimeScreen.HOUR_TEXT)
     self.hour_edit = EditField(self.edit_area, window=self.hour_list,
                                validate=hour_valid,
                                error_win=self.hour_err,
                                on_exit=hour_on_exit,
                                text=self.saved_hour,
                                numeric_pad="0")
     self.hour_edit.clear_on_enter = True
     self.hour_edit.right_justify = True
     self.center_win.add_text("(0-23)", y_loc, self.info_offset)
     
     y_loc += 1
     self.err_area.y_loc = y_loc
     self.list_area.y_loc = y_loc
     
     self.minute_err = ErrorWindow(self.err_area, window=self.center_win,
                                   centered=False)
     self.minute_list = ListItem(self.list_area, window=self.center_win,
                                 text=DateTimeScreen.MINUTE_TEXT)
     self.minute_edit = EditField(self.edit_area,
                                  window=self.minute_list,
                                  validate=minute_valid,
                                  error_win=self.minute_err,
                                  on_exit=minute_on_exit,
                                  text=self.saved_minute,
                                  numeric_pad="0")
     self.minute_edit.clear_on_enter = True
     self.minute_edit.right_justify = True
     self.center_win.add_text("(0-59)", y_loc, self.info_offset)
     
     self.main_win.do_update()
     self.center_win.activate_object(self.year_list)
示例#28
0
    def _show(self):
        '''
        Prepare the editable fields for day, month, year, hour and minute
        
        '''
        y_loc = 1

        y_loc += self.center_win.add_paragraph(DateTimeScreen.PARAGRAPH, y_loc)

        sc_profile = solaris_install.sysconfig.profile.from_engine()

        os.environ["TZ"] = sc_profile.system.tz_timezone
        now = datetime.datetime.now()
        LOGGER.log(
            LOG_LEVEL_INPUT, "Current date (year-month-day hour:minute)"
            ": %s-%s-%s %s:%s", now.year, now.month, now.day, now.hour,
            now.minute)

        # Only update saved values if this is first time on screen or
        # if we have saved offset in profile (F2, return to screen)
        #
        update_vals = False
        if self.saved_year is None:
            update_vals = True
            showtime = now
        elif sc_profile.system.time_offset != 0:
            showtime = now + sc_profile.system.time_offset
            update_vals = True
            sc_profile.system.time_offset = 0

        if update_vals:
            self.saved_year = str(showtime.year)
            self.saved_month = str(showtime.month)
            self.saved_day = str(showtime.day)
            self.saved_hour = str(showtime.hour)
            self.saved_minute = str(showtime.minute)
            self.saved_days_in_month = calendar.monthrange(
                showtime.year, showtime.month)[1]

        LOGGER.debug("starting year month day hour minute:_%s_%s_%s_%s_%s",
                     self.saved_year, self.saved_month, self.saved_day,
                     self.saved_hour, self.saved_minute)
        LOGGER.debug("starting days_in_month: %s", self.saved_days_in_month)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.year_err = ErrorWindow(self.err_area,
                                    window=self.center_win,
                                    centered=False)
        self.year_list = ListItem(self.list_area,
                                  window=self.center_win,
                                  text=DateTimeScreen.YEAR_TEXT)
        self.year_edit = EditField(self.year_edit_area,
                                   window=self.year_list,
                                   validate=year_valid,
                                   error_win=self.year_err,
                                   on_exit=year_on_exit,
                                   text=self.saved_year)
        self.year_edit.clear_on_enter = True

        self.center_win.add_text(DateTimeScreen.YEAR_FORMAT, y_loc,
                                 self.info_offset)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.month_err = ErrorWindow(self.err_area,
                                     window=self.center_win,
                                     centered=False)
        self.month_list = ListItem(self.list_area,
                                   window=self.center_win,
                                   text=DateTimeScreen.MONTH_TEXT)
        self.month_edit = EditField(self.edit_area,
                                    window=self.month_list,
                                    validate=month_valid,
                                    error_win=self.month_err,
                                    on_exit=month_on_exit,
                                    text=self.saved_month,
                                    numeric_pad="0")
        self.month_edit.clear_on_enter = True
        self.month_edit.right_justify = True
        self.center_win.add_text("(1-12)", y_loc, self.info_offset)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.day_err = ErrorWindow(self.err_area,
                                   window=self.center_win,
                                   centered=False)
        self.day_list = ListItem(self.list_area,
                                 window=self.center_win,
                                 text=DateTimeScreen.DAY_TEXT)
        self.day_edit = EditField(self.edit_area,
                                  window=self.day_list,
                                  validate=day_valid,
                                  error_win=self.day_err,
                                  on_exit=day_on_exit,
                                  text=self.saved_day,
                                  numeric_pad="0")
        self.day_edit.clear_on_enter = True
        self.day_edit.right_justify = True

        self.month_edit.validate_kwargs["date_time"] = self
        self.month_edit.validate_kwargs["year_edit"] = self.year_edit
        self.month_edit.validate_kwargs["day_edit"] = self.day_edit

        self.year_edit.validate_kwargs["date_time"] = self
        self.year_edit.validate_kwargs["month_edit"] = self.month_edit
        self.year_edit.validate_kwargs["day_edit"] = self.day_edit

        self.day_edit.validate_kwargs["date_time"] = self
        self.day_edit.validate_kwargs["year_edit"] = self.year_edit
        self.day_edit.validate_kwargs["month_edit"] = self.month_edit
        self.date_range_loc = (y_loc, self.info_offset)
        self.update_day_range(self.saved_days_in_month)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.hour_err = ErrorWindow(self.err_area,
                                    window=self.center_win,
                                    centered=False)
        self.hour_list = ListItem(self.list_area,
                                  window=self.center_win,
                                  text=DateTimeScreen.HOUR_TEXT)
        self.hour_edit = EditField(self.edit_area,
                                   window=self.hour_list,
                                   validate=hour_valid,
                                   error_win=self.hour_err,
                                   on_exit=hour_on_exit,
                                   text=self.saved_hour,
                                   numeric_pad="0")
        self.hour_edit.clear_on_enter = True
        self.hour_edit.right_justify = True
        self.center_win.add_text("(0-23)", y_loc, self.info_offset)

        y_loc += 1
        self.err_area.y_loc = y_loc
        self.list_area.y_loc = y_loc

        self.minute_err = ErrorWindow(self.err_area,
                                      window=self.center_win,
                                      centered=False)
        self.minute_list = ListItem(self.list_area,
                                    window=self.center_win,
                                    text=DateTimeScreen.MINUTE_TEXT)
        self.minute_edit = EditField(self.edit_area,
                                     window=self.minute_list,
                                     validate=minute_valid,
                                     error_win=self.minute_err,
                                     on_exit=minute_on_exit,
                                     text=self.saved_minute,
                                     numeric_pad="0")
        self.minute_edit.clear_on_enter = True
        self.minute_edit.right_justify = True
        self.center_win.add_text("(0-59)", y_loc, self.info_offset)

        self.main_win.do_update()
        self.center_win.activate_object(self.year_list)
示例#29
0
    def _show(self):
        '''Create an EditField for entering hostname, and list items
        for each of the network types
        
        '''
        sc_profile = solaris_install.sysconfig.profile.from_engine()

        if sc_profile.system is None:
            sc_profile.system = SystemInfo()
        self.sys_info = sc_profile.system
        if sc_profile.nic is None:
            sc_profile.nic = self.nic_info

        y_loc = 1

        y_loc += self.center_win.add_paragraph(NetworkTypeScreen.PARAGRAPH,
                                               y_loc)

        y_loc += 1
        self.center_win.add_text(NetworkTypeScreen.HOSTNAME_TEXT, y_loc)

        max_cols = self.win_size_x - self.hostfield_offset
        cols = min(max_cols, NetworkTypeScreen.HOSTNAME_SCREEN_LEN)
        scrollable_columns = SystemInfo.MAX_HOSTNAME_LEN + 1
        hostname_area = WindowArea(1,
                                   cols,
                                   y_loc,
                                   self.hostfield_offset,
                                   scrollable_columns=scrollable_columns)
        self.hostname = EditField(hostname_area,
                                  window=self.center_win,
                                  text=self.sys_info.hostname,
                                  validate=hostname_is_valid,
                                  error_win=self.main_win.error_line)
        self.hostname.item_key = None

        # Display network configuration part of screen only if applicable.
        if self.configure_network:
            y_loc += 3

            # If there are no configurable links, there is no point to let
            # user select type of network configuration.
            if not self.have_nic:
                # Inform user that no network interfaces were found
                # on the system.
                # If this is the case of non-global zone with all links
                # mandated from global zone, be more specific.
                if self.nic_info.type == NetworkInfo.FROMGZ:
                    self.center_win.add_paragraph(
                        NetworkTypeScreen.ALL_NICS_FROMGZ, y_loc, 1)
                else:
                    self.center_win.add_paragraph(
                        NetworkTypeScreen.NO_NICS_FOUND, y_loc, 1)

                self.main_win.do_update()
                activate = self.net_type_dict.get(self.nic_info.type,
                                                  self.hostname)
                self.center_win.activate_object(activate)
                return

        self.main_win.do_update()
        activate = self.net_type_dict.get(self.nic_info.type, self.hostname)
        self.center_win.activate_object(activate)
示例#30
0
文件: iscsi.py 项目: alhazred/caiman
class IscsiScreen(BaseScreen):
    """ Allow the user to specify parameters for iSCSI LUNs
    """

    HEADER_TEXT = _("iSCSI Discovery")
    INTRO = _("The installer needs additional information for iSCSI LUN "
              "discovery")
    FOUND_DHCP_LABEL = _("DHCP has iSCSI parameters defined for this host")
    TARGET_IP_LABEL = _("Target IP:")
    TARGET_PORT_LABEL = _("Port:")
    TARGET_LUN_LABEL = _("Target LUN:")
    TARGET_NAME_LABEL = _("Target Name:")
    INITIATOR_NAME_LABEL = _("Initiator Name:")
    USE_CHAP_LABEL = _("Use CHAP:")
    CHAP_NAME_LABEL = _("CHAP Name:")
    CHAP_PASSWORD_LABEL = _("CHAP Password:"******"Required Field")
    USE_CHAP_LABEL = _("If using CHAP for authentication")
    MAPPING_LUN_LABEL = _("Mapping iSCSI LUN...")
    MAPPING_TARGET_LABEL = _("Mapping iSCSI Target...")
    ISCSI_BOOT_LABEL = _("iSCSI boot enabled - Initiator Name set in BIOS")

    # error strings
    MISSING_TARGET_IP = _("Target IP address not provided")
    INVALID_TARGET_IP = _("Invalid Target IP address")
    INVALID_INITIATOR_IQN = _("Invalid Initiator IQN string")
    INVALID_TARGET_IQN = _("Invalid Target IQN string")
    CHAP_USERNAME_MISSING = _("CHAP username not specified")
    CHAP_PASSWORD_MISSING = _("CHAP password not specified")
    CHAP_PASSWORD_TOO_SHORT = _("CHAP password must be between 12 and 16 "
                                "characters")
    UNABLE_TO_MAP = _("Unable to map iSCSI LUN: ")

    HELP_DATA = (TUI_HELP + "/%s/iscsi.txt", _("iSCSI"))

    MAX_IP_LEN = 15
    MAX_LUN_LEN = 4
    MAX_PORT_LEN = 5
    MAX_NAME_LEN = 223
    CHAP_LEN = 16
    ITEM_OFFSET = 2
    DEAD_ZONE = 3
    REQUIRED_MARK = EditField.ASTERISK_CHAR

    def __init__(self, main_win):
        """ screen object containing iSCSI criteria objects
        """

        global LOGGER
        LOGGER = logging.getLogger(INSTALL_LOGGER_NAME)
        super(IscsiScreen, self).__init__(main_win)

        self.target_ip = None
        self.target_port = None
        self.target_lun = None
        self.target_name = None
        self._initiator_name = None
        self.chap_name = None
        self.chap_password = None

        self.full_win_width = self.win_size_x - IscsiScreen.DEAD_ZONE
        self.half_win_width = (self.win_size_x - IscsiScreen.DEAD_ZONE) / 2

        self.default_edit = WindowArea(y_loc=0, lines=1,
                                       columns=IscsiScreen.CHAP_LEN)
        self.right_edit = WindowArea(y_loc=0, lines=1,
                                     columns=IscsiScreen.MAX_PORT_LEN)
        self.name_edit = WindowArea(y_loc=0, lines=1,
            scrollable_columns=IscsiScreen.MAX_NAME_LEN + 1)
        self.chap_edit = WindowArea(y_loc=0, lines=1,
                                    columns=IscsiScreen.CHAP_LEN)
        self.target_ip_list = None
        self.target_ip_edit = None
        self.target_port_list = None
        self.target_port_edit = None
        self.target_lun_list = None
        self.target_lun_edit = None
        self.target_name_edit = None
        self.initiator_name_edit = None
        self.chap_name_edit = None
        self.chap_password_edit = None

        # key map dictionary for Target entries
        self.add_keys = {curses.KEY_LEFT: self.on_arrow_key,
                         curses.KEY_RIGHT: self.on_arrow_key,
                         curses.KEY_DOWN: self.on_arrow_key,
                         curses.KEY_UP: self.on_arrow_key}

        self.iscsi_obj = None
        self.is_iscsiboot = is_iscsiboot()

    def on_arrow_key(self, input_key):
        """ override the default behavior of the arrow keys for specific
        EditFields.
        """

        # get the active object
        active = self.center_win.get_active_object()

        # only allow the right arrow to move from IP to Port
        if input_key == curses.KEY_RIGHT and active is self.target_ip_list:
            self.center_win.activate_object(self.target_port_list)
            return None

        # only allow the left arrow to move from Port to IP
        elif input_key == curses.KEY_LEFT and active is self.target_port_list:
            self.center_win.activate_object(self.target_ip_list)
            return None

        # override the default behavior for the up and down arrows to skip the
        # Port field if moving from IP to LUN
        elif input_key == curses.KEY_DOWN and active is self.target_ip_list:
            self.center_win.activate_object(self.target_lun_list)
            return None
        elif input_key == curses.KEY_UP and active is self.target_lun_list:
            self.center_win.activate_object(self.target_ip_list)
            return None

        return input_key

    def check_dhcp(self):
        """ query the DHCP server for the Rootpath string.  If present, update
        the proper attributes.
        """

        dhcp_params = Iscsi.get_dhcp()
        if dhcp_params is not None:
            self.target_ip,
            self.target_port,
            self.target_lun,
            self.target_name = dhcp_params
            return True
        return False

    @property
    def initiator_name(self):
        """ property to return the initiator name
        """

        if self._initiator_name is None:
            cmd = [ISCSIADM, "list", "initiator-node"]
            p = run(cmd)
            for line in p.stdout.splitlines():
                if line.startswith("Initiator node name:"):
                    self._initiator_name = line.split(": ")[1]
        return self._initiator_name

    @initiator_name.setter
    def initiator_name(self, name):
        """ property setter for _initiator_name
        """

        self._initiator_name = name

    def _show(self):
        """ create the screen to collect user input
        """

        # look in the DOC for an Iscsi object
        eng = InstallEngine.get_instance()
        iscsi_obj = eng.doc.volatile.get_children(name=ISCSI_LABEL,
                                                  class_type=Iscsi)

        # If there's no iscsi object in the DOC, skip this screen
        if not iscsi_obj:
            raise SkipException
        else:
            self.iscsi_obj = iscsi_obj[0]
            LOGGER.debug("show Iscsi object:  %s" % str(self.iscsi_obj))

        y_loc = 1
        self.center_win.add_paragraph(IscsiScreen.INTRO, start_y=y_loc)

        # look to see if DHCP is providing information
        if self.check_dhcp():
            y_loc += 2
            self.center_win.add_paragraph(IscsiScreen.FOUND_DHCP_LABEL,
                                          start_y=y_loc)

        # Target IP
        y_loc += 2

        # Mark this field required
        self.center_win.window.addch(y_loc, 2, IscsiScreen.REQUIRED_MARK,
            self.center_win.color_theme.inactive)

        edit_start = textwidth(IscsiScreen.TARGET_IP_LABEL) + \
                     IscsiScreen.ITEM_OFFSET
        ip_area = WindowArea(y_loc=y_loc, x_loc=1, lines=1,
            columns=edit_start + IscsiScreen.MAX_IP_LEN + 1)

        self.target_ip_list = ListItem(ip_area,
                                       window=self.center_win,
                                       text=IscsiScreen.TARGET_IP_LABEL)
        self.target_ip_list.key_dict.update(self.add_keys)

        self.default_edit.x_loc = edit_start
        self.default_edit.columns = IscsiScreen.MAX_IP_LEN + 1
        self.target_ip_edit = EditField(self.default_edit,
                                        window=self.target_ip_list,
                                        validate=incremental_validate_ip,
                                        error_win=self.main_win.error_line)
        self.target_ip_edit.key_dict.update(self.add_keys)
        if self.target_ip is not None:
            self.target_ip_edit.set_text(self.target_ip)

        # Target Port
        edit_start = ip_area.x_loc + \
                     textwidth(IscsiScreen.TARGET_PORT_LABEL) + \
                     IscsiScreen.ITEM_OFFSET
        port_area = WindowArea(y_loc=y_loc,
            x_loc=self.half_win_width + IscsiScreen.DEAD_ZONE,
            lines=1, columns=edit_start + IscsiScreen.MAX_PORT_LEN + 1)

        self.target_port_list = ListItem(port_area,
                                         window=self.center_win,
                                         text=IscsiScreen.TARGET_PORT_LABEL)
        self.target_port_list.key_dict.update(self.add_keys)

        self.right_edit.x_loc = edit_start
        self.right_edit.columns = IscsiScreen.MAX_PORT_LEN + 1
        self.target_port_edit = EditField(self.right_edit,
                                          window=self.target_port_list,
                                          validate=incremental_validate_digits,
                                          error_win=self.main_win.error_line,
                                          text=Iscsi.ISCSI_DEFAULT_PORT)
        self.target_port_edit.key_dict.update(self.add_keys)
        if self.target_port is not None:
            self.target_port_edit.set_text(self.target_port)

        # Target LUN
        y_loc += 1

        edit_start = textwidth(IscsiScreen.TARGET_LUN_LABEL) + \
                     IscsiScreen.ITEM_OFFSET
        lun_area = WindowArea(y_loc=y_loc, x_loc=1, lines=1,
            columns=edit_start + IscsiScreen.MAX_LUN_LEN + 1)

        self.target_lun_list = ListItem(lun_area,
                                        window=self.center_win,
                                        text=IscsiScreen.TARGET_LUN_LABEL)
        self.target_lun_list.key_dict.update(self.add_keys)

        self.default_edit.x_loc = edit_start
        self.default_edit.columns = IscsiScreen.MAX_LUN_LEN + 1
        self.target_lun_edit = EditField(self.default_edit,
                                         window=self.target_lun_list,
                                         validate=incremental_validate_hex,
                                         error_win=self.main_win.error_line)
        self.target_lun_edit.key_dict.update(self.add_keys)
        if self.target_lun is not None:
            self.target_lun_edit.set_text(self.target_lun)

        # Target Name
        y_loc += 2
        name_area = WindowArea(y_loc=y_loc, x_loc=1, lines=1,
            columns=self.full_win_width)

        name_area.y_loc = y_loc
        target_name_list = ListItem(name_area, window=self.center_win,
                                    text=IscsiScreen.TARGET_NAME_LABEL)

        self.name_edit.x_loc = textwidth(IscsiScreen.TARGET_NAME_LABEL) + \
                                         IscsiScreen.ITEM_OFFSET
        self.name_edit.columns = self.full_win_width - \
                                 textwidth(IscsiScreen.TARGET_NAME_LABEL) - \
                                 IscsiScreen.ITEM_OFFSET
        self.target_name_edit = EditField(self.name_edit,
                                          window=target_name_list)
        if self.target_name is not None:
            self.target_name_edit.set_text(self.target_name)

        # Horizontal line
        y_loc += 1
        self.center_win.window.hline(y_loc, 3, curses.ACS_HLINE,
                                     self.full_win_width)

        # Initiator Name
        y_loc += 1

        if self.is_iscsiboot:
            # the system BIOS is configured for iSCSI boot.  This means the
            # user will be unable to change the initiator-name.  Display the
            # name, but don't allow it to be changed.
            text = "%s  %s" % \
                (IscsiScreen.INITIATOR_NAME_LABEL, self.initiator_name)
            self.center_win.add_text(text, start_y=y_loc, start_x=1)
            y_loc += 1
            self.center_win.add_text(IscsiScreen.ISCSI_BOOT_LABEL,
                                     start_y=y_loc, start_x=1)
        else:
            # display the edit field as normal
            name_area.y_loc = y_loc
            initiator_name_list = ListItem(name_area, window=self.center_win,
                text=IscsiScreen.INITIATOR_NAME_LABEL)

            self.name_edit.x_loc = \
                textwidth(IscsiScreen.INITIATOR_NAME_LABEL) + \
                IscsiScreen.ITEM_OFFSET
            self.name_edit.columns = self.full_win_width - \
                textwidth(IscsiScreen.INITIATOR_NAME_LABEL) - \
                IscsiScreen.ITEM_OFFSET
            self.initiator_name_edit = EditField(self.name_edit,
                                                 window=initiator_name_list,
                                                 text=self.initiator_name)

        y_loc += 2
        self.center_win.add_text(IscsiScreen.USE_CHAP_LABEL, y_loc, 1)

        # CHAP username
        y_loc += 1
        edit_start = textwidth(IscsiScreen.CHAP_NAME_LABEL) + \
                               IscsiScreen.ITEM_OFFSET
        chapname_area = WindowArea(y_loc=y_loc, x_loc=15, lines=1,
            columns=edit_start + IscsiScreen.CHAP_LEN)

        chap_name_list = ListItem(chapname_area, window=self.center_win,
                                  text=IscsiScreen.CHAP_NAME_LABEL)

        self.chap_edit.x_loc = edit_start
        self.chap_edit.columns = IscsiScreen.CHAP_LEN + 1
        self.chap_edit.scrollable_columns = IscsiScreen.MAX_NAME_LEN + 1
        self.chap_name_edit = EditField(self.chap_edit, window=chap_name_list)
        if self.chap_name is not None:
            self.chap_name_edit.set_text(self.chap_name)

        # CHAP password
        y_loc += 1
        edit_start = textwidth(IscsiScreen.CHAP_PASSWORD_LABEL) + \
                     IscsiScreen.ITEM_OFFSET
        chapname_area.y_loc = y_loc
        chap_password_list = ListItem(chapname_area, window=self.center_win,
                                      text=IscsiScreen.CHAP_PASSWORD_LABEL)

        self.chap_edit.x_loc = textwidth(IscsiScreen.CHAP_PASSWORD_LABEL) + \
                               IscsiScreen.ITEM_OFFSET
        self.chap_edit.scrollable_columns = None
        self.chap_password_edit = PasswordField(self.chap_edit,
                                                window=chap_password_list)
        if self.chap_password is not None:
            self.chap_password_edit.set_text(self.chap_password)

        # Legend
        y_loc += 2
        self.center_win.window.addch(y_loc, 1, IscsiScreen.REQUIRED_MARK,
            self.center_win.color_theme.inactive)
        self.center_win.add_text(IscsiScreen.REQUIRED_FIELD_LABEL, y_loc, 1)

        self.main_win.do_update()
        self.center_win.activate_object()

    def on_change_screen(self):
        """ save the user's choices in case they return to this screen
        """

        self.target_ip = self.target_ip_edit.get_text()
        self.target_port = self.target_port_edit.get_text()
        self.target_lun = self.target_lun_edit.get_text()
        self.target_name = self.target_name_edit.get_text()
        if not self.is_iscsiboot:
            self.initiator_name = self.initiator_name_edit.get_text()
        self.chap_name = self.chap_name_edit.get_text()
        self.chap_password = self.chap_password_edit.get_text()

    def validate(self):
        """ validate the iSCSI attributes before continuing to disk selection.
        """

        target_ip = self.target_ip_edit.get_text()
        target_lun = self.target_lun_edit.get_text()
        target_port = self.target_port_edit.get_text()
        target_name = self.target_name_edit.get_text()
        if not self.is_iscsiboot:
            initiator_name = self.initiator_name_edit.get_text()
        chap_name = self.chap_name_edit.get_text()
        chap_password = self.chap_password_edit.get_text()

        # validate the target IP
        if not target_ip:
            raise UIMessage(IscsiScreen.MISSING_TARGET_IP)
        else:
            try:
                IPAddress.convert_address(target_ip)
            except ValueError as error:
                raise UIMessage("%s: %s" % \
                    (IscsiScreen.INVALID_TARGET_IP, str(error)))

        # validate the IQN strings (by default re.match only matches at the
        # beginning of a string)
        if not self.is_iscsiboot and initiator_name:
            if IQN_RE.match(initiator_name) is None:
                raise UIMessage(IscsiScreen.INVALID_INITIATOR_IQN)

        if target_name:
            if IQN_RE.match(target_name) is None:
                raise UIMessage(IscsiScreen.INVALID_TARGET_IQN)

        # validate that both CHAP username and password were specified (or not
        # at all)
        if chap_name and not chap_password:
            raise UIMessage(IscsiScreen.CHAP_PASSWORD_MISSING)
        if chap_password and not chap_name:
            raise UIMessage(IscsiScreen.CHAP_USERNAME_MISSING)

        # validate the CHAP password
        if chap_password:
            if not 12 <= len(chap_password) <= 16:
                raise UIMessage(IscsiScreen.CHAP_PASSWORD_TOO_SHORT)

        # Update the Iscsi DOC object
        self.iscsi_obj.target_ip = target_ip

        # force target_lun back to None if the user comes back and removes the
        # LUN entry from the screen
        if target_lun:
            self.iscsi_obj.target_lun = target_lun
        else:
            self.iscsi_obj.target_lun = None

        if target_name:
            self.iscsi_obj.target_name = target_name
        if target_port:
            self.iscsi_obj.target_port = target_port

        if not self.is_iscsiboot and initiator_name:
            self.iscsi_obj.initiator_name = initiator_name

        if chap_name:
            self.iscsi_obj.chap_name = chap_name
        if chap_password:
            self.iscsi_obj.chap_password = chap_password

        # attempt to connect to the LUN
        if target_lun:
            self.main_win.error_line.display_err(IscsiScreen.MAPPING_LUN_LABEL)
        else:
            self.main_win.error_line.display_err(
                IscsiScreen.MAPPING_TARGET_LABEL)

        try:
            self.iscsi_obj.setup_iscsi()
            LOGGER.debug("Iscsi object:  %s" % str(self.iscsi_obj))
        except (CalledProcessError, RuntimeError) as err:
            # remove the iSCSI configuration since it's invalid
            try:
                self.iscsi_obj.teardown()
            except CalledProcessError:
                # ignore any errors
                pass
            raise UIMessage("%s %s" % (IscsiScreen.UNABLE_TO_MAP, str(err)))
示例#31
0
class NSDomain(NameService):

    HEADER_TEXT = _("Domain Name")
    HELP_DATA = (SCI_HELP + "/%s/domain.txt", HEADER_TEXT)

    def __init__(self, main_win, screen=None):
        super(NSDomain, self).__init__(main_win)
        self.intro = \
                _("Specify the domain for the NIS or LDAP name server. "
                  "Use the domain name's exact capitalization and "
                  "punctuation.")
        self.title = _("Domain Name:")

    def _show(self):
        ''' show domain '''
        super(NSDomain, self)._show()
        if not _has_name_service():
            raise SkipException
        if not self.nameservice.nameservice:
            raise SkipException
        y_loc = self._paint_opening()
        cols = min(MAXDOMAINLEN + 1,
                   self.win_size_x - textwidth(self.title) - INDENT - 1)
        self.center_win.add_text(self.title, y_loc, INDENT)
        area = WindowArea(1, cols, y_loc, textwidth(self.title) + INDENT + 1,
                          scrollable_columns=MAXDOMAINLEN + 1)
        self.domain = EditField(area, window=self.center_win,
                                text=self.nameservice.domain,
                                validate=incremental_validate_domain,
                                error_win=self.main_win.error_line)
        self.main_win.do_update()
        self.center_win.activate_object(self.domain)

    def validate(self):
        validate_domain(self.domain.get_text(), allow_empty=False)

    def on_change_screen(self):
        ns = self.nameservice
        new_domain = self.domain.get_text()
        if ns.domain != new_domain or \
                (ns.nameservice == 'LDAP' and not ns.ldap_search_base):
            ns.domain = new_domain
            # default in LDAP-formatted values for domain
            if self.nameservice.nameservice == 'LDAP':
                ldapdom = _convert_to_ldap_domain(new_domain)
                # default in search base from domain
                if not ns.ldap_search_base or \
                        not ns.ldap_search_base.startswith(ldapdom):
                    ns.ldap_search_base = ldapdom
                # base DN on search base
                if ns.ldap_pb_dn:
                    # update DN with any changes in search_base from user
                    fixedbase = _ldap_domain_fixup(ns.ldap_pb_dn,
                            ns.ldap_search_base)
                    if fixedbase:
                        # user changed search base, update DN
                        ns.ldap_pb_dn = fixedbase
                else:
                    # provide probable DN default
                    ns.ldap_pb_dn = 'cn=proxyagent,ou=profile,' + \
                            ns.ldap_search_base
示例#32
0
    def _show(self):
        '''Display the user name, real name, and password fields'''
        
        sc_profile = solaris_install.sysconfig.profile.from_engine()

        #
        # Create UserInfo instances holding information about root and user
        # accounts.
        #
        if sc_profile.users is None:
            #
            # Assume root is a normal account. It will be changed to a role
            # if the user account is created.
            #
            root = UserInfo(login_name="root", is_role=False)

            #
            # Initialize attributes of user account which can't be configured
            # on screens.
            #
            user = UserInfo(gid=10, shell="/usr/bin/bash", roles="root",
                            profiles="System Administrator",
                            sudoers="ALL=(ALL) ALL")
            sc_profile.users = UserInfoContainer(root, user)

        self.root = sc_profile.users.root
        self.user = sc_profile.users.user
        
        LOGGER.debug("Root: %s", self.root)
        LOGGER.debug("User: %s", self.user)
        
        root_set = (self.root.passlen != 0)
        user_set = (self.user.passlen != 0)
        
        y_loc = 1
        
        if self.show_user_account:
            intro_text = UserScreen.INTRO_SHOW_USER
        else:
            intro_text = UserScreen.INTRO_HIDE_USER

        self.center_win.add_paragraph(intro_text, y_loc, 1,
                                      y_loc + 2, self.win_size_x - 1)
        
        y_loc += 3
        self.center_win.add_text(UserScreen.ROOT_TEXT, y_loc, 1,
                                 self.win_size_x - 1)
        
        y_loc += 2
        self.error_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        self.root_pass_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.root_pass_list = ListItem(self.list_area, window=self.center_win,
                                       text=UserScreen.ROOT_LABEL)
        self.root_pass_edit = PasswordField(self.edit_area,
                                            window=self.root_pass_list,
                                            error_win=self.root_pass_err,
                                            fill=root_set)
        
        y_loc += 1
        self.error_area.y_loc = y_loc
        self.list_area.y_loc = y_loc
        self.root_confirm_err = ErrorWindow(self.error_area,
                                            window=self.center_win)
        self.root_confirm_list = ListItem(self.list_area,
                                          window=self.center_win,
                                          text=UserScreen.CONFIRM_LABEL)
        self.root_confirm_edit = PasswordField(self.edit_area,
                                               window=self.root_confirm_list,
                                               fill=root_set,
                                               on_exit=pass_match,
                                               error_win=self.root_confirm_err)
        rc_edit_kwargs = {"linked_win": self.root_pass_edit}
        self.root_confirm_edit.on_exit_kwargs = rc_edit_kwargs

        # User account disabled, do not display related widgets.
        if not self.show_user_account:
            self.main_win.do_update()
            self.center_win.activate_object(self.root_pass_list)
            return

        y_loc += 2
        self.center_win.add_text(UserScreen.USER_TEXT, y_loc, 1,
                                 self.win_size_x - 1)
        
        y_loc += 2
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.real_name_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.real_name_list = ListItem(self.list_area, window=self.center_win,
                                       text=UserScreen.NAME_LABEL)
        self.real_name_edit = EditField(self.edit_area,
                                        window=self.real_name_list,
                                        error_win=self.real_name_err,
                                        text=self.user.real_name)
        
        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.username_err = ErrorWindow(self.error_area,
                                        window=self.center_win)
        self.username_list = ListItem(self.list_area,
                                      window=self.center_win,
                                      text=UserScreen.USERNAME_LABEL)
        self.username_edit = EditField(self.username_edit_area,
                                       window=self.username_list,
                                       validate=username_valid,
                                       error_win=self.username_err,
                                       on_exit=login_valid,
                                       text=self.user.login_name)
        
        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.user_pass_err = ErrorWindow(self.error_area,
                                         window=self.center_win)
        self.user_pass_list = ListItem(self.list_area, window=self.center_win,
                                       text=UserScreen.USER_PASS_LABEL)
        self.user_pass_edit = PasswordField(self.edit_area,
                                            window=self.user_pass_list,
                                            error_win=self.user_pass_err,
                                            fill=user_set)
        
        y_loc += 1
        self.list_area.y_loc = y_loc
        self.error_area.y_loc = y_loc
        self.user_confirm_err = ErrorWindow(self.error_area,
                                            window=self.center_win)
        self.user_confirm_list = ListItem(self.list_area,
                                          window=self.center_win,
                                          text=UserScreen.CONFIRM_LABEL)
        self.user_confirm_edit = PasswordField(self.edit_area,
                                               window=self.user_confirm_list,
                                               on_exit=pass_match,
                                               error_win=self.user_confirm_err,
                                               fill=user_set)
        uc_edit_kwargs = {"linked_win": self.user_pass_edit}
        self.user_confirm_edit.on_exit_kwargs = uc_edit_kwargs
        
        self.main_win.do_update()
        self.center_win.activate_object(self.root_pass_list)