[PATCH rhel6-branch] (take II) Control all devs by NM by default + filtering (iSCSI, FCoE) (#606745)

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

 



This version of patch differs only in that nm controlled dialog
was removed.

* All devices are set to NM_CONTROLLED in Network.__init__.
  This solves the issue that for media installs without network
  devices were not controlled by NM and thus not configurable
  with nm-applet after install (the bug).

* For devices used for FCoE and iSCSI NM_CONTROLLED is modified
  later (after storage initialization and FCoE/iSCSI setting)
  in two places:

  - before running nm-c-e
    - FCoE devices are set to not controlled

  - before writing ifcfg files to installed system
    - FCoE devices are set to not controlled
    - iSCSI devices *backing root* are set to not controlled
      This can go away when
      https://bugzilla.redhat.com/show_bug.cgi?id=607921
      is fixed.

  This change required splitting of isStorageDevice into three
  finer functions (usedByFCoE, usedBy..., ...). Also note that
  iSCSI case was fixed to count only devices actually used in route
  to the target - code from dracutSetupString moved into function
  ifaceForHostIP is used, as Hans suggested.

* Dialog for selecting devices controlled by NM is removed.
  With all devices controlled by default it doesn't seem useful
  enough.
---
 gui.py            |   20 +++++---
 iw/network_gui.py |  137 ++++++++++++++++++-----------------------------------
 network.py        |   68 ++++++++++++++++++--------
 3 files changed, 106 insertions(+), 119 deletions(-)

diff --git a/gui.py b/gui.py
index c116cbd..004fc78 100755
--- a/gui.py
+++ b/gui.py
@@ -954,27 +954,31 @@ class InstallInterface(InstallInterfaceBase):
         pass
 
 
-    # TODORV: handle one device case - don't ask
     # just_setup is used for [Configure Network] button
     def enableNetwork(self, just_setup=False):
 
         if len(self.anaconda.id.network.netdevices) == 0:
             return False
 
+        nm_controlled_devices = [devname for (devname, dev)
+                                 in self.anaconda.id.network.netdevices.items()
+                                 if not dev.usedByFCoE(self.anaconda)]
+        if not just_setup and not nm_controlled_devices:
+            return False
+
         from network_gui import (runNMCE,
-                                 selectNetDevicesDialog)
+                                 selectInstallNetDeviceDialog)
 
         networkEnabled = False
         while not networkEnabled:
-            if just_setup and len(self.anaconda.id.network.netdevices) <= 1:
-                nm_controlled_devices = self.anaconda.id.network.netdevices.keys()
+
+            if just_setup:
                 install_device = None
             else:
-                choice = selectNetDevicesDialog(self.anaconda.id.network,
-                                                select_install_device=(not just_setup))
-                if not choice:
+                install_device = selectInstallNetDeviceDialog(self.anaconda.id.network,
+                                                              nm_controlled_devices)
+                if not install_device:
                     break
-                nm_controlled_devices, install_device = choice
 
             # update ifcfg files for nm-c-e
             self.anaconda.id.network.setNMControlledDevices(nm_controlled_devices)
diff --git a/iw/network_gui.py b/iw/network_gui.py
index 18c16f7..ecd010b 100644
--- a/iw/network_gui.py
+++ b/iw/network_gui.py
@@ -123,98 +123,62 @@ def runNMCE(anaconda=None, blocking=True):
         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()
+def selectInstallNetDeviceDialog(network, devices = None):
+
+    devs = devices or network.netdevices.keys()
+    if not devs:
+        return None
     devs.sort()
 
-    rv = {}
-    dialog = gtk.Dialog(_("Select network interfaces"))
+    dialog = gtk.Dialog(_("Select network interface"))
     dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
     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_idx = 0
-
-        for idx, dev in enumerate(devs):
-            i = store.append(None)
-
-            desc = netdevs[dev].description
-            if desc:
-                desc = "%s - %s" %(dev, desc)
-            else:
-                desc = "%s" %(dev,)
-
-            hwaddr = netdevs[dev].get("HWADDR")
-
-            if hwaddr:
-                desc = "%s - %s" %(desc, hwaddr,)
-
-            if ksdevice and ksdevice == dev:
-                selected_interface_idx = idx
-
-            store[i] = (desc, dev)
+    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')
+    preselected = None
+
+    for dev in devices:
+        i = store.append(None)
+        if not preselected:
+            preselected = i
+
+        desc = network.netdevices[dev].description
+        if desc:
+            desc = "%s - %s" %(dev, desc)
+        else:
+            desc = "%s" %(dev,)
 
-        # TODORV: simplify to use just indexes
-        combo.set_active(selected_interface_idx)
+        hwaddr = network.netdevices[dev].get("HWADDR")
 
-        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)
+        if hwaddr:
+            desc = "%s - %s" %(desc, hwaddr,)
 
-        dialog.vbox.pack_start(combo)
+        if ksdevice and ksdevice == dev:
+            preselected = i
 
+        store[i] = (desc, dev)
 
-    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:
-        selected_dev_cb = dev_check_buttons[selected_interface_idx][1]
-        selected_dev_cb.set_active(True)
-        selected_dev_cb.set_sensitive(False)
-        combo.connect("changed", installDevChanged, dev_check_buttons)
+    combo.set_active_iter(preselected)
+    dialog.vbox.pack_start(combo)
 
     dialog.show_all()
 
@@ -223,18 +187,9 @@ def selectNetDevicesDialog(network, select_install_device=True):
     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)
+        active = combo.get_active_iter()
+        install_device = combo.get_model().get_value(active, 1)
 
     dialog.destroy()
-    return retval
-
-
+    return install_device
 
diff --git a/network.py b/network.py
index f7c5a3b..78a9a47 100644
--- a/network.py
+++ b/network.py
@@ -307,17 +307,33 @@ class NetworkDevice(IfcfgFile):
         lf.close()
         f.close()
 
-    def isStorageDevice(self, anaconda):
+    def usedByFCoE(self, anaconda):
         import storage
-        rootdev = anaconda.id.storage.rootDevice
-        # FIXME: use d.host_address to only add "NM_CONTROLLED=no"
-        # for interfaces actually used enroute to the device
         for d in anaconda.id.storage.devices:
-            if isinstance(d, storage.devices.NetworkStorageDevice) and\
-               (rootdev.dependsOn(d) or d.nic == self.iface):
+            if (isinstance(d, storage.devices.NetworkStorageDevice) and
+                d.nic == self.iface):
                 return True
         return False
 
+    def usedByRootOnISCSI(self, anaconda):
+        import storage
+        rootdev = anaconda.id.storage.rootDevice
+        for d in anaconda.id.storage.devices:
+            if (isinstance(d, storage.devices.NetworkStorageDevice) and
+                d.host_address and
+                rootdev.dependsOn(d)):
+                if self.iface == ifaceForHostIP(d.host_address):
+                    return True
+        return False
+
+    def usedByISCSI(self, anaconda):
+        import storage
+        for d in anaconda.id.storage.devices:
+            if (isinstance(d, storage.devices.NetworkStorageDevice) and
+                d.host_address):
+                if self.iface == ifaceForHostIP(d.host_address):
+                    return True
+        return False
 
 class Network:
 
@@ -330,6 +346,12 @@ class Network:
         # We want wireless devices to be nm controlled by default
         self.controlWireless()
 
+        # Set all devices to be controlled by NM by default.
+        # We can filter out storage devices only after
+        # we have device tree populated. So we do it before
+        # running nm-c-e and before writing ifcfg files to system.
+        self.setNMControlledDevices(self.netdevices.keys())
+
     def update(self):
 
         self.netdevices = {}
@@ -561,7 +583,8 @@ class Network:
 
     def disableNMForStorageDevices(self, anaconda, instPath=''):
         for devName, device in self.netdevices.items():
-            if device.isStorageDevice(anaconda):
+            if (device.usedByFCoE(anaconda) or
+                device.usedByRootOnISCSI(anaconda)):
                 dev = NetworkDevice(instPath + netscriptsDir, devName)
                 if os.access(dev.path, os.R_OK):
                     dev.loadIfcfgFile()
@@ -769,21 +792,10 @@ class Network:
             nic = networkStorageDevice.nic
         else:
             # Storage bound through ip, find out which interface leads to host
-            host = networkStorageDevice.host_address
-            route = iutil.execWithCapture("ip", [ "route", "get", "to", host ])
-            if not route:
-                log.error("Could net get interface for route to %s" % host)
-                return ""
-
-            routeInfo = route.split()
-            if routeInfo[0] != host or len(routeInfo) < 5 or \
-               "dev" not in routeInfo or routeInfo.index("dev") > 3:
-                log.error('Unexpected "ip route get to %s" reply: %s' %
-                          (host, routeInfo))
+            nic = ifaceForHostIP(networkStorageDevice.host_address)
+            if not nic:
                 return ""
 
-            nic = routeInfo[routeInfo.index("dev") + 1]
-
         if nic not in self.netdevices.keys():
             log.error('Unknown network interface: %s' % nic)
             return ""
@@ -828,3 +840,19 @@ class Network:
                 netargs += ",%s" % (','.join(options))
 
         return netargs
+
+def ifaceForHostIP(host):
+    route = iutil.execWithCapture("ip", [ "route", "get", "to", host ])
+    if not route:
+        log.error("Could not get interface for route to %s" % host)
+        return ""
+
+    routeInfo = route.split()
+    if routeInfo[0] != host or len(routeInfo) < 5 or \
+       "dev" not in routeInfo or routeInfo.index("dev") > 3:
+        log.error('Unexpected "ip route get to %s" reply: %s' %
+                  (host, routeInfo))
+        return ""
+
+    return routeInfo[routeInfo.index("dev") + 1]
+
-- 
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