[PATCH 4/5] Bonding support: GUI - generate kickstart network command for bonds (#906263)
Radek Vykydal
rvykydal at redhat.com
Thu Mar 7 13:47:09 UTC 2013
---
pyanaconda/network.py | 77 +++++++++++++++++++++++++++++++++----
pyanaconda/ui/gui/spokes/network.py | 10 ++++-
2 files changed, 77 insertions(+), 10 deletions(-)
diff --git a/pyanaconda/network.py b/pyanaconda/network.py
index 06136e1..626e2c0 100644
--- a/pyanaconda/network.py
+++ b/pyanaconda/network.py
@@ -195,17 +195,22 @@ def logIfcfgFile(path, message=""):
content = "file not found"
ifcfglog.debug("%s%s:\n%s" % (message, path, content))
-def logIfcfgFiles(message=""):
- ifcfglog.debug("content of files (%s):" % message)
- for name in os.listdir(netscriptsDir):
+def _ifcfg_files(directory):
+ rv = []
+ for name in os.listdir(directory):
if name.startswith("ifcfg-"):
- if name == 'ifcfg-lo':
+ if name == "ifcfg-lo":
continue
- path = os.path.join(netscriptsDir, name)
- f = open(path, 'r')
+ rv.append(name)
+ return rv
+
+def logIfcfgFiles(message=""):
+ ifcfglog.debug("content of files (%s):" % message)
+ for name in _ifcfg_files(netscriptsDir):
+ path = os.path.join(netscriptsDir, name)
+ with open(path, "r") as f:
content = f.read()
- f.close()
- ifcfglog.debug("%s:\n%s" % (path, content))
+ ifcfglog.debug("%s:\n%s" % (path, content))
class NetworkDevice(IfcfgFile):
@@ -410,6 +415,10 @@ def kickstartNetworkData(ifcfg=None, hostname=None):
if not ifcfg and hostname:
return handler.NetworkData(hostname=hostname, bootProto="")
+ # no network command for bond slaves
+ if ifcfg.get("MASTER"):
+ return None
+
# ipv4 and ipv6
if not ifcfg.get("ESSID"):
kwargs["device"] = ifcfg.iface
@@ -490,8 +499,60 @@ def kickstartNetworkData(ifcfg=None, hostname=None):
hostname != DEFAULT_HOSTNAME):
kwargs["hostname"] = hostname
+ # bonding
+ # FIXME: dracut has only BOND_OPTS
+ if ifcfg.get("BONDING_MASTER") == "yes" or ifcfg.get("TYPE") == "Bond":
+ slaves = get_bond_slaves_from_ifcfgs([ifcfg.iface, ifcfg.get("UUID")])
+ if slaves:
+ kwargs["bondslaves"] = ",".join(slaves)
+ bondopts = ifcfg.get("BONDING_OPTS")
+ if bondopts:
+ sep = ","
+ if sep in bondopts:
+ sep = ";"
+ kwargs["bondopts"] = sep.join(bondopts.split())
+
return handler.NetworkData(**kwargs)
+def get_bond_master_ifcfg_name(devname):
+ """Name of ifcfg file of bond device devname"""
+
+ for filename in _ifcfg_files(netscriptsDir):
+ ifcfg = NetworkDevice(netscriptsDir, filename[6:])
+ ifcfg.loadIfcfgFile()
+ # FIXME: dracut has only BOND_OPTS
+ if ifcfg.get("BONDING_MASTER") == "yes" or ifcfg.get("TYPE") == "Bond":
+ if ifcfg.get("DEVICE") == devname:
+ return filename
+
+def get_bond_slaves_from_ifcfgs(master_specs):
+ """List of slave device names of master specified by master_specs.
+
+ master_specs is a list containing device name of master (dracut)
+ and/or master's connection uuid
+ """
+ slaves = []
+
+ for filename in _ifcfg_files(netscriptsDir):
+ ifcfg = NetworkDevice(netscriptsDir, filename[6:])
+ ifcfg.loadIfcfgFile()
+ master = ifcfg.get("MASTER")
+ if master in master_specs:
+ device = ifcfg.get("DEVICE")
+ if device:
+ slaves.append(device)
+ else:
+ hwaddr = ifcfg.get("HWADDR")
+ for devname in nm.nm_devices():
+ try:
+ h = nm.nm_device_property(devname, "PermHwAddress")
+ except nm.PropertyNotFoundError:
+ pass
+ if h.upper() == hwaddr.upper():
+ slaves.append(devname)
+ break
+ return slaves
+
def ifaceForHostIP(host):
route = iutil.execWithCapture("ip", [ "route", "get", "to", host ])
if not route:
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py
index f1133cf..6f646ec 100644
--- a/pyanaconda/ui/gui/spokes/network.py
+++ b/pyanaconda/ui/gui/spokes/network.py
@@ -42,7 +42,7 @@ from pyanaconda.ui.gui.categories.software import SoftwareCategory
from pyanaconda.ui.gui.hubs.summary import SummaryHub
from pyanaconda.ui.gui.utils import gtk_call_once
-from pyanaconda.network import NetworkDevice, netscriptsDir, kickstartNetworkData, logIfcfgFiles, update_hostname_data, sanityCheckHostname, getHostname, DEFAULT_HOSTNAME
+from pyanaconda.network import NetworkDevice, netscriptsDir, kickstartNetworkData, logIfcfgFiles, update_hostname_data, sanityCheckHostname, getHostname, DEFAULT_HOSTNAME, get_bond_master_ifcfg_name
from pyanaconda.nm import nm_activated_devices
from gi.repository import GLib, GObject, Pango, Gio, NetworkManager, NMClient
@@ -1046,6 +1046,8 @@ class NetworkSpoke(NormalSpoke):
hostname = self.network_control_box.hostname
update_hostname_data(self.data, hostname)
+ log.debug("network: apply ksdata %s" % self.data.network)
+
@property
def completed(self):
# TODO: check also if source requires updates when implemented
@@ -1170,6 +1172,8 @@ class NetworkStandaloneSpoke(StandaloneSpoke):
hostname = self.network_control_box.hostname
update_hostname_data(self.data, hostname)
+ log.debug("network: apply ksdata %s" % self.data.network)
+
self._now_available = self.completed
log.debug("network standalone spoke (apply) payload: %s completed: %s" % (self.payload.baseRepo, self._now_available))
@@ -1226,6 +1230,8 @@ def getKSNetworkData(device):
ap = device.get_active_access_point()
if ap:
ifcfg_suffix = ap.get_ssid()
+ elif device.get_device_type() == NetworkManager.DeviceType.BOND:
+ ifcfg_suffix = get_bond_master_ifcfg_name(device.get_iface())[6:]
if ifcfg_suffix:
ifcfg_suffix = ifcfg_suffix.replace(' ', '_')
@@ -1236,7 +1242,7 @@ def getKSNetworkData(device):
log.debug("getKSNetworkData %s: %s" % (ifcfg_suffix, e))
return None
retval = kickstartNetworkData(ifcfg=device_cfg)
- if device.get_iface() in nm_activated_devices():
+ if retval and device.get_iface() in nm_activated_devices():
retval.activate = True
return retval
--
1.7.11.7
More information about the anaconda-patches
mailing list