Пример #1
0
    def usage(self):
        #if no interfaces at all - display error and go to advanced
        if len(self._get_filtered_ifnames()) == 0:
            self.console.msgbox("Error", "No network adapters detected")
            return "usage"

        #if interfaces but no default - display error and go to networking
        ifname = self._get_default_nic()
        if not ifname:
            self.console.msgbox("Error", "Networking is not yet configured")
            return "networking"

        #display usage
        key = CONFIG.get("appliance_key", "")
        if not key: key = "NOT SET, PLEASE CONFIGURE"
        
        t = file(get_configuration_path("usage.txt"), 'r').read()
        text = Template(t).substitute(
            hostname=ifutil.get_hostname().capitalize(),
            appname=self.appname,
            ipaddr=ifutil.get_ipconf(ifname)[0],
            key=key
        )

        retcode, choice = self.console.menu("Usage", text, self._get_advmenu(), no_cancel=True)
        if retcode is not self.OK:
            self.running = False

        fn = choice.lower()
        fn = "_adv_" + fn.replace(" ", "_")
        return fn
Пример #2
0
    def usage(self):
        # if no interfaces at all - display error and go to advanced
        if len(self._get_filtered_ifnames()) == 0:
            self.console.msgbox("Error", "No network adapters detected")
            return "advanced"

        # if interfaces but no default - display error and go to networking
        ifname = self._get_default_nic()
        if not ifname:
            self.console.msgbox("Error", "Networking is not yet configured")
            return "networking"

        # display usage
        ipaddr = ifutil.get_ipconf(ifname)[0]
        hostname = netinfo.get_hostname().upper()

        try:
            # backwards compatible - use usage.txt if it exists
            t = file(conf.path("usage.txt"), "r").read()
            text = Template(t).substitute(hostname=hostname, ipaddr=ipaddr)

            retcode = self.console.msgbox("Usage", text, button_label="Advanced Menu")
        except conf.Error:
            t = file(conf.path("services.txt"), "r").read().rstrip()
            text = Template(t).substitute(ipaddr=ipaddr)

            retcode = self.console.msgbox("%s appliance services" % hostname, text, button_label="Advanced Menu")

        if retcode is not self.OK:
            self.running = False

        return "advanced"
    def _get_ifconfmenu(self, ifname):
        menu = []
        menu.append(("DHCP", "Configure networking automatically"))
        menu.append(("StaticIP", "Configure networking manually"))

        if not ifname == self._get_default_nic() and \
           len(self._get_filtered_ifnames()) > 1 and \
           ifutil.get_ipconf(ifname)[0] is not None:
            menu.append(("Default", "Show this adapter's IP address in Usage"))

        return menu
Пример #4
0
    def _get_ifconfmenu(self, ifname):
        menu = []
        menu.append(("DHCP", "Configure networking automatically"))
        menu.append(("StaticIP", "Configure networking manually"))

        if not ifname == self._get_default_nic() and \
           len(self._get_filtered_ifnames()) > 1 and \
           ifutil.get_ipconf(ifname)[0] is not None:
            menu.append(("Default", "Show this adapter's IP address in Usage"))

        return menu
Пример #5
0
 def _adv_view_settings(self):
     ip = ifutil.get_ipconf(self._get_default_nic())[0]
     
     agg_url = CONFIG.get("aggregator", "")
     if not agg_url: agg_url = "NOT SET, PLEASE CONFIGURE"
     port = CONFIG.get("remote_agent_port", "")
     if not port: port = "6000"
     agent_address = "%s:%s" % (ip, port)
     
     t = file(get_configuration_path("info.txt"), 'r').read()
     text = Template(t).substitute(
         agent_address=agent_address,
         agg_url=agg_url
     )
     choice = self.console.msgbox("View Settings", text)
     return "usage"
    def _get_netmenu(self):
        menu = []
        for ifname in self._get_filtered_ifnames():
            addr = ifutil.get_ipconf(ifname)[0]
            ifmethod = ifutil.get_ifmethod(ifname)

            if addr:
                desc = addr
                if ifmethod:
                    desc += " (%s)" % ifmethod

                if ifname == self._get_default_nic():
                    desc += " [*]"
            else:
                desc = "not configured"

            menu.append((ifname, desc))

        return menu
Пример #7
0
    def _get_netmenu(self):
        menu = []
        for ifname in self._get_filtered_ifnames():
            addr = ifutil.get_ipconf(ifname)[0]
            ifmethod = ifutil.get_ifmethod(ifname)

            if addr:
                desc = addr
                if ifmethod:
                    desc += " (%s)" % ifmethod

                if ifname == self._get_default_nic():
                    desc += " [*]"
            else:
                desc = "not configured"

            menu.append((ifname, desc))

        return menu
Пример #8
0
    def _get_ifconftext(self, ifname):
        addr, netmask, gateway, nameservers = ifutil.get_ipconf(ifname)
        if addr is None:
            return "Network adapter is not configured\n"

        text =  "IP Address:      %s\n" % addr
        text += "Netmask:         %s\n" % netmask
        text += "Default Gateway: %s\n" % gateway
        text += "Name Server(s):  %s\n\n" % " ".join(nameservers)

        ifmethod = ifutil.get_ifmethod(ifname)
        if ifmethod:
            text += "Networking configuration method: %s\n" % ifmethod

        if len(self._get_filtered_ifnames()) > 1:
            text += "Is this adapter's IP address displayed in Usage: "
            if ifname == self._get_default_nic():
                text += "yes\n"
            else:
                text += "no\n"

        return text
    def _get_ifconftext(self, ifname):
        addr, netmask, gateway, nameservers = ifutil.get_ipconf(ifname)
        if addr is None:
            return "Network adapter is not configured\n"
        
        text =  "IP Address:      %s\n" % addr
        text += "Netmask:         %s\n" % netmask
        text += "Default Gateway: %s\n" % gateway
        text += "Name Server(s):  %s\n\n" % " ".join(nameservers)

        ifmethod = ifutil.get_ifmethod(ifname)
        if ifmethod:
            text += "Networking configuration method: %s\n" % ifmethod

        if len(self._get_filtered_ifnames()) > 1:
            text += "Is this adapter's IP address displayed in Usage: "
            if ifname == self._get_default_nic():
                text += "yes\n"
            else:
                text += "no\n"

        return text
Пример #10
0
    def _get_default_nic(cls):
        def _validip(ifname):
            ip = ifutil.get_ipconf(ifname)[0]
            if ip and not ip.startswith('169'):
                return True
            return False

        selected_ifname = None
        default_nic = ConsoleConf().default_nic
        
        if default_nic and _validip(ifname): selected_ifname = default_nic
        else:
            for ifname in cls._get_filtered_ifnames():
                if _validip(ifname): selected_ifname = ifname
            
        if selected_ifname:
            ip = ifutil.get_ipconf(selected_ifname)[0]
            if selected_ifname != CONFIG["nic"] and ip != CONFIG["ip"]:
                CONFIG["nic"] = ifname
                CONFIG["ip"] = ip
                save_config()

        return selected_ifname
Пример #11
0
    def get_interface_config(self, s_address = None, s_netmask = None, s_gateway = None, s_nameserver1 = None, s_nameserver2 = None):
        ''' Get's the configuration for the primary interface '''
        address, netmask, gateway, nameservers = get_ipconf(self.interface)
        
        if s_nameserver2: nameservers.insert(0, s_nameserver2)
        if s_nameserver1: nameservers.insert(0, s_nameserver1)

        nameservers = nameservers[:2] + ['']*(2 - len(nameservers))
        option_nameservers = []

        for nameserv in xrange(2):
            option_nameservers.append(('Nameserver {}:'.format(nameserv+1), nameservers[nameserv], 15))

        fields = [
            ('Address: ', s_address or address or '', 15),
            ('Netmask: ', s_netmask or netmask or '', 15),
            ('Gateway: ', s_gateway or gateway or '', 15),
        ] + option_nameservers
        
        
        code, (address, netmask, gateway, nameserver1, nameserver2) = self.dialog.form('Interface config', 'Interfaces configuration', fields = fields, no_cancel = True)
        nameservers = [nameserver1, nameserver2]
        self.if_data = address, netmask, gateway, nameservers
Пример #12
0
    def _ifconf_staticip(self):
        def _validate(addr, netmask, gateway, nameservers):
            """Validate Static IP form parameters. Returns an empty array on
               success, an array of strings describing errors otherwise"""

            errors = []
            if not addr:
                errors.append("No IP address provided")
            elif not ipaddr.is_legal_ip(addr):
                errors.append("Invalid IP address: %s" % addr)

            if not netmask:
                errors.append("No netmask provided")
            elif not ipaddr.is_legal_ip(netmask):
                errors.append("Invalid netmask: %s" % netmask)

            for nameserver in nameservers:
                if nameserver and not ipaddr.is_legal_ip(nameserver):
                    errors.append("Invalid nameserver: %s" % nameserver)

            if len(nameservers) != len(set(nameservers)):
                errors.append("Duplicate nameservers specified")

            if errors:
                return errors

            if gateway:
                if not ipaddr.is_legal_ip(gateway):
                    return ["Invalid gateway: %s" % gateway]
                else:
                    iprange = ipaddr.IPRange(addr, netmask)
                    if gateway not in iprange:
                        return [
                            "Gateway (%s) not in IP range (%s)"
                            "" % (gateway, iprange)
                        ]
            return []

        warnings = []
        try:
            addr, netmask, gateway, nameservers = ifutil.get_ipconf(
                self.ifname, True)
        except CalledProcessError:
            warnings.append(
                '`route -n` returned non-0 exit code! (unable to get gateway)')
            addr, netmask, gateway, nameservers = None, None, '', []
        except netinfo.NetInfoError:
            warnings.append('failed to find default gateway!')
            addr, netmask, gateway, nameservers = None, None, '', []

        if addr is None:
            warnings.append('failed to assertain current address!')
            addr = ''
        if netmask is None:
            warnings.append('failed to assertain current netmask!')
            netmask = ''

        if warnings:
            warnings.append('\nWill leave relevant fields blank')

        if warnings:
            self.console.msgbox("Warning", '\n'.join(warnings))

        input = [addr, netmask, gateway]
        input.extend(nameservers)

        # include minimum 2 nameserver fields and 1 blank one
        if len(input) < 4:
            input.append('')

        if input[-1]:
            input.append('')

        field_width = 30
        field_limit = 15

        while 1:
            fields = [
                ("IP Address", input[0], field_width, field_limit),
                ("Netmask", input[1], field_width, field_limit),
                ("Default Gateway", input[2], field_width, field_limit),
            ]

            for i in range(len(input[3:])):
                fields.append(
                    ("Name Server", input[3 + i], field_width, field_limit))

            fields = format_fields(fields)
            text = "Static IP configuration (%s)" % self.ifname
            retcode, input = self.console.form("Network settings", text,
                                               fields)

            if retcode is not self.OK:
                break

            # remove any whitespaces the user might of included
            for i in range(len(input)):
                input[i] = input[i].strip()

            # unconfigure the nic if all entries are empty
            if not input[0] and not input[1] and not input[2] and not input[3]:
                ifutil.unconfigure_if(self.ifname)
                break

            addr, netmask, gateway = input[:3]
            nameservers = input[3:]
            for i in range(nameservers.count('')):
                nameservers.remove('')

            err = _validate(addr, netmask, gateway, nameservers)
            if err:
                err = "\n".join(err)
            else:
                in_ssh = 'SSH_CONNECTION' in os.environ
                if not in_ssh or (in_ssh and self.console.yesno(
                        "Warning: Changing ip while an ssh session is active will"
                        " drop said ssh session!",
                        autosize=True) == self.OK):
                    err = ifutil.set_static(self.ifname, addr, netmask,
                                            gateway, nameservers)
                    if not err:
                        break
                else:
                    break

            self.console.msgbox("Error", err)

        return "ifconf"
Пример #13
0
    def _ifconf_staticip(self):
        def _validate(addr, netmask, gateway, nameservers):
            """Validate Static IP form parameters. Returns an empty array on
               success, an array of strings describing errors otherwise"""

            errors = []
            if not addr:
                errors.append("No IP address provided")
            elif not ipaddr.is_legal_ip(addr):
                errors.append("Invalid IP address: %s" % addr)

            if not netmask:
                errors.append("No netmask provided")
            elif not ipaddr.is_legal_ip(netmask):
                errors.append("Invalid netmask: %s" % netmask)

            for nameserver in nameservers:
                if nameserver and not ipaddr.is_legal_ip(nameserver):
                    errors.append("Invalid nameserver: %s" % nameserver)

            if len(nameservers) != len(set(nameservers)):
                errors.append("Duplicate nameservers specified")

            if errors:
                return errors

            if gateway:
                if not ipaddr.is_legal_ip(gateway):
                    return [ "Invalid gateway: %s" % gateway ]
                else:
                    iprange = ipaddr.IPRange(addr, netmask)
                    if gateway not in iprange:
                        return [ "Gateway (%s) not in IP range (%s)" % (gateway,
                                                                        iprange) ]
            return []

        addr, netmask, gateway, nameservers = ifutil.get_ipconf(self.ifname)
        input = [addr, netmask, gateway]
        input.extend(nameservers)

        # include minimum 2 nameserver fields and 1 blank one
        if len(input) < 4:
            input.append('')

        if input[-1]:
            input.append('')

        field_width = 30
        field_limit = 15

        while 1:
            fields = [
                ("IP Address", input[0], field_width, field_limit),
                ("Netmask", input[1], field_width, field_limit),
                ("Default Gateway", input[2], field_width, field_limit),
            ]

            for i in range(len(input[3:])):
                fields.append(("Name Server", input[3+i], field_width, field_limit))

            text = "Static IP configuration (%s)" % self.ifname
            retcode, input = self.console.form("Network settings", text, fields)

            if retcode is not self.OK:
                break

            # remove any whitespaces the user might of included
            for i in range(len(input)):
                input[i] = input[i].strip()

            # unconfigure the nic if all entries are empty
            if not input[0] and not input[1] and not input[2] and not input[3]:
                ifutil.unconfigure_if(self.ifname)
                break

            addr, netmask, gateway = input[:3]
            nameservers = input[3:]
            for i in range(nameservers.count('')):
                nameservers.remove('')

            err = _validate(addr, netmask, gateway, nameservers)
            if err:
                err = "\n".join(err)
            else:
                err = ifutil.set_static(self.ifname, addr, netmask,
                                        gateway, nameservers)
                if not err:
                    break

            self.console.msgbox("Error", err)

        return "ifconf"
Пример #14
0
            self.console.msgbox("Error", error)
            return "networking"

        #tklbam integration
        try:
            tklbam_status = executil.getoutput("tklbam-status --short")
        except executil.ExecError, e:
            if e.exitcode in (10, 11): #not initialized, no backups
                tklbam_status = e.output
            else:
                tklbam_status = ''

        #display usage
        ip_addr = self._get_public_ipaddr()
        if not ip_addr:
            ip_addr = ifutil.get_ipconf(ifname)[0]

        hostname = netinfo.get_hostname().upper()

        try:
            #backwards compatible - use usage.txt if it exists
            t = file(conf.path("usage.txt"), 'r').read()
            text = Template(t).substitute(hostname=hostname, ipaddr=ip_addr)

            retcode = self.console.msgbox("Usage", text,
                                          button_label=default_button_label)
        except conf.Error:
            t = file(conf.path("services.txt"), 'r').read().rstrip()
            text = Template(t).substitute(ipaddr=ip_addr)

            text += "\n\n%s\n\n" % tklbam_status
Пример #15
0
 def _validip(ifname):
     ip = ifutil.get_ipconf(ifname)[0]
     if ip and not ip.startswith('169'):
         return True
     return False
Пример #16
0
 def _validip(ifname):
     ip = ifutil.get_ipconf(ifname)[0]
     if ip and not ip.startswith('169'):
         return True
     return False
Пример #17
0
            self.console.msgbox("Error", error)
            return "networking"

        #tklbam integration
        try:
            tklbam_status = executil.getoutput("tklbam-status --short")
        except executil.ExecError, e:
            if e.exitcode in (10, 11): #not initialized, no backups
                tklbam_status = e.output
            else:
                tklbam_status = ''

        #display usage
        ip_addr = self._get_public_ipaddr()
        if not ip_addr:
            ip_addr = ifutil.get_ipconf(ifname)[0]

        hostname = netinfo.get_hostname().upper()

        try:
            #backwards compatible - use usage.txt if it exists
            t = file(conf.path("usage.txt"), 'r').read()
            text = Template(t).substitute(hostname=hostname, ipaddr=ip_addr)

            retcode = self.console.msgbox("Usage", text,
                                          button_label=default_button_label)
        except conf.Error:
            t = file(conf.path("services.txt"), 'r').read().rstrip()
            text = Template(t).substitute(ipaddr=ip_addr)

            text += "\n\n%s\n\n" % tklbam_status
Пример #18
0
class TurnkeyConsole:
    OK = 0
    CANCEL = 1

    def __init__(self, advanced_enabled=True):
        title = "Chitanka Configuration Console"
        self.width = 60
        self.height = 20

        self.console = Console(title, self.width, self.height)
        self.appname = "%s" % netinfo.get_hostname().upper()

        self.installer = Installer(path='/usr/bin/di-live')

        self.advanced_enabled = advanced_enabled

    @staticmethod
    def _get_filtered_ifnames():
        ifnames = []
        for ifname in netinfo.get_ifnames():
            if ifname.startswith(('lo', 'tap', 'br', 'tun', 'vmnet', 'wmaster')):
                continue
            ifnames.append(ifname)

        ifnames.sort()
        return ifnames

    @classmethod
    def _get_default_nic(cls):
        def _validip(ifname):
            ip = ifutil.get_ipconf(ifname)[0]
            if ip and not ip.startswith('169'):
                return True
            return False

        ifname = conf.Conf().default_nic
        if ifname and _validip(ifname):
            return ifname

        for ifname in cls._get_filtered_ifnames():
            if _validip(ifname):
                return ifname

        return None

    def _get_advmenu(self):
        items = []
        items.append(("Networking", "Configure appliance networking"))

        if self.installer.available:
            items.append(("Install", "Install to hard disk"))

        items.append(("Reboot", "Reboot the appliance"))
        items.append(("Shutdown", "Shutdown the appliance"))
        items.append(("Ping", "Test internet connection"))
        items.append(("Repair", "Repair and update Chitanka"))
        items.append(("UPDATENOW", "Get latest books"))
        #items.append(("Share", "Share content folder in LAN"))
        #items.append(("Noshare", "Remove shared content folder"))
        items.append(("Clear", "Clear free space"))

        return items



    def _get_netmenu(self):
        menu = []
        for ifname in self._get_filtered_ifnames():
            addr = ifutil.get_ipconf(ifname)[0]
            ifmethod = ifutil.get_ifmethod(ifname)

            if addr:
                desc = addr
                if ifmethod:
                    desc += " (%s)" % ifmethod

                if ifname == self._get_default_nic():
                    desc += " [*]"
            else:
                desc = "not configured"

            menu.append((ifname, desc))

        return menu

    def _get_ifconfmenu(self, ifname):
        menu = []
        menu.append(("DHCP", "Configure networking automatically"))
        menu.append(("StaticIP", "Configure networking manually"))

        if not ifname == self._get_default_nic() and \
           len(self._get_filtered_ifnames()) > 1 and \
           ifutil.get_ipconf(ifname)[0] is not None:
            menu.append(("Default", "Show this adapter's IP address in Usage"))

        return menu

    def _get_ifconftext(self, ifname):
        addr, netmask, gateway, nameservers = ifutil.get_ipconf(ifname)
        if addr is None:
            return "Network adapter is not configured\n"

        text =  "IP Address:      %s\n" % addr
        text += "Netmask:         %s\n" % netmask
        text += "Default Gateway: %s\n" % gateway
        text += "Name Server(s):  %s\n\n" % " ".join(nameservers)

        ifmethod = ifutil.get_ifmethod(ifname)
        if ifmethod:
            text += "Networking configuration method: %s\n" % ifmethod

        if len(self._get_filtered_ifnames()) > 1:
            text += "Is this adapter's IP address displayed in Usage: "
            if ifname == self._get_default_nic():
                text += "yes\n"
            else:
                text += "no\n"

        return text

    def usage(self):
        if self.advanced_enabled:
            default_button_label = "Advanced Menu"
            default_return_value = "advanced"

        else:
            default_button_label = "Quit"
            default_return_value = "quit"

        #if no interfaces at all - display error and go to advanced
        if len(self._get_filtered_ifnames()) == 0:
            error = "No network adapters detected"
            if not self.advanced_enabled:
                fatal(error)

            self.console.msgbox("Error", error)
            return "advanced"

        #if interfaces but no default - display error and go to networking
        ifname = self._get_default_nic()
        if not ifname:
            error = "Networking is not yet configured"
            if not self.advanced_enabled:
                fatal(error)

            self.console.msgbox("Error", error)
            return "networking"

        #tklbam integration
        try:
            tklbam_status = executil.getoutput("tklbam-status --short")
        except executil.ExecError, e:
            if e.exitcode in (10, 11): #not initialized, no backups
                tklbam_status = e.output
            else:
                tklbam_status = ''

        #display usage
        ipaddr = ifutil.get_ipconf(ifname)[0]
        hostname = netinfo.get_hostname().upper()

        try:
            #backwards compatible - use usage.txt if it exists
            t = file(conf.path("usage.txt"), 'r').read()
            text = Template(t).substitute(hostname=hostname, ipaddr=ipaddr)

            retcode = self.console.msgbox("Usage", text,
                                          button_label=default_button_label)
        except conf.Error:
            t = file(conf.path("services.txt"), 'r').read().rstrip()
            text = Template(t).substitute(ipaddr=ipaddr)


            retcode = self.console.msgbox("%s appliance services" % hostname,
                                          text, button_label=default_button_label)

        if retcode is not self.OK:
            self.running = False

        return default_return_value
Пример #19
0
    def usage(self):
        if self.advanced_enabled:
            default_button_label = "Advanced Menu"
            default_return_value = "advanced"
        else:
            default_button_label = "Quit"
            default_return_value = "quit"

        # if no interfaces at all - display error and go to advanced
        if len(self._get_filtered_ifnames()) == 0:
            error = "No network adapters detected"
            if not self.advanced_enabled:
                fatal(error)

            self.console.msgbox("Error", error)
            return "advanced"

        # if interfaces but no default - display error and go to networking
        ifname = self._get_default_nic()
        if not ifname:
            error = "Networking is not yet configured"
            if not self.advanced_enabled:
                fatal(error)

            self.console.msgbox("Error", error)
            return "networking"

        # tklbam integration
        tklbamstatus_cmd = subprocess.run(['which', 'tklbam-status'],
                                          stdout=PIPE,
                                          encoding='utf-8').stdout.strip()
        if tklbamstatus_cmd:
            tklbam_status = subprocess.run([tklbamstatus_cmd, "--short"],
                                           stdout=PIPE,
                                           encoding='utf-8').stdout
        else:
            tklbam_status = ("TKLBAM not found - please check that it's"
                             " installed.")

        # display usage
        ip_addr = self._get_public_ipaddr()
        if not ip_addr:
            ip_addr = ifutil.get_ipconf(ifname)[0]

        hostname = netinfo.get_hostname().upper()

        try:
            # backwards compatible - use usage.txt if it exists
            with open(conf.path("usage.txt"), 'r') as fob:
                t = fob.read()
            text = Template(t).substitute(hostname=hostname, ipaddr=ip_addr)

            retcode = self.console.msgbox("Usage",
                                          text,
                                          button_label=default_button_label)
        except conf.Error:
            try:
                with open(conf.path('services.txt'), 'r') as fob:
                    t = fob.read().rstrip()
            except:
                t = ""
            text = Template(t).substitute(ipaddr=ip_addr)

            text += "\n\n%s\n\n" % tklbam_status
            text += "\n" * (self.height - len(text.splitlines()) - 7)
            text += "         TurnKey Backups and Cloud Deployment\n"
            text += "             https://hub.turnkeylinux.org"

            retcode = self.console.msgbox("%s appliance services" % hostname,
                                          text,
                                          button_label=default_button_label)

        if retcode is not self.OK:
            self.running = False

        return default_return_value
Пример #20
0
    def _ifconf_staticip(self):
        def _validate(addr, netmask, gateway, nameservers):
            """Validate Static IP form parameters. Returns an empty array on
               success, an array of strings describing errors otherwise"""

            errors = []
            if not addr:
                errors.append("No IP address provided")
            elif not ipaddr.is_legal_ip(addr):
                errors.append("Invalid IP address: %s" % addr)

            if not netmask:
                errors.append("No netmask provided")
            elif not ipaddr.is_legal_ip(netmask):
                errors.append("Invalid netmask: %s" % netmask)

            for nameserver in nameservers:
                if nameserver and not ipaddr.is_legal_ip(nameserver):
                    errors.append("Invalid nameserver: %s" % nameserver)

            if len(nameservers) != len(set(nameservers)):
                errors.append("Duplicate nameservers specified")

            if errors:
                return errors

            if gateway:
                if not ipaddr.is_legal_ip(gateway):
                    return [ "Invalid gateway: %s" % gateway ]
                else:
                    iprange = ipaddr.IPRange(addr, netmask)
                    if gateway not in iprange:
                        return [ "Gateway (%s) not in IP range (%s)" % (gateway,
                                                                        iprange) ]
            return []

        addr, netmask, gateway, nameservers = ifutil.get_ipconf(self.ifname)
        input = [addr, netmask, gateway]
        input.extend(nameservers)

        # include minimum 2 nameserver fields and 1 blank one
        if len(input) < 4:
            input.append('')

        if input[-1]:
            input.append('')

        field_width = 30
        field_limit = 15

        while 1:
            fields = [
                ("IP Address", input[0], field_width, field_limit),
                ("Netmask", input[1], field_width, field_limit),
                ("Default Gateway", input[2], field_width, field_limit),
            ]

            for i in range(len(input[3:])):
                fields.append(("Name Server", input[3+i], field_width, field_limit))

            text = "Static IP configuration (%s)" % self.ifname
            retcode, input = self.console.form("Network settings", text, fields)

            if retcode is not self.OK:
                break

            # remove any whitespaces the user might of included
            for i in range(len(input)):
                input[i] = input[i].strip()

            # unconfigure the nic if all entries are empty
            if not input[0] and not input[1] and not input[2] and not input[3]:
                ifutil.unconfigure_if(self.ifname)
                break

            addr, netmask, gateway = input[:3]
            nameservers = input[3:]
            for i in range(nameservers.count('')):
                nameservers.remove('')

            err = _validate(addr, netmask, gateway, nameservers)
            if err:
                err = "\n".join(err)
            else:
                err = ifutil.set_static(self.ifname, addr, netmask,
                                        gateway, nameservers)
                if not err:
                    break

            self.console.msgbox("Error", err)

        return "ifconf"