[PATCH 09/22] Enable networking in stage 2 using nm-c-e (#520146)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Key patch of series. enableNetwork method is the root of all other
changes in the patchset. The method is used both for network enabling
in stage 2 triggered by need of network (repos, network storage, etc..)
and [Configure Network] button

What we select in stage 2 network UI is:
- device to be activated (only in case of network enabling), this is
  controlled by ONBOOT ifcfg setting, note that devices actually
  activated depend on editing in nm-c-e
- devices to be controlled by NM (and thus visible in nm-c-e),
  this is set by NM_CONTROLLED ifcfg setting

A dialog for that is part of the patch, it needs some polishing.

bringUp method had to be split into write and waitForConnection
because in case of just config, without actually activating any
device in nm-c-e, we don't want to wait for activation.
---
 gui.py                  |   66 +++++-
 iw/advanced_storage.py  |    8 +-
 iw/netconfig_dialog.py  |  329 -----------------------------
 iw/network_gui.py       |  164 +++++++++++++--
 kickstart.py            |    1 +
 network.py              |   42 +++-
 textw/netconfig_text.py |    2 +
 ui/netconfig.glade      |  538 -----------------------------------------------
 8 files changed, 246 insertions(+), 904 deletions(-)
 delete mode 100644 iw/netconfig_dialog.py
 delete mode 100644 ui/netconfig.glade

diff --git a/gui.py b/gui.py
index ce6d071..307f5dc 100755
--- a/gui.py
+++ b/gui.py
@@ -41,7 +41,7 @@ import gobject
 from language import expandLangs
 from constants import *
 from product import *
-from network import hasActiveNetDev
+import network
 from installinterfacebase import InstallInterfaceBase
 import xutils
 import imputil
@@ -953,15 +953,67 @@ class InstallInterface(InstallInterfaceBase):
     def resume(self):
         pass
 
-    def enableNetwork(self):
+
+    # TODORV: handle one device case - don't ask
+    def enableNetwork(self, just_setup=False):
+
         if len(self.anaconda.network.netdevices) == 0:
             return False
-        from netconfig_dialog import NetworkConfigurator
-        net = NetworkConfigurator(self.anaconda.network)
-        ret = net.run()
-        net.destroy()
 
-        return ret not in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]
+        from network_gui import (runNMCE,
+                                 selectNetDevicesDialog)
+
+        networkEnabled = False
+        while not networkEnabled:
+            choice = selectNetDevicesDialog(self.anaconda.network,
+                                            select_install_device=(not just_setup))
+            if not choice:
+                break
+            nm_controlled_devices, install_device = choice
+
+            # update ifcfg files for nm-c-e
+            self.anaconda.network.setNMControlledDevices(nm_controlled_devices)
+            if not just_setup:
+                self.anaconda.network.updateActiveDevices([install_device])
+
+            runNMCE(self.anaconda)
+
+            self.anaconda.network.update()
+
+            if just_setup:
+                # TODORV check which devices were actually activated by nmce
+                # and which we should wait for (the case for more than one
+                # device)
+                onboot_devs = self.anaconda.network.getOnbootIfaces()
+                if onboot_devs:
+                    install_device = onboot_devs[0]
+
+            self.anaconda.network.write()
+
+            if install_device:
+                w = WaitWindow(_("Waiting for NetworkManager"),
+                               _("Waiting for NetworkManager to get connection."))
+                networkEnabled = self.anaconda.network.waitForConnection()
+                if not networkEnabled and not just_setup:
+                    self._handleNetworkError(install_device)
+                w.pop()
+
+            if just_setup:
+                break
+
+        return networkEnabled
+
+
+    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)
+        addFrame(d)
+        d.run()
+        d.destroy()
 
     def setInstallProgressClass(self, c):
         self.instProgress = c
diff --git a/iw/advanced_storage.py b/iw/advanced_storage.py
index c03b3ab..3e517dc 100644
--- a/iw/advanced_storage.py
+++ b/iw/advanced_storage.py
@@ -27,7 +27,6 @@ import iutil
 import network
 import storage.fcoe
 import storage.iscsi
-from netconfig_dialog import NetworkConfigurator
 
 def addFcoeDrive(anaconda):
     (dxml, dialog) = gui.getGladeWidget("fcoe-config.glade", "fcoeDialog")
@@ -107,11 +106,8 @@ def addFcoeDrive(anaconda):
 
 def addIscsiDrive(anaconda):
     if not network.hasActiveNetDev():
-        net = NetworkConfigurator(anaconda.network)
-        ret = net.run()
-        net.destroy()
-        if ret != gtk.RESPONSE_OK:
-            return ret
+        if not self.anaconda.intf.enableNetwork()
+            return gtk.RESPONSE_CANCEL
 
     (dxml, dialog) = gui.getGladeWidget("iscsi-config.glade", "iscsiDialog")
     gui.addFrame(dialog)
diff --git a/iw/netconfig_dialog.py b/iw/netconfig_dialog.py
deleted file mode 100644
index 336cf0e..0000000
--- a/iw/netconfig_dialog.py
+++ /dev/null
@@ -1,329 +0,0 @@
-#
-# 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 <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-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()
diff --git a/iw/network_gui.py b/iw/network_gui.py
index 4d8e5da..60af4ba 100644
--- a/iw/network_gui.py
+++ b/iw/network_gui.py
@@ -28,6 +28,9 @@ import network
 import iutil
 import gobject
 import subprocess
+import gtk
+import isys
+import urlgrabber.grabber
 
 from constants import *
 import gettext
@@ -46,7 +49,7 @@ class NetworkWindow(InstallWindow):
         self.hostnameEntry = self.xml.get_widget("hostnameEntry")
         self.hostnameEntry.set_text(self.hostname)
 
-        self.xml.get_widget("netconfButton").connect("clicked", self._NMConfig)
+        self.xml.get_widget("netconfButton").connect("clicked", self._setupNetwork)
 
         # pressing Enter in confirm == clicking Next
         self.hostnameEntry.connect("activate",
@@ -57,6 +60,11 @@ class NetworkWindow(InstallWindow):
 
         return self.align
 
+    def _setupNetwork(self, *args):
+        self.intf.enableNetwork(just_setup=True)
+        if network.hasActiveNetDev():
+            urlgrabber.grabber.reset_curl_obj()
+
     def focus(self):
         self.hostnameEntry.grab_focus()
 
@@ -87,20 +95,142 @@ class NetworkWindow(InstallWindow):
         self.anaconda.network.hostname = hostname
         return None
 
-    def _NMExited(self, pid, condition, data):
-        self.intf.icw.window.set_sensitive(True)
-
-    def _NMConfig(self, *args):
-
-        self.intf.icw.window.set_sensitive(False)
-        cmd = ["/usr/bin/nm-connection-editor"]
-        out = open("/dev/tty5", "w")
-        try:
-            proc = subprocess.Popen(cmd, stdout=out, stderr=out)
-        except Exception as e:
-            self.intf.icw.window.set_sensitive(True)
-            import logging
-            log = logging.getLogger("anaconda")
-            log.error("Could not start nm-connection-editor: %s" % e)
+def NMCEExited(pid, condition, anaconda):
+    if anaconda:
+        anaconda.intf.icw.window.set_sensitive(True)
+
+# TODORV: get rid of setting sensitive completely?
+def runNMCE(anaconda=None, blocking=True):
+    if not blocking and anaconda:
+        anaconda.intf.icw.window.set_sensitive(False)
+    cmd = ["/usr/bin/nm-connection-editor"]
+    out = open("/dev/tty5", "w")
+    try:
+        proc = subprocess.Popen(cmd, stdout=out, stderr=out)
+    except Exception as e:
+        if not blocking and anaconda:
+            anaconda.intf.icw.window.set_sensitive(True)
+        import logging
+        log = logging.getLogger("anaconda")
+        log.error("Could not start nm-connection-editor: %s" % e)
+        return None
+    else:
+        if blocking:
+            proc.wait()
+        else:
+            gobject.child_watch_add(proc.pid, NMCEExited, data=anaconda, priority=gobject.PRIORITY_DEFAULT)
+
+def selectNetDevicesDialog(network, select_install_device=True):
+
+    netdevs = network.netdevices
+    devs = netdevs.keys()
+    devs.sort()
+
+    rv = {}
+    dialog = gtk.Dialog(_("Select network interfaces"))
+    dialog.add_button('gtk-cancel', 2)
+    dialog.add_button('gtk-ok', 1)
+    dialog.set_position(gtk.WIN_POS_CENTER)
+    gui.addFrame(dialog)
+
+    if select_install_device:
+
+        dialog.vbox.pack_start(gui.WrappingLabel(
+            _("This requires that you have an active "
+              "network connection during the installation "
+              "process.  Please configure a network interface.")))
+
+        combo = gtk.ComboBox()
+        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)
+
+        ksdevice = network.getKSDevice()
+        if ksdevice:
+            ksdevice = ksdevice.get('DEVICE')
+        selected_interface = None
+
+        for dev in devs:
+            i = store.append(None)
+            # TODORV: add description
+            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)
+
+        # TODORV: simplify to use just indexes
+        if selected_interface:
+            combo.set_active_iter(selected_interface)
         else:
-            gobject.child_watch_add(proc.pid, self._NMExited, data=None, priority=gobject.PRIORITY_DEFAULT)
+            combo.set_active(0)
+
+        def installDevChanged(combo, dev_check_buttons):
+            active = combo.get_active()
+            for idx, (dev, cb) in enumerate(dev_check_buttons):
+                if idx == active:
+                    cb.set_active(True)
+                    cb.set_sensitive(False)
+                else:
+                    cb.set_sensitive(True)
+
+        dialog.vbox.pack_start(combo)
+
+
+    dialog.vbox.pack_start(gui.WrappingLabel(
+        _("Select which devices should be configured with NetworkManager.")))
+
+    table = gtk.Table(len(devs), 1)
+    table.set_row_spacings(5)
+    table.set_col_spacings(5)
+
+    dev_check_buttons = []
+    for i, dev in enumerate(devs):
+        cb = gtk.CheckButton(dev)
+        # TODORV: We want all devices controlled by nm by default,
+        # but we might want to add storage net devices filtering here
+        #if not (netdevs[dev].get("NM_CONTROLLED") == "no"):
+        cb.set_active(True)
+        table.attach(cb, 0, 1, i, i+1, gtk.FILL, gtk.FILL)
+        dev_check_buttons.append([dev, cb])
+
+    dialog.vbox.pack_start(table)
+
+    if select_install_device:
+        combo.connect("changed", installDevChanged, dev_check_buttons)
+
+    dialog.show_all()
+
+    rc = dialog.run()
+
+    if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+        retval = None
+    else:
+        install_device = None
+        if select_install_device:
+            active = combo.get_active_iter()
+            install_device = combo.get_model().get_value(active, 1)
+
+        nm_controlled_devices = [dev for (dev, cb) in dev_check_buttons if
+                                 cb.get_active()]
+
+        retval = (nm_controlled_devices, install_device)
+
+    dialog.destroy()
+    return retval
+
+
+
diff --git a/kickstart.py b/kickstart.py
index 8e3368d..a233e07 100644
--- a/kickstart.py
+++ b/kickstart.py
@@ -612,6 +612,7 @@ class NetworkData(commands.network.F8_NetworkData):
                       anaconda.methodstr.startswith("nfs:")))
         if needs_net and not network.hasActiveNetDev():
             log.info("Bringing up network in stage2 kickstart ...")
+            dev.set (('NM_CONTROLLED', 'yes'))
             rc = anaconda.network.bringUp()
             log.info("Network setup %s" % (rc and 'succeeded' or 'failed',))
 
diff --git a/network.py b/network.py
index 8f61a3a..9bbb935 100644
--- a/network.py
+++ b/network.py
@@ -264,11 +264,8 @@ class NetworkDevice(IfcfgFile):
             keys.remove("HWADDR")
 
         for key in keys:
-            if (key == 'NAME') or \
-               (key == 'NM_CONTROLLED' and not flags.livecdInstall):
-                continue
             # make sure we include autoneg in the ethtool line
-            elif key == 'ETHTOOL_OPTS' and self.info[key].find("autoneg")== -1:
+            if key == 'ETHTOOL_OPTS' and self.info[key].find("autoneg")== -1:
                 s = s + key + """="autoneg off %s"\n""" % (self.info[key])
             elif self.info[key] is not None:
                 s = s + key + '="' + self.info[key] + '"\n'
@@ -413,6 +410,32 @@ class Network:
 
         return ip
 
+    # devices == None => set for all
+    def setNMControlledDevices(self, devices=None):
+        for devname, device in self.netdevices.items():
+            if devices and devname not in devices:
+                continue
+            device.set(('NM_CONTROLLED', 'yes'))
+            device.writeIfcfgFile()
+            device.log_file("device set to be nm controlled\n")
+
+    # devices == None => set for all
+    def updateActiveDevices(self, devices=None):
+        for devname, device in self.netdevices.items():
+            if devices and devname not in devices:
+                device.set(('ONBOOT', 'no'))
+            else:
+                device.set(('ONBOOT', 'yes'))
+            device.writeIfcfgFile()
+            device.log_file("updateActiveDevices\n")
+
+    def getOnbootIfaces(self):
+        ifaces = []
+        for iface, device in self.netdevices.items():
+            if device.get('ONBOOT') == "yes":
+                ifaces.append(iface)
+        return ifaces
+
     def writeKS(self, f):
         devNames = self.netdevices.keys()
         devNames.sort()
@@ -658,9 +681,7 @@ class Network:
     # write out current configuration state and wait for NetworkManager
     # to bring the device up, watch NM state and return to the caller
     # once we have a state
-    def bringUp(self, devices=None):
-        self.write(devices=devices)
-
+    def waitForConnection(self):
         bus = dbus.SystemBus()
         nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
         props = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
@@ -681,6 +702,13 @@ class Network:
 
         return False
 
+    # write out current configuration state and wait for NetworkManager
+    # to bring the device up, watch NM state and return to the caller
+    # once we have a state
+    def bringUp(self, devices=None):
+        self.write(devices=devices)
+        return self.waitForConnection()
+
     # get a kernel cmdline string for dracut needed for access to host host
     def dracutSetupString(self, networkStorageDevice):
         netargs=""
diff --git a/textw/netconfig_text.py b/textw/netconfig_text.py
index fb37429..41c0376 100644
--- a/textw/netconfig_text.py
+++ b/textw/netconfig_text.py
@@ -196,8 +196,10 @@ class NetworkConfiguratorText:
 
             for name, dev in netdevs.items():
                 if name in selected:
+                    dev.set(('NM_CONTROLLED', 'yes'))
                     dev.set(('ONBOOT', 'yes'))
                 else:
+                    dev.set(('NM_CONTROLLED', 'no'))
                     dev.set(('ONBOOT', 'no'))
 
             selected_netdevs = []
diff --git a/ui/netconfig.glade b/ui/netconfig.glade
deleted file mode 100644
index cb8991f..0000000
--- a/ui/netconfig.glade
+++ /dev/null
@@ -1,538 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkDialog" id="NetworkConfigWindow">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Enable network interface</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelButton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okButton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox1">
-	  <property name="border_width">18</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">12</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label1">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes" context="yes">This requires that you have an active network connection during the installation process.  Please configure a network interface.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="interfaceBox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="interfaceLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;_Interface:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkComboBox" id="interfaceCombo">
-		  <property name="visible">True</property>
-		  <property name="add_tearoffs">False</property>
-		  <property name="focus_on_click">True</property>
-		  <signal name="changed" handler="on_interfaceCombo_changed"/>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkCheckButton" id="dhcpCheckbutton">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes" context="yes">Use _dynamic IP configuration (DHCP)</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	      <signal name="toggled" handler="on_dhcpCheckbutton_toggled"/>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkCheckButton" id="ipv4Checkbutton">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes" context="yes">Enable IPv_4 support</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	      <signal name="toggled" handler="on_ipv4Checkbutton_toggled"/>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkCheckButton" id="ipv6Checkbutton">
-	      <property name="label" translatable="yes" context="yes">Enable IPv_6 support</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	      <signal name="toggled" handler="on_ipv6Checkbutton_toggled"/>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="ipv4Box">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="ipv4Label">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;IPv4 Address:&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="ipv4Address">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">16</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label10">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">/</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="ipv4Netmask">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">16</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="ipv6Box">
-	      <property name="sensitive">False</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="ipv6Label">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;IPv6 Address:&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="ipv6Address">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">41</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label11">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">/</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="ipv6Netmask">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">4</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="gatewayBox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="gatewayLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;Gateway:&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="gatewayEntry">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">41</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="nameserverBox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="nameserverLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;Nameserver:&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="nameserverEntry">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">41</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <placeholder/>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
-- 
1.6.0.6

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux