From: Michael Tremer Date: Fri, 26 Dec 2008 22:26:11 +0000 (+0100) Subject: Added a rudimentary network support. X-Git-Tag: v3.0-alpha1~320 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0eef2c653bfc8355152e5bf9110d1d72d7c0b2a5;p=ipfire-3.x.git Added a rudimentary network support. This can set a hostname. --- diff --git a/src/pomona/dispatch.py b/src/pomona/dispatch.py index 36b4ec9b5..e2d8f6e31 100644 --- a/src/pomona/dispatch.py +++ b/src/pomona/dispatch.py @@ -57,7 +57,7 @@ installSteps = [ ("bootloadersetup", bootloaderSetupChoices, ), ("bootloader", ), ("bootloaderadvanced", ), - #("network", ), + ("network", ), ("timezone", ), ("accounts", ), #("reposetup", doRepoSetup, ), diff --git a/src/pomona/instdata.py b/src/pomona/instdata.py index 0e5e76b07..0c6c4199f 100644 --- a/src/pomona/instdata.py +++ b/src/pomona/instdata.py @@ -17,7 +17,7 @@ import os import string import language import keyboard -#import network +import network import timezone import fsset import bootloader @@ -40,7 +40,7 @@ class InstallData: # - The keyboard self.instClass = None -# self.network = network.Network() + self.network = network.Network() self.timezone = timezone.Timezone() self.timezone.setTimezoneInfo(self.instLanguage.getDefaultTimeZone()) self.users = None @@ -62,7 +62,7 @@ class InstallData: self.instLanguage.write(pomona.rootPath) self.keyboard.write(pomona.rootPath) #self.timezone.write(pomona.rootPath) - #self.network.write(pomona.rootPath) + self.network.write(pomona.rootPath) self.users = users.Users() diff --git a/src/pomona/network.py b/src/pomona/network.py new file mode 100644 index 000000000..aa9fc6429 --- /dev/null +++ b/src/pomona/network.py @@ -0,0 +1,129 @@ +#!/usr/bin/python + +import string +import shutil +import isys +import inutil +import socket +import struct +import os +import time +import minihal +import pyfire +import dbus +from flags import flags + +from constants import * + +from pyfire.config import ConfigFile + +from pyfire.translate import _ + +import logging +log = logging.getLogger("pomona") + +class IPError(Exception): + pass + +class IPMissing(Exception): + pass + +def sanityCheckHostname(hostname): + if len(hostname) < 1: + return None + + if len(hostname) > 255: + return _("Hostname must be 255 or fewer characters in length.") + + validStart = string.ascii_letters + string.digits + validAll = validStart + ".-" + + if string.find(validStart, hostname[0]) == -1: + return _("Hostname must start with a valid character in the ranges " + "'a-z', 'A-Z', or '0-9'") + + for i in range(1, len(hostname)): + if string.find(validAll, hostname[i]) == -1: + return _("Hostnames can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.'") + + return None + +# Try to determine what the hostname should be for this system +def getDefaultHostname(pomona): + return pomona.id.network.hostname + +# sanity check an IP string. +def sanityCheckIPString(ip_string): + if ip_string.strip() == "": + raise IPMissing, _("IP address is missing.") + + if ip_string.find(':') == -1 and ip_string.find('.') > 0: + family = socket.AF_INET + errstr = _("IPv4 addresses must contain four numbers between 0 and 255, separated by periods.") + elif ip_string.find(':') > 0 and ip_string.find('.') == -1: + family = socket.AF_INET6 + errstr = _("'%s' is not a valid IPv6 address.") % ip_string + else: + raise IPError, _("'%s' is an invalid IP address.") % ip_string + + try: + socket.inet_pton(family, ip_string) + except socket.error: + raise IPError, errstr + +def networkDeviceCheck(pomona): + devs = pomona.id.network.available() + if not devs: + pomona.dispatch.skipStep("network") + +class NetworkDevice(ConfigFile): + def __init__(self, dev): + self.info = { "DEVICE" : dev, + "ONBOOT": "no" } + +class Network: + def __init__(self): + self.netdevices = {} + self.gateway = "" + self.primaryNS = "" + self.secondaryNS = "" + self.domains = [] + self.isConfigured = 0 + self.hostname = sname + ".localdomain" + + # now initialize devices + self.available() + + def getDevice(self, device): + return self.netdevices[device] + + def available(self): + for device in minihal.get_devices_by_type("net"): + if device.has_key('net.arp_proto_hw_id'): + if device['net.arp_proto_hw_id'] == 1: + dev = device['device'] + self.netdevices[dev] = NetworkDevice(dev) + self.netdevices[dev].set(('hwaddr',device['net.address'])) + self.netdevices[dev].set(('desc',device['description'])) + + return self.netdevices + + def setHostname(self, hn): + self.hostname = hn + + def setDNS(self, ns): + dns = ns.split(',') + if len(dns) >= 1: + self.primaryNS = dns[0] + if len(dns) >= 2: + self.secondaryNS = dns[1] + + def setGateway(self, gw): + self.gateway = gw + + def write(self, instPath): + filename = "%s/etc/sysconfig/network" % (instPath,) + f = ConfigFile() + f.read(filename) + f.set(("HOSTNAME", self.hostname)) + f.write(filename) diff --git a/src/pomona/tui.py b/src/pomona/tui.py index 3d4c5d7e8..ab2e5dbb7 100644 --- a/src/pomona/tui.py +++ b/src/pomona/tui.py @@ -24,6 +24,7 @@ stepToClasses = { "install" : ("tui_progress", "setupForInstall"), "keyboard" : ("tui_keyboard", "KeyboardWindow"), "language" : ("tui_language", "LanguageWindow"), + "network" : ("tui_network", "HostnameWindow"), "partition": ("tui_partition", "PartitionWindow"), "parttype" : ("tui_partition", "PartitionTypeWindow"), "timezone" : ("tui_timezone", "TimezoneWindow"), diff --git a/src/pomona/tui_network.py b/src/pomona/tui_network.py new file mode 100644 index 000000000..b409d88b5 --- /dev/null +++ b/src/pomona/tui_network.py @@ -0,0 +1,84 @@ +# +# network_text.py: text mode network configuration dialogs +# +# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Author(s): Jeremy Katz +# Michael Fulbright +# David Cantrell +# + +import string +import network +import socket +from snack import * +from constants import * + +from pyfire.translate import _ + +import logging +log = logging.getLogger("pomona") + +class HostnameWindow: + def __call__(self, screen, pomona): + toplevel = GridFormHelp(screen, _("Hostname"), "hostname", 1, 3) + + # XXX: currently string frozen for F10, but change this text + # to 'Please name this computer. The hostname identifies the + # computer on a network.' after F10 is released. This will + # have the text interface match the iw interface. + text = TextboxReflowed(55, + _("Please name this computer. The hostname " + "identifies the computer on a network.")) + toplevel.add(text, 0, 0, (0, 0, 0, 1)) + + hostEntry = Entry(55) + hostEntry.set(network.getDefaultHostname(pomona)) + toplevel.add(hostEntry, 0, 1, padding = (0, 0, 0, 1)) + + bb = ButtonBar(screen, (TEXT_OK_BUTTON, TEXT_BACK_BUTTON)) + toplevel.add(bb, 0, 2, growx = 1) + + while 1: + result = toplevel.run() + rc = bb.buttonPressed(result) + + if rc == TEXT_BACK_CHECK: + screen.popWindow() + return INSTALL_BACK + + hname = string.strip(hostEntry.value()) + if len(hname) == 0: + ButtonChoiceWindow(screen, _("Invalid Hostname"), + _("You have not specified a hostname."), + buttons = [ _("OK") ]) + continue + + neterrors = network.sanityCheckHostname(hname) + if neterrors is not None: + ButtonChoiceWindow(screen, _("Invalid Hostname"), + _("The hostname \"%s\" is not valid " + "for the following reason:\n\n%s") + %(hname, neterrors), + buttons = [ _("OK") ]) + continue + + pomona.id.network.hostname = hname + break + + screen.popWindow() + return INSTALL_OK