#
# netconfig_dialog.py: Configure a network interface now.
#
# Copyright (C) 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
#
import gtk
import gobject
import gui
from constants import *
import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
import network
import isys
class NetworkConfigurator:
def __init__(self, network):
(xml, w) = gui.getGladeWidget("netconfig.glade", "NetworkConfigWindow")
self.window = w
self.network = network
self.xml = xml
self.rc = gtk.RESPONSE_CANCEL
self._setSizeGroup()
self._connectSignals()
self._populateNetdevs()
self.xml.get_widget("ipv4Checkbutton").set_active(True)
self.xml.get_widget("ipv6Checkbutton").set_active(False)
def _connectSignals(self):
sigs = { "on_ipv4Checkbutton_toggled": self._ipv4Toggled,
"on_ipv6Checkbutton_toggled": self._ipv6Toggled,
"on_dhcpCheckbutton_toggled": self._dhcpToggled,
"on_interfaceCombo_changed": self._netdevChanged,
"on_cancelButton_clicked": self._cancel,
"on_okButton_clicked": self._ok }
self.xml.signal_autoconnect(sigs)
def _setSizeGroup(self): # too bad we can't do this in the glade file
sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
for w in ("nameserverLabel", "gatewayLabel", "ipv6Label",
"ipv4Label", "interfaceLabel"):
sg.add_widget(self.xml.get_widget(w))
def _netdevChanged(self, combo):
active = combo.get_active_iter()
val = combo.get_model().get_value(active, 1)
netdev = self.network.available()[val]
bootproto = netdev.get("BOOTPROTO")
if not bootproto or bootproto == "dhcp" or bootproto == "ibft":
self.xml.get_widget("dhcpCheckbutton").set_active(True)
else:
self.xml.get_widget("dhcpCheckbutton").set_active(False)
# FIXME: need to set ipv6 here too once we have that
try:
if netdev.get('IPADDR'):
self.xml.get_widget("ipv4Address").set_text(netdev.get('IPADDR'))
except:
pass
try:
if netdev.get('NETMASK'):
self.xml.get_widget("ipv4Netmask").set_text(netdev.get('NETMASK'))
except:
pass
try:
if self.network.gateway:
self.xml.get_widget("gatewayEntry").set_text(self.network.gateway)
except:
pass
try:
if self.network.primaryNS:
self.xml.get_widget("nameserverEntry").set_text(self.network.primaryNS)
except:
pass
def _ipv4Toggled(self, cb):
if self.xml.get_widget("dhcpCheckbutton").get_active():
return
if cb.get_active():
self.xml.get_widget("ipv4Box").set_sensitive(True)
else:
self.xml.get_widget("ipv4Box").set_sensitive(False)
def _ipv6Toggled(self, cb):
if self.xml.get_widget("dhcpCheckbutton").get_active():
return
if cb.get_active():
self.xml.get_widget("ipv6Box").set_sensitive(True)
else:
self.xml.get_widget("ipv6Box").set_sensitive(False)
def _dhcpToggled(self, cb):
boxes = ("ipv4Box", "ipv6Box", "nameserverBox", "gatewayBox")
if not cb.get_active():
map(lambda x: self.xml.get_widget(x).set_sensitive(True), boxes)
self.xml.get_widget("ipv4Box").set_sensitive(self.xml.get_widget("ipv4Checkbutton").get_active())
self.xml.get_widget("ipv6Box").set_sensitive(self.xml.get_widget("ipv6Checkbutton").get_active())
else:
map(lambda x: self.xml.get_widget(x).set_sensitive(False), boxes)
def _populateNetdevs(self):
combo = self.xml.get_widget("interfaceCombo")
cell = gtk.CellRendererText()
combo.pack_start(cell, True)
combo.set_attributes(cell, text = 0)
cell.set_property("wrap-width", 525)
combo.set_size_request(480, -1)
store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
combo.set_model(store)
netdevs = self.network.available()
devs = netdevs.keys()
devs.sort()
ksdevice = self.network.getKSDevice()
if ksdevice:
ksdevice = ksdevice.get('DEVICE')
selected_interface = None
for dev in devs:
i = store.append(None)
hwaddr = netdevs[dev].get("HWADDR")
if hwaddr:
desc = "%s - %s" %(dev, hwaddr,)
else:
desc = "%s" %(dev,)
if selected_interface is None:
selected_interface = i
if ksdevice and ksdevice == dev:
selected_interface = i
store[i] = (desc, dev)
if selected_interface:
combo.set_active_iter(selected_interface)
else:
combo.set_active(0)
def run(self):
gui.addFrame(self.window)
busycursor = gui.getBusyCursorStatus()
gui.setCursorToNormal()
self.window.show()
while True:
rc = self.window.run()
if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
self._cancel()
break
if self._ok():
break
# restore busy cursor
if busycursor:
gui.setCursorToBusy()
return self.rc
def destroy(self):
self.window.destroy()
def _handleIPError(self, field, errmsg):
d = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR,
gtk.BUTTONS_OK,
_("An error occurred converting the value "
"entered for \"%(field)s\":\n%(errmsg)s")
% {'field': field, 'errmsg': errmsg})
d.set_title(_("Error With Data"))
d.set_position(gtk.WIN_POS_CENTER)
gui.addFrame(d)
d.run()
d.destroy()
def _handleIPMissing(self, field):
d = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
_("A value is required for the field %s.") % (field,))
d.set_title(_("Error With Data"))
d.set_position(gtk.WIN_POS_CENTER)
gui.addFrame(d)
d.run()
d.destroy()
def _handleNetworkError(self, field):
d = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR,
gtk.BUTTONS_OK,
_("An error occurred trying to bring up the "
"%s network interface.") % (field,))
d.set_title(_("Error Configuring Network"))
d.set_position(gtk.WIN_POS_CENTER)
gui.addFrame(d)
d.run()
d.destroy()
def _cancel(self, *args):
self.rc = gtk.RESPONSE_CANCEL
def _ok(self, *args):
self.rc = gtk.RESPONSE_OK
haveNet = False
combo = self.xml.get_widget("interfaceCombo")
active = combo.get_active_iter()
val = combo.get_model().get_value(active, 1)
for v, dev in self.network.available().items():
if v == val:
dev.set(('ONBOOT', 'yes'))
netdev = dev
else:
dev.set(('ONBOOT', 'no'))
# FIXME: need to do input validation
if self.xml.get_widget("dhcpCheckbutton").get_active():
netdev.set(('BOOTPROTO', 'dhcp'))
self.window.hide()
w = gui.WaitWindow(_("Dynamic IP Address"),
_("Sending request for IP address information "
"for %s") % (netdev.get('DEVICE'),))
haveNet = self.network.bringUp(devices=[netdev])
w.pop()
else:
netdev.set(('BOOTPROTO', 'static'))
ipv4addr = self.xml.get_widget("ipv4Address").get_text()
ipv4nm = self.xml.get_widget("ipv4Netmask").get_text()
gateway = self.xml.get_widget("gatewayEntry").get_text()
ns = self.xml.get_widget("nameserverEntry").get_text()
try:
network.sanityCheckIPString(ipv4addr)
netdev.set(('IPADDR', ipv4addr))
except network.IPMissing, msg:
self._handleIPMissing(_("IP Address"))
return False
except network.IPError, msg:
self._handleIPError(_("IP Address"), msg)
return False
if ipv4nm.find('.') == -1:
# user provided a CIDR prefix
try:
if int(ipv4nm) > 32 or int(ipv4nm) < 0:
msg = _("IPv4 CIDR prefix must be between 0 and 32.")
self._handleIPError(_("IPv4 Network Mask"), msg)
return False
else:
ipv4nm = isys.prefix2netmask(int(ipv4nm))
netdev.set(('NETMASK', ipv4nm))
except:
self._handleIPMissing(_("IPv4 Network Mask"))
return False
else:
# user provided a dotted-quad netmask
try:
network.sanityCheckIPString(ipv4nm)
netdev.set(('NETMASK', ipv4nm))
except network.IPMissing, msg:
self._handleIPMissing(_("IPv4 Network Mask"))
return False
except network.IPError, msg:
self._handleIPError(_("IPv4 Network Mask"), msg)
return False
try:
if gateway:
network.sanityCheckIPString(gateway)
netdev.set(('GATEWAY', gateway))
except network.IPMissing, msg:
pass
except network.IPError, msg:
self._handleIPError(_("Gateway"), msg)
return False
try:
if ns:
network.sanityCheckIPString(ns)
netdev.set(('DNS1', ns))
except network.IPMissing, msg:
pass
except network.IPError, msg:
self._handleIPError(_("Nameserver"), msg)
return False
try:
haveNet = self.network.bringUp(devices=[netdev])
except Exception, e:
import logging
log = logging.getLogger("anaconda")
log.error("Error configuring network device: %s" %(e,))
self._handleIPError(_("Error configuring network device:"), e)
return False
if not haveNet:
self._handleNetworkError(netdev.get('DEVICE'))
return False
return True
def main():
net = network.Network()
d = NetworkConfigurator(net)
ret = d.run()
if __name__ == "__main__":
main()