The cleanup itself is in [1/7].
Then there are some patches fixing issues I came across while testing the patch (text mode, wifi, vlan, bonding, no link).
And a bit more of tui improvement and code consolidation in [6/7].
- Remove obsolete NetworkDevice class, use just IfcfgFile instead. - More robust lookup of ifcfg files of devices - based on values instead of relying on filename. --- pyanaconda/installclasses/fedora.py | 14 +- pyanaconda/network.py | 269 +++++++++++++++++------------------- pyanaconda/nm.py | 38 +++++ pyanaconda/simpleconfig.py | 34 ----- pyanaconda/ui/gui/spokes/network.py | 29 ++-- pyanaconda/ui/tui/spokes/network.py | 12 +- 6 files changed, 187 insertions(+), 209 deletions(-)
diff --git a/pyanaconda/installclasses/fedora.py b/pyanaconda/installclasses/fedora.py index 2977211..c433d49 100644 --- a/pyanaconda/installclasses/fedora.py +++ b/pyanaconda/installclasses/fedora.py @@ -63,15 +63,15 @@ class InstallClass(BaseInstallClass): except ValueError: continue if link_up: - dev = network.NetworkDevice(ROOT_PATH + network.netscriptsDir, devName) - try: - dev.loadIfcfgFile() - except IOError: + ifcfg_path = network.find_ifcfg_file_of_device(devName, root_path=ROOT_PATH) + if not ifcfg_path: continue - dev.set(('ONBOOT', 'yes')) - dev.writeIfcfgFile() + ifcfg = network.IfcfgFile(ifcfg_path) + ifcfg.read() + ifcfg.set(('ONBOOT', 'yes')) + ifcfg.write() for nd in ksdata.network.network: - if nd.device == dev.iface: + if nd.device == devName: nd.onboot = True break break diff --git a/pyanaconda/network.py b/pyanaconda/network.py index d21e9b0..9c526ad 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -35,7 +35,7 @@ import re import dbus import IPy
-from simpleconfig import IfcfgFile +from simpleconfig import SimpleConfigFile from blivet.devices import FcoeDiskDevice, iScsiDiskDevice import blivet.arch
@@ -209,81 +209,43 @@ def _ifcfg_files(directory): if name.startswith("ifcfg-"): if name == "ifcfg-lo": continue - rv.append(name) + rv.append(os.path.join(directory,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) + for path in _ifcfg_files(netscriptsDir): with open(path, "r") as f: content = f.read() ifcfglog.debug("%s:\n%s", path, content)
-class NetworkDevice(IfcfgFile): - - def __init__(self, directory, iface): - IfcfgFile.__init__(self, directory, iface) - if iface.startswith('ctc'): - self.info["TYPE"] = "CTC" - self.wepkey = "" +class IfcfgFile(SimpleConfigFile): + def __init__(self, filename): + SimpleConfigFile.__init__(self, always_quote=True, filename=filename) self._dirty = False
- def clear(self): - IfcfgFile.clear(self) - if self.iface.startswith('ctc'): - self.info["TYPE"] = "CTC" - self.wepkey = "" - - def __str__(self): - s = "" - keys = self.info.keys() - if blivet.arch.isS390() and ("HWADDR" in keys): - keys.remove("HWADDR") - # make sure we include autoneg in the ethtool line - if 'ETHTOOL_OPTS' in keys: - eopts = self.get('ETHTOOL_OPTS') - if "autoneg" not in eopts: - self.set(('ETHTOOL_OPTS', "autoneg off %s" % eopts)) - - for key in keys: - if self.info[key] is not None: - s = s + key + '="' + self.info[key] + '"\n' - - return s - - def loadIfcfgFile(self): - ifcfglog.debug("loadIfcfFile %s", self.path) - - self.clear() - IfcfgFile.read(self) + def read(self): + self.reset() + ifcfglog.debug("IfcfFile.read %s", self.filename) + SimpleConfigFile.read(self) self._dirty = False
- def writeIfcfgFile(self): - # Write out the file only if there is a key whose - # value has been changed since last load of ifcfg file. - ifcfglog.debug("writeIfcfgFile %s to %s%s", self.iface, self.path, - ("" if self._dirty else " not needed")) - if self._dirty: - ifcfglog.debug("old %s:\n%s", self.path, self.fileContent()) - ifcfglog.debug("writing NetworkDevice %s:\n%s", self.iface, self.__str__()) - IfcfgFile.write(self) + def write(self, filename=None): + if self._dirty or filename: + # ifcfg-rh is using inotify IN_CLOSE_WRITE event so we don't use + # temporary file for new configuration + ifcfglog.debug("IfcfgFile.write %s:\n%s", self.filename, self.__str__()) + SimpleConfigFile.write(self, filename, use_tmp=False) self._dirty = False
- # We can't read the file right now racing with ifcfg-rh update - #ifcfglog.debug("%s:\n%s" % (device.path, device.fileContent())) - def set(self, *args): - # If we are changing value of a key set _dirty flag - # informing that ifcfg file needs to be synced. - s = " ".join("%s=%s" % key_val for key_val in args) - ifcfglog.debug("NetworkDevice %s set: %s", self.iface, s) for (key, data) in args: if self.get(key) != data: break else: return - IfcfgFile.set(self, *args) + ifcfglog.debug("IfcfgFile.set %s: %s", self.filename, args) + SimpleConfigFile.set(self, *args) self._dirty = True
def unset(self, *args): @@ -293,19 +255,8 @@ class NetworkDevice(IfcfgFile): break else: return - IfcfgFile.unset(self, *args) - - @property - def keyfilePath(self): - return os.path.join(self.dir, "keys-%s" % self.iface) - - def fileContent(self): - if not os.path.exists(self.path): - return "" - f = open(self.path, 'r') - content = f.read() - f.close() - return content + ifcfglog.debug("IfcfgFile.unset %s: %s", self.filename, args) + SimpleConfigFile.unset(self, *args)
def dumpMissingDefaultIfcfgs(): """ @@ -331,7 +282,7 @@ def dumpMissingDefaultIfcfgs(): con_uuid = nm.nm_device_setting_value(devname, "connection", "uuid") except nm.DeviceSettingsNotFoundError: continue - if get_ifcfg_name([("UUID", con_uuid)], root_path=""): + if find_ifcfg_file([("UUID", con_uuid)], root_path=""): continue
try: @@ -348,6 +299,7 @@ def dumpMissingDefaultIfcfgs(): # get a kernel cmdline string for dracut needed for access to storage host def dracutSetupArgs(networkStorageDevice):
+ import pdb; pdb.set_trace() if networkStorageDevice.nic == "default" or ":" in networkStorageDevice.nic: nic = ifaceForHostIP(networkStorageDevice.host_address) if not nic: @@ -359,16 +311,20 @@ def dracutSetupArgs(networkStorageDevice): log.error('Unknown network interface: %s', nic) return ""
- ifcfg = NetworkDevice(netscriptsDir, nic) - ifcfg.loadIfcfgFile() - return dracutBootArguments(ifcfg, + ifcfg_path = find_ifcfg_file_of_device(nic) + if not ifcfg_path: + log.error("dracutSetupArgs: can't find ifcfg file for %s", nic) + return "" + ifcfg = IfcfgFile(ifcfg_path) + ifcfg.read() + return dracutBootArguments(nic, + ifcfg, networkStorageDevice.host_address, getHostname())
-def dracutBootArguments(ifcfg, storage_ipaddr, hostname=None): +def dracutBootArguments(devname, ifcfg, storage_ipaddr, hostname=None):
netargs = set() - devname = ifcfg.iface
if ifcfg.get('BOOTPROTO') == 'ibft': netargs.add("ip=ibft") @@ -424,23 +380,6 @@ def dracutBootArguments(ifcfg, storage_ipaddr, hostname=None):
return netargs
-def get_ks_network_data(devname, ifcfg_suffix=None): - retval = None - ifcfg_suffix = ifcfg_suffix or devname - - ifcfg_suffix = ifcfg_suffix.replace(' ', '_') - device_cfg = NetworkDevice(netscriptsDir, ifcfg_suffix) - try: - device_cfg.loadIfcfgFile() - except IOError as e: - log.debug("get_ks_network_data %s: %s", ifcfg_suffix, e) - return None - retval = kickstartNetworkData(ifcfg=device_cfg) - if retval and devname in nm.nm_activated_devices(): - retval.activate = True - - return retval - def update_settings_with_ksdata(devname, networkdata):
new_values = [] @@ -499,28 +438,56 @@ def update_settings_with_ksdata(devname, networkdata):
nm.nm_update_settings_of_device(devname, new_values)
-def kickstartNetworkData(ifcfg=None, hostname=None): +def ksdata_from_ifcfg(devname): + + ifcfg_path = None + if nm.nm_device_type_is_ethernet(devname): + ifcfg_path = find_ifcfg_file_of_device(devname) + elif nm.nm_device_type_is_wifi(devname): + ssid = nm.nm_device_active_ssid(devname) + if ssid: + ifcfg_path = find_ifcfg_file([("ESSID", ssid)]) + elif nm.nm_device_type_is_bond(devname): + ifcfg_path = find_ifcfg_file([("DEVICE", devname)]) + elif nm.nm_device_type_is_vlan(devname): + ifcfg_path = find_ifcfg_file([("DEVICE", devname)]) + + if not ifcfg_path: + return None + + ifcfg = IfcfgFile(ifcfg_path) + ifcfg.read() + nd = ifcfg_to_ksdata(ifcfg, devname) + + if not nd: + return None + + if nm.nm_device_type_is_ethernet(devname): + nd.device = devname + elif nm.nm_device_type_is_wifi(devname): + nm.device = "" + elif nm.nm_device_type_is_bond(devname): + nd.device = devname + elif nm.nm_device_type_is_vlan(devname): + nd.device = devname.split(".")[0] + + return nd + +def ifcfg_to_ksdata(ifcfg, devname):
from pyanaconda.kickstart import AnacondaKSHandler handler = AnacondaKSHandler() kwargs = {}
- if not ifcfg and hostname: - # pylint: disable-msg=E1101 - 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 if ifcfg.get("ONBOOT") and ifcfg.get("ONBOOT" ) == "no": kwargs["onboot"] = False if ifcfg.get('MTU') and ifcfg.get('MTU') != "0": kwargs["mtu"] = ifcfg.get('MTU') - # ipv4 if not ifcfg.get('BOOTPROTO'): kwargs["noipv4"] = True @@ -589,15 +556,11 @@ def kickstartNetworkData(ifcfg=None, hostname=None): # hostname if ifcfg.get("DHCP_HOSTNAME"): kwargs["hostname"] = ifcfg.get("DHCP_HOSTNAME") - elif iutil.lowerASCII(ifcfg.get("BOOTPROTO")) != "dhcp": - if (hostname and - 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")]) + slaves = get_bond_slaves_from_ifcfgs([devname, ifcfg.get("UUID")]) if slaves: kwargs["bondslaves"] = ",".join(slaves) bondopts = ifcfg.get("BONDING_OPTS") @@ -615,23 +578,40 @@ def kickstartNetworkData(ifcfg=None, hostname=None): # pylint: disable-msg=E1101 return handler.NetworkData(**kwargs)
-def get_ifcfg_name(values, root_path=""): - for filename in _ifcfg_files(os.path.normpath(root_path+netscriptsDir)): - ifcfg = NetworkDevice(netscriptsDir, filename[6:]) - ifcfg.loadIfcfgFile() +def hostname_ksdata(hostname): + from pyanaconda.kickstart import AnacondaKSHandler + handler = AnacondaKSHandler() + kwargs = {} + # pylint: disable-msg=E1101 + return handler.NetworkData(hostname=hostname, bootProto="") + +def find_ifcfg_file_of_device(devname, root_path=""): + ifcfg_path = None + try: + hwaddr = nm.nm_device_hwaddress(devname) + except nm.PropertyNotFoundError: + hwaddr = None + if hwaddr: + hwaddr_check = lambda mac: mac.upper() == hwaddr.upper() + ifcfg_path = find_ifcfg_file([("HWADDR", hwaddr_check)]) + if not ifcfg_path: + ifcfg_path = find_ifcfg_file([("DEVICE", devname)]) + return ifcfg_path + +def find_ifcfg_file(values, root_path=""): + for filepath in _ifcfg_files(os.path.normpath(root_path+netscriptsDir)): + ifcfg = IfcfgFile(filepath) + ifcfg.read() for key, value in values: - if ifcfg.get(key) != value: - break + if callable(value): + if not value(ifcfg.get(key)): + break + else: + if ifcfg.get(key) != value: + break else: - return filename - -def get_bond_master_ifcfg_name(devname): - """Name of ifcfg file of bond device devname""" - return get_ifcfg_name([("TYPE", "Bond"), ("DEVICE", devname)]) - -def get_vlan_ifcfg_name(devname): - """Name of ifcfg file of vlan device devname""" - return get_ifcfg_name([("TYPE", "Vlan"), ("DEVICE", devname)]) + return filepath + return None
def get_bond_slaves_from_ifcfgs(master_specs): """List of slave device names of master specified by master_specs. @@ -641,9 +621,9 @@ def get_bond_slaves_from_ifcfgs(master_specs): """ slaves = []
- for filename in _ifcfg_files(netscriptsDir): - ifcfg = NetworkDevice(netscriptsDir, filename[6:]) - ifcfg.loadIfcfgFile() + for filepath in _ifcfg_files(netscriptsDir): + ifcfg = IfcfgFile(filepath) + ifcfg.read() master = ifcfg.get("MASTER") if master in master_specs: device = ifcfg.get("DEVICE") @@ -781,33 +761,36 @@ def disableNMForStorageDevices(rootpath, storage): for devname in nm.nm_devices(): if (usedByFCoE(devname, storage) or usedByRootOnISCSI(devname, storage)): - dev = NetworkDevice(rootpath + netscriptsDir, devname) - if os.access(dev.path, os.R_OK): - dev.loadIfcfgFile() - dev.set(('NM_CONTROLLED', 'no')) - dev.writeIfcfgFile() - log.info("network device %s used by storage will not be " - "controlled by NM", devname) - else: + ifcfg_path = find_ifcfg_file_of_device(devname, root_path=rootpath) + if not ifcfg_path: log.warning("disableNMForStorageDevices: ifcfg file for %s not found", devname) + continue + ifcfg = IfcfgFile(ifcfg_path) + ifcfg.read() + ifcfg.set(('NM_CONTROLLED', 'no')) + ifcfg.write() + log.info("network device %s used by storage will not be " + "controlled by NM", devname)
# sets ONBOOT=yes (and its mirror value in ksdata) for devices used by FCoE def autostartFCoEDevices(rootpath, storage, ksdata): for devname in nm.nm_devices(): if usedByFCoE(devname, storage): - dev = NetworkDevice(rootpath + netscriptsDir, devname) - if os.access(dev.path, os.R_OK): - dev.loadIfcfgFile() - dev.set(('ONBOOT', 'yes')) - dev.writeIfcfgFile() - log.debug("setting ONBOOT=yes for network device %s used by fcoe", devname) - for nd in ksdata.network.network: - if nd.device == dev.iface: - nd.onboot = True - break - else: + ifcfg_path = find_ifcfg_file_of_device(devname, root_path=rootpath) + if not ifcfg_path: log.warning("autoconnectFCoEDevices: ifcfg file for %s not found", devname) + continue + + ifcfg = IfcfgFile(ifcfg_path) + ifcfg.read() + ifcfg.set(('ONBOOT', 'yes')) + ifcfg.write() + log.debug("setting ONBOOT=yes for network device %s used by fcoe", devname) + for nd in ksdata.network.network: + if nd.device == devname: + nd.onboot = True + break
def usedByFCoE(iface, storage): for d in storage.devices: @@ -863,7 +846,7 @@ def update_hostname_data(ksdata, hostname): nd.hostname = hostname hostname_found = True if not hostname_found: - nd = kickstartNetworkData(hostname=hostname) + nd = hostname_ksdata(hostname) ksdata.network.network.append(nd)
def get_device_name(devspec): diff --git a/pyanaconda/nm.py b/pyanaconda/nm.py index a53ffe0..ae0b9cd 100644 --- a/pyanaconda/nm.py +++ b/pyanaconda/nm.py @@ -233,6 +233,24 @@ def nm_device_type_is_ethernet(name): """ return nm_device_type(name) == NetworkManager.DeviceType.ETHERNET
+def nm_device_type_is_bond(name): + """Is the type of device bond? + + Exceptions: + UnknownDeviceError if device is not found + PropertyNotFoundError if type is not found + """ + return nm_device_type(name) == NetworkManager.DeviceType.BOND + +def nm_device_type_is_vlan(name): + """Is the type of device vlan? + + Exceptions: + UnknownDeviceError if device is not found + PropertyNotFoundError if type is not found + """ + return nm_device_type(name) == NetworkManager.DeviceType.VLAN + def nm_device_hwaddress(name): """Return device's 'HwAddress' property
@@ -277,6 +295,26 @@ def nm_device_ip_addresses(name, version=4):
return retval
+def nm_device_active_ssid(name): + """Return ssid of device's active access point. + + Exceptions: + UnknownDeviceError if device is not found + """ + + try: + aap = nm_device_property(name, "ActiveAccessPoint") + except PropertyNotFoundError: + return None + + if aap == "/": + return None + + ssid_ay = _get_property(aap, "Ssid", ".AccessPoint") + ssid = "".join(chr(b) for b in ssid_ay) + + return ssid + def nm_device_ip_config(name, version=4): """Return list of devices's IP config
diff --git a/pyanaconda/simpleconfig.py b/pyanaconda/simpleconfig.py index 1d3aee2..42773ac 100644 --- a/pyanaconda/simpleconfig.py +++ b/pyanaconda/simpleconfig.py @@ -159,37 +159,3 @@ class SimpleConfigFile(object):
return s
- -class IfcfgFile(SimpleConfigFile): - def __init__(self, directory, iface): - SimpleConfigFile.__init__(self, always_quote=True) - self.iface = iface - self.dir = directory - - @property - def path(self): - return os.path.join(self.dir, "ifcfg-%s" % self.iface) - - def clear(self): - SimpleConfigFile.reset(self) - - def read(self, filename=None): - """ Reads values from ifcfg file. - - returns: number of values read - """ - SimpleConfigFile.read(self, self.path) - return len(self.info) - - def write(self, directory=None): - """ Writes values into ifcfg file. - """ - - if not directory: - path = self.path - else: - path = os.path.join(directory, os.path.basename(self.path)) - - # ifcfg-rh is using inotify IN_CLOSE_WRITE event so we don't use - # temporary file for new configuration - SimpleConfigFile.write(self, path, use_tmp=False) diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index 5963e6f..372602e 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -43,7 +43,7 @@ from pyanaconda.ui.gui.utils import gtk_call_once, enlightbox from pyanaconda.ui.common import FirstbootSpokeMixIn
from pyanaconda import network -from pyanaconda.nm import nm_device_setting_value, nm_device_ip_config +from pyanaconda.nm import nm_device_setting_value, nm_device_ip_config, nm_activated_devices
from gi.repository import GLib, GObject, Pango, Gio, NetworkManager, NMClient import dbus @@ -1482,29 +1482,16 @@ class NetworkStandaloneSpoke(StandaloneSpoke): def _update_network_data(data, ncb): data.network.network = [] for dev in ncb.listed_devices: - network_data = None - ifcfg_suffix = _ifcfg_suffix(dev) - if ifcfg_suffix: - network_data = network.get_ks_network_data(dev, ifcfg_suffix) - if network_data is not None: - data.network.network.append(network_data) + devname = dev.get_iface() + nd = network.ksdata_from_ifcfg(devname) + if not nd: + continue + if devname in nm_activated_devices(): + nd.activate = True + data.network.network.append(nd) hostname = ncb.hostname network.update_hostname_data(data, hostname)
-def _ifcfg_suffix(device): - retval = None - if device.get_device_type() == NetworkManager.DeviceType.ETHERNET: - retval = device.get_iface() - elif device.get_device_type() == NetworkManager.DeviceType.WIFI: - ap = device.get_active_access_point() - if ap: - retval = ap.get_ssid() - elif device.get_device_type() == NetworkManager.DeviceType.BOND: - retval = network.get_bond_master_ifcfg_name(device.get_iface())[6:] - elif device.get_device_type() == NetworkManager.DeviceType.VLAN: - retval = network.get_vlan_ifcfg_name(device.get_iface())[6:] - return retval - def test(): win = Gtk.Window() win.connect("delete-event", Gtk.main_quit) diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py index a432bcb..f14d42a 100644 --- a/pyanaconda/ui/tui/spokes/network.py +++ b/pyanaconda/ui/tui/spokes/network.py @@ -28,6 +28,7 @@ from pyanaconda.ui.tui.simpleline import TextWidget, ColumnWidget from pyanaconda.i18n import _ from pyanaconda import network from pyanaconda.nm import nm_activated_devices, nm_state, nm_devices, nm_device_type_is_ethernet, nm_device_ip_config, nm_activate_device_connection, nm_device_setting_value + from pyanaconda.regexes import IPV4_PATTERN_WITHOUT_ANCHORS from pyanaconda.constants_text import INPUT_PROCESSED
@@ -189,7 +190,7 @@ class NetworkSpoke(EditTUISpoke): elif 2 <= num <= len(self.supported_devices) + 1: # configure device devname = self.supported_devices[num-2] - ndata = network.get_ks_network_data(devname) + ndata = network.ksdata_from_ifcfg(devname) newspoke = ConfigureNetworkSpoke(self.app, self.data, self.storage, self.payload, self.instclass, ndata) self.app.switch_screen_modal(newspoke) @@ -229,9 +230,12 @@ class NetworkSpoke(EditTUISpoke):
self.data.network.network = [] for name in self.supported_devices: - network_data = network.get_ks_network_data(name) - if network_data is not None: - self.data.network.network.append(network_data) + nd = network.ksdata_from_ifcfg(name) + if not nd: + continue + if name in nm_activated_devices(): + nd.activate = True + self.data.network.network.append(nd)
(valid, error) = network.sanityCheckHostname(self.hostname_dialog.value) if valid:
On Fri, 2013-09-13 at 15:32 +0200, Radek Vykydal wrote:
- Remove obsolete NetworkDevice class, use just IfcfgFile instead.
- More robust lookup of ifcfg files of devices - based on values
instead of relying on filename.
pyanaconda/installclasses/fedora.py | 14 +- pyanaconda/network.py | 269 +++++++++++++++++------------------- pyanaconda/nm.py | 38 +++++ pyanaconda/simpleconfig.py | 34 ----- pyanaconda/ui/gui/spokes/network.py | 29 ++-- pyanaconda/ui/tui/spokes/network.py | 12 +- 6 files changed, 187 insertions(+), 209 deletions(-)
diff --git a/pyanaconda/installclasses/fedora.py b/pyanaconda/installclasses/fedora.py index 2977211..c433d49 100644 --- a/pyanaconda/installclasses/fedora.py +++ b/pyanaconda/installclasses/fedora.py @@ -63,15 +63,15 @@ class InstallClass(BaseInstallClass): except ValueError: continue if link_up:
dev = network.NetworkDevice(ROOT_PATH + network.netscriptsDir, devName)try:dev.loadIfcfgFile()except IOError:
ifcfg_path = network.find_ifcfg_file_of_device(devName, root_path=ROOT_PATH)if not ifcfg_path: continue
dev.set(('ONBOOT', 'yes'))dev.writeIfcfgFile()
ifcfg = network.IfcfgFile(ifcfg_path)ifcfg.read()ifcfg.set(('ONBOOT', 'yes'))ifcfg.write() for nd in ksdata.network.network:
if nd.device == dev.iface:
if nd.device == devName: nd.onboot = True break breakdiff --git a/pyanaconda/network.py b/pyanaconda/network.py index d21e9b0..9c526ad 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -35,7 +35,7 @@ import re import dbus import IPy
-from simpleconfig import IfcfgFile +from simpleconfig import SimpleConfigFile from blivet.devices import FcoeDiskDevice, iScsiDiskDevice import blivet.arch
@@ -209,81 +209,43 @@ def _ifcfg_files(directory): if name.startswith("ifcfg-"): if name == "ifcfg-lo": continue
rv.append(name)
return rvrv.append(os.path.join(directory,name))def logIfcfgFiles(message=""): ifcfglog.debug("content of files (%s):", message)
- for name in _ifcfg_files(netscriptsDir):
path = os.path.join(netscriptsDir, name)
- for path in _ifcfg_files(netscriptsDir): with open(path, "r") as f: content = f.read() ifcfglog.debug("%s:\n%s", path, content)
-class NetworkDevice(IfcfgFile):
- def __init__(self, directory, iface):
IfcfgFile.__init__(self, directory, iface)if iface.startswith('ctc'):self.info["TYPE"] = "CTC"self.wepkey = ""+class IfcfgFile(SimpleConfigFile):
- def __init__(self, filename):
SimpleConfigFile.__init__(self, always_quote=True, filename=filename) self._dirty = False
- def clear(self):
IfcfgFile.clear(self)if self.iface.startswith('ctc'):self.info["TYPE"] = "CTC"self.wepkey = ""- def __str__(self):
s = ""keys = self.info.keys()if blivet.arch.isS390() and ("HWADDR" in keys):keys.remove("HWADDR")# make sure we include autoneg in the ethtool lineif 'ETHTOOL_OPTS' in keys:eopts = self.get('ETHTOOL_OPTS')if "autoneg" not in eopts:self.set(('ETHTOOL_OPTS', "autoneg off %s" % eopts))for key in keys:if self.info[key] is not None:s = s + key + '="' + self.info[key] + '"\n'return s- def loadIfcfgFile(self):
ifcfglog.debug("loadIfcfFile %s", self.path)self.clear()IfcfgFile.read(self)
- def read(self):
self.reset()ifcfglog.debug("IfcfFile.read %s", self.filename)SimpleConfigFile.read(self) self._dirty = False
- def writeIfcfgFile(self):
# Write out the file only if there is a key whose# value has been changed since last load of ifcfg file.ifcfglog.debug("writeIfcfgFile %s to %s%s", self.iface, self.path,("" if self._dirty else " not needed"))if self._dirty:ifcfglog.debug("old %s:\n%s", self.path, self.fileContent())ifcfglog.debug("writing NetworkDevice %s:\n%s", self.iface, self.__str__())IfcfgFile.write(self)
- def write(self, filename=None):
if self._dirty or filename:# ifcfg-rh is using inotify IN_CLOSE_WRITE event so we don't use# temporary file for new configurationifcfglog.debug("IfcfgFile.write %s:\n%s", self.filename, self.__str__())SimpleConfigFile.write(self, filename, use_tmp=False) self._dirty = False
# We can't read the file right now racing with ifcfg-rh update#ifcfglog.debug("%s:\n%s" % (device.path, device.fileContent()))- def set(self, *args):
# If we are changing value of a key set _dirty flag# informing that ifcfg file needs to be synced.s = " ".join("%s=%s" % key_val for key_val in args)ifcfglog.debug("NetworkDevice %s set: %s", self.iface, s) for (key, data) in args: if self.get(key) != data: break else: returnIfcfgFile.set(self, *args)
ifcfglog.debug("IfcfgFile.set %s: %s", self.filename, args)SimpleConfigFile.set(self, *args) self._dirty = Truedef unset(self, *args):
@@ -293,19 +255,8 @@ class NetworkDevice(IfcfgFile): break else: return
IfcfgFile.unset(self, *args)- @property
- def keyfilePath(self):
return os.path.join(self.dir, "keys-%s" % self.iface)- def fileContent(self):
if not os.path.exists(self.path):return ""f = open(self.path, 'r')content = f.read()f.close()return content
ifcfglog.debug("IfcfgFile.unset %s: %s", self.filename, args)SimpleConfigFile.unset(self, *args)def dumpMissingDefaultIfcfgs(): """ @@ -331,7 +282,7 @@ def dumpMissingDefaultIfcfgs(): con_uuid = nm.nm_device_setting_value(devname, "connection", "uuid") except nm.DeviceSettingsNotFoundError: continue
if get_ifcfg_name([("UUID", con_uuid)], root_path=""):
if find_ifcfg_file([("UUID", con_uuid)], root_path=""): continue try:@@ -348,6 +299,7 @@ def dumpMissingDefaultIfcfgs(): # get a kernel cmdline string for dracut needed for access to storage host def dracutSetupArgs(networkStorageDevice):
- import pdb; pdb.set_trace()
Maybe this could go away before pushing. :)
On Fri, Sep 13, 2013 at 03:32:15PM +0200, Radek Vykydal wrote:
- Remove obsolete NetworkDevice class, use just IfcfgFile instead.
- More robust lookup of ifcfg files of devices - based on values
instead of relying on filename.
pyanaconda/installclasses/fedora.py | 14 +- pyanaconda/network.py | 269 +++++++++++++++++------------------- pyanaconda/nm.py | 38 +++++ pyanaconda/simpleconfig.py | 34 ----- pyanaconda/ui/gui/spokes/network.py | 29 ++-- pyanaconda/ui/tui/spokes/network.py | 12 +- 6 files changed, 187 insertions(+), 209 deletions(-)
diff --git a/pyanaconda/installclasses/fedora.py b/pyanaconda/installclasses/fedora.py index 2977211..c433d49 100644 --- a/pyanaconda/installclasses/fedora.py +++ b/pyanaconda/installclasses/fedora.py @@ -63,15 +63,15 @@ class InstallClass(BaseInstallClass): except ValueError: continue if link_up:
dev = network.NetworkDevice(ROOT_PATH + network.netscriptsDir, devName)try:dev.loadIfcfgFile()except IOError:
ifcfg_path = network.find_ifcfg_file_of_device(devName, root_path=ROOT_PATH)if not ifcfg_path: continue
dev.set(('ONBOOT', 'yes'))dev.writeIfcfgFile()
ifcfg = network.IfcfgFile(ifcfg_path)ifcfg.read()ifcfg.set(('ONBOOT', 'yes'))ifcfg.write() for nd in ksdata.network.network:
if nd.device == dev.iface:
if nd.device == devName: nd.onboot = True break breakdiff --git a/pyanaconda/network.py b/pyanaconda/network.py index d21e9b0..9c526ad 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -35,7 +35,7 @@ import re import dbus import IPy
-from simpleconfig import IfcfgFile +from simpleconfig import SimpleConfigFile from blivet.devices import FcoeDiskDevice, iScsiDiskDevice import blivet.arch
@@ -209,81 +209,43 @@ def _ifcfg_files(directory): if name.startswith("ifcfg-"): if name == "ifcfg-lo": continue
rv.append(name)
return rvrv.append(os.path.join(directory,name))def logIfcfgFiles(message=""): ifcfglog.debug("content of files (%s):", message)
- for name in _ifcfg_files(netscriptsDir):
path = os.path.join(netscriptsDir, name)
- for path in _ifcfg_files(netscriptsDir): with open(path, "r") as f: content = f.read() ifcfglog.debug("%s:\n%s", path, content)
-class NetworkDevice(IfcfgFile):
- def __init__(self, directory, iface):
IfcfgFile.__init__(self, directory, iface)if iface.startswith('ctc'):self.info["TYPE"] = "CTC"self.wepkey = ""+class IfcfgFile(SimpleConfigFile):
- def __init__(self, filename):
SimpleConfigFile.__init__(self, always_quote=True, filename=filename) self._dirty = False
- def clear(self):
IfcfgFile.clear(self)if self.iface.startswith('ctc'):self.info["TYPE"] = "CTC"self.wepkey = ""- def __str__(self):
s = ""keys = self.info.keys()if blivet.arch.isS390() and ("HWADDR" in keys):keys.remove("HWADDR")# make sure we include autoneg in the ethtool lineif 'ETHTOOL_OPTS' in keys:eopts = self.get('ETHTOOL_OPTS')if "autoneg" not in eopts:self.set(('ETHTOOL_OPTS', "autoneg off %s" % eopts))for key in keys:if self.info[key] is not None:s = s + key + '="' + self.info[key] + '"\n'return s- def loadIfcfgFile(self):
ifcfglog.debug("loadIfcfFile %s", self.path)self.clear()IfcfgFile.read(self)
- def read(self):
self.reset()ifcfglog.debug("IfcfFile.read %s", self.filename)SimpleConfigFile.read(self) self._dirty = False
- def writeIfcfgFile(self):
# Write out the file only if there is a key whose# value has been changed since last load of ifcfg file.ifcfglog.debug("writeIfcfgFile %s to %s%s", self.iface, self.path,("" if self._dirty else " not needed"))if self._dirty:ifcfglog.debug("old %s:\n%s", self.path, self.fileContent())ifcfglog.debug("writing NetworkDevice %s:\n%s", self.iface, self.__str__())IfcfgFile.write(self)
- def write(self, filename=None):
if self._dirty or filename:# ifcfg-rh is using inotify IN_CLOSE_WRITE event so we don't use# temporary file for new configurationifcfglog.debug("IfcfgFile.write %s:\n%s", self.filename, self.__str__())SimpleConfigFile.write(self, filename, use_tmp=False) self._dirty = False
# We can't read the file right now racing with ifcfg-rh update#ifcfglog.debug("%s:\n%s" % (device.path, device.fileContent()))- def set(self, *args):
# If we are changing value of a key set _dirty flag# informing that ifcfg file needs to be synced.s = " ".join("%s=%s" % key_val for key_val in args)ifcfglog.debug("NetworkDevice %s set: %s", self.iface, s) for (key, data) in args: if self.get(key) != data: break else: returnIfcfgFile.set(self, *args)
ifcfglog.debug("IfcfgFile.set %s: %s", self.filename, args)SimpleConfigFile.set(self, *args) self._dirty = Truedef unset(self, *args):
@@ -293,19 +255,8 @@ class NetworkDevice(IfcfgFile): break else: return
IfcfgFile.unset(self, *args)- @property
- def keyfilePath(self):
return os.path.join(self.dir, "keys-%s" % self.iface)- def fileContent(self):
if not os.path.exists(self.path):return ""f = open(self.path, 'r')content = f.read()f.close()return content
ifcfglog.debug("IfcfgFile.unset %s: %s", self.filename, args)SimpleConfigFile.unset(self, *args)def dumpMissingDefaultIfcfgs(): """ @@ -331,7 +282,7 @@ def dumpMissingDefaultIfcfgs(): con_uuid = nm.nm_device_setting_value(devname, "connection", "uuid") except nm.DeviceSettingsNotFoundError: continue
if get_ifcfg_name([("UUID", con_uuid)], root_path=""):
if find_ifcfg_file([("UUID", con_uuid)], root_path=""): continue try:@@ -348,6 +299,7 @@ def dumpMissingDefaultIfcfgs(): # get a kernel cmdline string for dracut needed for access to storage host def dracutSetupArgs(networkStorageDevice):
- import pdb; pdb.set_trace() if networkStorageDevice.nic == "default" or ":" in networkStorageDevice.nic: nic = ifaceForHostIP(networkStorageDevice.host_address) if not nic:
@@ -359,16 +311,20 @@ def dracutSetupArgs(networkStorageDevice): log.error('Unknown network interface: %s', nic) return ""
- ifcfg = NetworkDevice(netscriptsDir, nic)
- ifcfg.loadIfcfgFile()
- return dracutBootArguments(ifcfg,
- ifcfg_path = find_ifcfg_file_of_device(nic)
- if not ifcfg_path:
log.error("dracutSetupArgs: can't find ifcfg file for %s", nic)return ""- ifcfg = IfcfgFile(ifcfg_path)
- ifcfg.read()
- return dracutBootArguments(nic,
ifcfg, networkStorageDevice.host_address, getHostname())-def dracutBootArguments(ifcfg, storage_ipaddr, hostname=None): +def dracutBootArguments(devname, ifcfg, storage_ipaddr, hostname=None):
netargs = set()
devname = ifcfg.iface
if ifcfg.get('BOOTPROTO') == 'ibft': netargs.add("ip=ibft")
@@ -424,23 +380,6 @@ def dracutBootArguments(ifcfg, storage_ipaddr, hostname=None):
return netargs-def get_ks_network_data(devname, ifcfg_suffix=None):
- retval = None
- ifcfg_suffix = ifcfg_suffix or devname
- ifcfg_suffix = ifcfg_suffix.replace(' ', '_')
- device_cfg = NetworkDevice(netscriptsDir, ifcfg_suffix)
- try:
device_cfg.loadIfcfgFile()- except IOError as e:
log.debug("get_ks_network_data %s: %s", ifcfg_suffix, e)return None- retval = kickstartNetworkData(ifcfg=device_cfg)
- if retval and devname in nm.nm_activated_devices():
retval.activate = True- return retval
def update_settings_with_ksdata(devname, networkdata):
new_values = []@@ -499,28 +438,56 @@ def update_settings_with_ksdata(devname, networkdata):
nm.nm_update_settings_of_device(devname, new_values)-def kickstartNetworkData(ifcfg=None, hostname=None): +def ksdata_from_ifcfg(devname):
- ifcfg_path = None
- if nm.nm_device_type_is_ethernet(devname):
ifcfg_path = find_ifcfg_file_of_device(devname)- elif nm.nm_device_type_is_wifi(devname):
ssid = nm.nm_device_active_ssid(devname)if ssid:ifcfg_path = find_ifcfg_file([("ESSID", ssid)])- elif nm.nm_device_type_is_bond(devname):
ifcfg_path = find_ifcfg_file([("DEVICE", devname)])- elif nm.nm_device_type_is_vlan(devname):
ifcfg_path = find_ifcfg_file([("DEVICE", devname)])- if not ifcfg_path:
return None- ifcfg = IfcfgFile(ifcfg_path)
- ifcfg.read()
- nd = ifcfg_to_ksdata(ifcfg, devname)
- if not nd:
return None- if nm.nm_device_type_is_ethernet(devname):
nd.device = devname- elif nm.nm_device_type_is_wifi(devname):
nm.device = ""- elif nm.nm_device_type_is_bond(devname):
nd.device = devname- elif nm.nm_device_type_is_vlan(devname):
nd.device = devname.split(".")[0]- return nd
+def ifcfg_to_ksdata(ifcfg, devname):
from pyanaconda.kickstart import AnacondaKSHandler handler = AnacondaKSHandler() kwargs = {}
if not ifcfg and hostname:
# pylint: disable-msg=E1101return 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.ifaceif ifcfg.get("ONBOOT") and ifcfg.get("ONBOOT" ) == "no": kwargs["onboot"] = False if ifcfg.get('MTU') and ifcfg.get('MTU') != "0": kwargs["mtu"] = ifcfg.get('MTU')
# ipv4 if not ifcfg.get('BOOTPROTO'): kwargs["noipv4"] = True
@@ -589,15 +556,11 @@ def kickstartNetworkData(ifcfg=None, hostname=None): # hostname if ifcfg.get("DHCP_HOSTNAME"): kwargs["hostname"] = ifcfg.get("DHCP_HOSTNAME")
elif iutil.lowerASCII(ifcfg.get("BOOTPROTO")) != "dhcp":
if (hostname andhostname != 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")])
slaves = get_bond_slaves_from_ifcfgs([devname, ifcfg.get("UUID")]) if slaves: kwargs["bondslaves"] = ",".join(slaves) bondopts = ifcfg.get("BONDING_OPTS")@@ -615,23 +578,40 @@ def kickstartNetworkData(ifcfg=None, hostname=None): # pylint: disable-msg=E1101 return handler.NetworkData(**kwargs)
-def get_ifcfg_name(values, root_path=""):
- for filename in _ifcfg_files(os.path.normpath(root_path+netscriptsDir)):
ifcfg = NetworkDevice(netscriptsDir, filename[6:])ifcfg.loadIfcfgFile()+def hostname_ksdata(hostname):
- from pyanaconda.kickstart import AnacondaKSHandler
- handler = AnacondaKSHandler()
- kwargs = {}
- # pylint: disable-msg=E1101
- return handler.NetworkData(hostname=hostname, bootProto="")
+def find_ifcfg_file_of_device(devname, root_path=""):
- ifcfg_path = None
- try:
hwaddr = nm.nm_device_hwaddress(devname)- except nm.PropertyNotFoundError:
hwaddr = None- if hwaddr:
hwaddr_check = lambda mac: mac.upper() == hwaddr.upper()ifcfg_path = find_ifcfg_file([("HWADDR", hwaddr_check)])- if not ifcfg_path:
ifcfg_path = find_ifcfg_file([("DEVICE", devname)])- return ifcfg_path
It doesn't look like root_path is ever used in this function, can it just be removed from the signature completely (and following that, from every instance where the function gets called)?
Samantha
On 09/13/2013 05:30 PM, Samantha N. Bueno wrote:
On Fri, Sep 13, 2013 at 03:32:15PM +0200, Radek Vykydal wrote:
+def find_ifcfg_file_of_device(devname, root_path=""):
- ifcfg_path = None
- try:
hwaddr = nm.nm_device_hwaddress(devname)- except nm.PropertyNotFoundError:
hwaddr = None- if hwaddr:
hwaddr_check = lambda mac: mac.upper() == hwaddr.upper()ifcfg_path = find_ifcfg_file([("HWADDR", hwaddr_check)])- if not ifcfg_path:
ifcfg_path = find_ifcfg_file([("DEVICE", devname)])- return ifcfg_path
It doesn't look like root_path is ever used in this function, can it just be removed from the signature completely (and following that, from every instance where the function gets called)?
I should pass the root_path to find_ifcfg_file (it is actually used eg for disableNMForStorageDevices where we work with ifcfg files on target system ('/mnt/sysimage'). Thanks for the catch.
Radek
--- pyanaconda/ui/tui/spokes/network.py | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py index f14d42a..f470416 100644 --- a/pyanaconda/ui/tui/spokes/network.py +++ b/pyanaconda/ui/tui/spokes/network.py @@ -55,6 +55,9 @@ class NetworkSpoke(EditTUISpoke): def initialize(self): for name in nm_devices(): if nm_device_type_is_ethernet(name): + # ignore slaves + if nm_device_setting_value(name, "connection", "slave-type"): + continue self.supported_devices.append(name)
EditTUISpoke.initialize(self)
Include all devices not only devices configurable in TUI. --- pyanaconda/ui/tui/spokes/network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py index f470416..91aa369 100644 --- a/pyanaconda/ui/tui/spokes/network.py +++ b/pyanaconda/ui/tui/spokes/network.py @@ -232,7 +232,7 @@ class NetworkSpoke(EditTUISpoke): hostname = self.data.network.hostname
self.data.network.network = [] - for name in self.supported_devices: + for name in nm_devices(): nd = network.ksdata_from_ifcfg(name) if not nd: continue
--- dracut/parse-kickstart | 1 + 1 file changed, 1 insertion(+)
diff --git a/dracut/parse-kickstart b/dracut/parse-kickstart index 12178bd..5728743 100755 --- a/dracut/parse-kickstart +++ b/dracut/parse-kickstart @@ -371,6 +371,7 @@ def ksnet_to_ifcfg(net, filename=None): ifcfg.pop('HWADDR') ifcfg['TYPE'] = "Vlan" ifcfg['VLAN'] = "yes" + ifcfg['VLAN_ID'] = net.vlanid ifcfg['NAME'] = "VLAN connection %s" % interface_name ifcfg['DEVICE'] = interface_name ifcfg['PHYSDEV'] = dev
--- pyanaconda/nm.py | 30 +++++++++++++++++++++++------- pyanaconda/ui/tui/spokes/network.py | 7 +++++-- 2 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/pyanaconda/nm.py b/pyanaconda/nm.py index ae0b9cd..268b8b5 100644 --- a/pyanaconda/nm.py +++ b/pyanaconda/nm.py @@ -42,6 +42,11 @@ class UnknownDeviceError(ValueError): def __str__(self): return self.__repr__()
+class UnmanagedDeviceError(Exception): + """Device of specified name is not managed by NM or unavailable""" + def __str__(self): + return self.__repr__() + class PropertyNotFoundError(ValueError): """Property of NM object was not found""" def __str__(self): @@ -195,7 +200,7 @@ def nm_device_property(name, prop): Gio.DBusCallFlags.NONE, DEFAULT_DBUS_TIMEOUT, None) - except Exception as e: + except GLib.GError as e: if "org.freedesktop.NetworkManager.UnknownDevice" in e.message: raise UnknownDeviceError(name, e) raise @@ -515,6 +520,12 @@ def nm_device_setting_value(name, key1, key2): return value
def nm_activate_device_connection(dev_name, con_uuid): + """Activate device with specified connection. + + Exceptions: + UnknownDeviceError - device was not found + + """
proxy = _get_proxy() args = GLib.Variant('(s)', (dev_name,)) @@ -524,7 +535,7 @@ def nm_activate_device_connection(dev_name, con_uuid): Gio.DBusCallFlags.NONE, DEFAULT_DBUS_TIMEOUT, None) - except Exception as e: + except GLib.GError as e: if "org.freedesktop.NetworkManager.UnknownDevice" in e.message: raise UnknownDeviceError(dev_name, e) raise @@ -535,11 +546,16 @@ def nm_activate_device_connection(dev_name, con_uuid):
args = GLib.Variant('(ooo)', (con_path, device_path, "/")) nm_proxy = _get_proxy() - nm_proxy.call_sync("ActivateConnection", - args, - Gio.DBusCallFlags.NONE, - DEFAULT_DBUS_TIMEOUT, - None) + try: + nm_proxy.call_sync("ActivateConnection", + args, + Gio.DBusCallFlags.NONE, + DEFAULT_DBUS_TIMEOUT, + None) + except GLib.GError as e: + if "org.freedesktop.NetworkManager.UnmanagedDevice" in e.message: + raise UnmanagedDeviceError(dev_name, e) + raise
def nm_update_settings_of_device(name, new_values): """Update setting of device. diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py index 91aa369..95432bc 100644 --- a/pyanaconda/ui/tui/spokes/network.py +++ b/pyanaconda/ui/tui/spokes/network.py @@ -27,7 +27,7 @@ from pyanaconda.ui.tui.spokes import EditTUISpokeEntry as Entry from pyanaconda.ui.tui.simpleline import TextWidget, ColumnWidget from pyanaconda.i18n import _ from pyanaconda import network -from pyanaconda.nm import nm_activated_devices, nm_state, nm_devices, nm_device_type_is_ethernet, nm_device_ip_config, nm_activate_device_connection, nm_device_setting_value +from pyanaconda.nm import nm_activated_devices, nm_state, nm_devices, nm_device_type_is_ethernet, nm_device_ip_config, nm_activate_device_connection, nm_device_setting_value, UnmanagedDeviceError
from pyanaconda.regexes import IPV4_PATTERN_WITHOUT_ANCHORS from pyanaconda.constants_text import INPUT_PROCESSED @@ -217,7 +217,10 @@ class NetworkSpoke(EditTUISpoke):
if ndata._apply: uuid = nm_device_setting_value(devname, "connection", "uuid") - nm_activate_device_connection(devname, uuid) + try: + nm_activate_device_connection(devname, uuid) + except UnmanagedDeviceError: + self.errors.append(_("Can't apply configuration, device activation failed."))
self.apply() return INPUT_PROCESSED
Not only for ethernet devices. Consolidate gui and tui functions. --- pyanaconda/network.py | 70 +++++++++++++++++++++++++++++++++++++ pyanaconda/ui/gui/spokes/network.py | 55 +---------------------------- pyanaconda/ui/tui/spokes/network.py | 27 +------------- 3 files changed, 72 insertions(+), 80 deletions(-)
diff --git a/pyanaconda/network.py b/pyanaconda/network.py index 9c526ad..67cae66 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -44,6 +44,8 @@ from pyanaconda import constants from pyanaconda.flags import flags, can_touch_runtime_system from pyanaconda.i18n import _
+from gi.repository import NetworkManager + import logging log = logging.getLogger("anaconda")
@@ -1028,3 +1030,71 @@ def wait_for_connectivity(timeout=constants.NETWORK_CONNECTION_TIMEOUT): # so we need to release it network_connected_condition.release() return connected + +def status_message(): + """ A short string describing which devices are connected. """ + + msg = _("Unknown") + + state = nm.nm_state() + if state == NetworkManager.State.CONNECTING: + msg = _("Connecting...") + elif state == NetworkManager.State.DISCONNECTING: + msg = _("Disconnecting...") + else: + active_devs = nm.nm_activated_devices() + if active_devs: + + slaves = {} + ssids = {} + nonslaves = [] + + # first find slaves and wireless aps + for devname in active_devs: + master = nm.nm_device_setting_value(devname, "connection", "master") + if master: + if master in slaves: + slaves[master].append(devname) + else: + slaves[master] = [devname] + else: + nonslaves.append(devname) + if nm.nm_device_type_is_wifi(devname): + ssids[devname] = nm.nm_device_active_ssid(devname) or "" + + if len(nonslaves) == 1: + if nm.nm_device_type_is_ethernet(devname): + msg = _("Wired (%(interface_name)s) connected") \ + % {"interface_name": devname} + elif nm.nm_device_type_is_wifi(devname): + msg = _("Wireless connected to %(access_point)s") \ + % {"access_point" : ssids[devname]} + elif nm.nm_device_type_is_bond(devname): + msg = _("Bond %(interface_name)s (%(list_of_slaves)s) connected") \ + % {"interface_name": devname, \ + "list_of_slaves": ",".join(slaves[devname])} + elif nm.nm_device_type_is_vlan(devname): + parent = nm.nm_device_setting_value(devname, "vlan", "parent") + vlanid = nm.nm_device_setting_value(devname, "vlan", "id") + msg = _("Vlan %(interface_name)s (%(parent_device)s, ID %(vlanid)s) connected") \ + % {"interface_name": devname, "parent_device": parent, "vlanid": vlanid} + elif len(nonslaves) > 1: + devlist = [] + for devname in nonslaves: + if nm.nm_device_type_is_ethernet(devname): + devlist.append("%s" % devname) + elif nm.nm_device_type_is_wifi(devname): + devlist.append("%s" % ssids[devname]) + elif nm.nm_device_type_is_bond(devname): + devlist.append("%s (%s)" % (devname, ",".join(slaves[devname]))) + elif nm.nm_device_type_is_vlan(devname): + devlist.append("%s" % devname) + msg = _("Connected: %(list_of_interface_names)s") \ + % {"list_of_interface_names": ", ".join(devlist)} + else: + msg = _("Not connected") + + if not nm.nm_devices(): + msg = _("No network devices available") + + return msg diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index 372602e..33d0a15 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -1290,60 +1290,7 @@ class NetworkSpoke(FirstbootSpokeMixIn, NormalSpoke): @property def status(self): """ A short string describing which devices are connected. """ - msg = _("Unknown") - - state = self.network_control_box.client.get_state() - if state == NetworkManager.State.CONNECTING: - msg = _("Connecting...") - elif state == NetworkManager.State.DISCONNECTING: - msg = _("Disconnecting...") - else: - ac = self.network_control_box.activated_connections() - if ac: - # Don't show bond slaves - slaves = [] - for name, ty, info in ac: - if ty == NetworkManager.DeviceType.BOND: - slaves.extend(info) - if slaves: - ac = [(name, ty, info) - for name, ty, info in ac - if name not in slaves] - - if len(ac) == 1: - name, ty, info = ac[0] - if ty == NetworkManager.DeviceType.ETHERNET: - msg = _("Wired (%(interface_name)s) connected") \ - % {"interface_name": name} - elif ty == NetworkManager.DeviceType.WIFI: - msg = _("Wireless connected to %(access_point)s") \ - % {"access_point" : info} - elif ty == NetworkManager.DeviceType.BOND: - msg = _("Bond %(interface_name)s (%(list_of_slaves)s) connected") \ - % {"interface_name": name, "list_of_slaves": ",".join(info)} - if ty == NetworkManager.DeviceType.VLAN: - msg = _("Vlan %(interface_name)s (%(parent_device)s, ID %(vlanid)s) connected") \ - % {"interface_name": name, "parent_device": info[0], "vlanid": info[1]} - else: - devlist = [] - for name, ty, info in ac: - if ty == NetworkManager.DeviceType.ETHERNET: - devlist.append("%s" % name) - elif ty == NetworkManager.DeviceType.WIFI: - devlist.append("%s" % info) - elif ty == NetworkManager.DeviceType.BOND: - devlist.append("%s (%s)" % (name, ",".join(info))) - if ty == NetworkManager.DeviceType.VLAN: - devlist.append("%s" % name) - msg = _("Connected: %(list_of_interface_names)s") \ - % {"list_of_interface_names": ", ".join(devlist)} - else: - msg = _("Not connected") - - if not self.network_control_box.listed_devices: - msg = _("No network devices available") - - return msg + return network.status_message()
def initialize(self): register_secret_agent(self) diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py index 95432bc..eb6895a 100644 --- a/pyanaconda/ui/tui/spokes/network.py +++ b/pyanaconda/ui/tui/spokes/network.py @@ -72,32 +72,7 @@ class NetworkSpoke(EditTUISpoke): @property def status(self): """ Short msg telling what devices are active. """ - msg = _("Unknown") - - state = nm_state() - if state == NetworkManager.State.CONNECTING: - msg = _("Connecting...") - elif state == NetworkManager.State.DISCONNECTING: - msg = _("Disconnecting...") - else: - activated_devs = nm_activated_devices() - if not activated_devs: - msg = _("Not connected") - elif len(activated_devs) == 1: - if nm_device_type_is_ethernet(activated_devs[0]): - msg = _("Wired %s connected" % activated_devs[0]) - else: - devlist = [] - for dev in activated_devs: - if nm_device_type_is_ethernet(dev): - devlist.append("%s" % dev) - msg = _("Connected: %(list_of_interface_names)s") \ - % {"list_of_interface_names": ", ".join(devlist)} - - if not nm_devices(): - msg = _("No network devices available") - - return msg + return network.status_message()
def _summary_text(self): """Devices cofiguration shown to user."""
--- pyanaconda/ui/tui/spokes/network.py | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py index eb6895a..c07af01 100644 --- a/pyanaconda/ui/tui/spokes/network.py +++ b/pyanaconda/ui/tui/spokes/network.py @@ -27,14 +27,11 @@ from pyanaconda.ui.tui.spokes import EditTUISpokeEntry as Entry from pyanaconda.ui.tui.simpleline import TextWidget, ColumnWidget from pyanaconda.i18n import _ from pyanaconda import network -from pyanaconda.nm import nm_activated_devices, nm_state, nm_devices, nm_device_type_is_ethernet, nm_device_ip_config, nm_activate_device_connection, nm_device_setting_value, UnmanagedDeviceError +from pyanaconda import nm
from pyanaconda.regexes import IPV4_PATTERN_WITHOUT_ANCHORS from pyanaconda.constants_text import INPUT_PROCESSED
-# pylint: disable-msg=E0611 -from gi.repository import NetworkManager - import re
__all__ = ["NetworkSpoke"] @@ -53,10 +50,10 @@ class NetworkSpoke(EditTUISpoke): self.errors = []
def initialize(self): - for name in nm_devices(): - if nm_device_type_is_ethernet(name): + for name in nm.nm_devices(): + if nm.nm_device_type_is_ethernet(name): # ignore slaves - if nm_device_setting_value(name, "connection", "slave-type"): + if nm.nm_device_setting_value(name, "connection", "slave-type"): continue self.supported_devices.append(name)
@@ -67,7 +64,7 @@ class NetworkSpoke(EditTUISpoke): @property def completed(self): return (not can_touch_runtime_system("require network connection") - or nm_activated_devices()) + or nm.nm_activated_devices())
@property def status(self): @@ -77,7 +74,7 @@ class NetworkSpoke(EditTUISpoke): def _summary_text(self): """Devices cofiguration shown to user.""" msg = "" - activated_devs = nm_activated_devices() + activated_devs = nm.nm_activated_devices() for name in self.supported_devices: if name in activated_devs: msg += self._activated_device_msg(name) @@ -90,8 +87,8 @@ class NetworkSpoke(EditTUISpoke): msg = _("Wired (%(interface_name)s) connected\n") \ % {"interface_name": devname}
- ipv4config = nm_device_ip_config(devname, version=4) - ipv6config = nm_device_ip_config(devname, version=6) + ipv4config = nm.nm_device_ip_config(devname, version=4) + ipv6config = nm.nm_device_ip_config(devname, version=6)
if ipv4config and ipv4config[0]: addr_str, prefix, gateway_str = ipv4config[0][0] @@ -191,10 +188,10 @@ class NetworkSpoke(EditTUISpoke): network.update_settings_with_ksdata(devname, ndata)
if ndata._apply: - uuid = nm_device_setting_value(devname, "connection", "uuid") + uuid = nm.nm_device_setting_value(devname, "connection", "uuid") try: - nm_activate_device_connection(devname, uuid) - except UnmanagedDeviceError: + nm.nm_activate_device_connection(devname, uuid) + except nm.UnmanagedDeviceError: self.errors.append(_("Can't apply configuration, device activation failed."))
self.apply() @@ -210,11 +207,11 @@ class NetworkSpoke(EditTUISpoke): hostname = self.data.network.hostname
self.data.network.network = [] - for name in nm_devices(): + for name in nm.nm_devices(): nd = network.ksdata_from_ifcfg(name) if not nd: continue - if name in nm_activated_devices(): + if name in nm.nm_activated_devices(): nd.activate = True self.data.network.network.append(nd)
On Fri, 2013-09-13 at 15:32 +0200, Radek Vykydal wrote:
The cleanup itself is in [1/7].
Then there are some patches fixing issues I came across while testing the patch (text mode, wifi, vlan, bonding, no link).
And a bit more of tui improvement and code consolidation in [6/7].
Apart from the debugging leftover in PATCH 1/7 these all look good to me. Nice way to simplify the code.
anaconda-patches@lists.fedorahosted.org