[PATCH] Fix check for device state when reading its IPXConfig (#1001776)
Radek Vykydal
rvykydal at redhat.com
Mon Sep 9 07:41:39 UTC 2013
Device has to be in ACTIVATED state for IPXConfig to be valid.
1) use a recently added nm module function to get IP configuration, replacing
python-dbus with GDBus here. Python-dbus would give us stale value.
2) Don't use get_cached_property of GDBus as it would give us stale value too.
Instead use DBus.Properties interface call to get current values.
---
pyanaconda/nm.py | 77 ++++++++++++++++++++-----------------
pyanaconda/ui/gui/spokes/network.py | 64 +++++++++++-------------------
2 files changed, 63 insertions(+), 78 deletions(-)
diff --git a/pyanaconda/nm.py b/pyanaconda/nm.py
index 1109d6e..4f0923d 100644
--- a/pyanaconda/nm.py
+++ b/pyanaconda/nm.py
@@ -73,10 +73,27 @@ def _get_proxy(bus_type=Gio.BusType.SYSTEM,
cancellable)
return proxy
+def _get_property(object_path, prop, interface_name_suffix=""):
+ interface_name = "org.freedesktop.NetworkManager" + interface_name_suffix
+ proxy = _get_proxy(object_path=object_path, interface_name="org.freedesktop.DBus.Properties")
+ args = GLib.Variant('(ss)', (interface_name, prop))
+ try:
+ prop = proxy.call_sync("Get",
+ args,
+ Gio.DBusCallFlags.NONE,
+ DEFAULT_DBUS_TIMEOUT,
+ None)
+ except GLib.GError as e:
+ if "org.freedesktop.DBus.Error.AccessDenied" in e.message:
+ return None
+ else:
+ raise
+
+ return prop.unpack()[0]
+
def nm_state():
"""Return state of NetworkManager"""
- proxy = _get_proxy()
- return proxy.get_cached_property("State").unpack()
+ return _get_property("/org/freedesktop/NetworkManager", "State")
# FIXME - use just GLOBAL? There is some connectivity checking
# for GLOBAL in NM (nm_connectivity_get_connected), not sure if
@@ -107,11 +124,11 @@ def nm_devices():
devices = devices.unpack()[0]
for device in devices:
- proxy = _get_proxy(object_path=device, interface_name="org.freedesktop.NetworkManager.Device")
- device_type = proxy.get_cached_property("DeviceType").unpack()
+ device_type = _get_property(device, "DeviceType", ".Device")
if device_type not in supported_device_types:
continue
- interfaces.append(proxy.get_cached_property("Interface").unpack())
+ iface = _get_property(device, "Interface", ".Device")
+ interfaces.append(iface)
return interfaces
@@ -120,19 +137,15 @@ def nm_activated_devices():
interfaces = []
- proxy = _get_proxy()
- active_connections = proxy.get_cached_property("ActiveConnections").unpack()
+ active_connections = _get_property("/org/freedesktop/NetworkManager", "ActiveConnections")
for ac in active_connections:
- proxy = _get_proxy(object_path=ac, interface_name="org.freedesktop.NetworkManager.Connection.Active")
- state = proxy.get_cached_property("State")
- if not state or state.unpack() != NetworkManager.ActiveConnectionState.ACTIVATED:
- continue
- devices = proxy.get_cached_property("Devices")
- if not devices:
+ state = _get_property(ac, "State", ".Connection.Active")
+ if state != NetworkManager.ActiveConnectionState.ACTIVATED:
continue
- for device in devices.unpack():
- proxy = _get_proxy(object_path=device, interface_name="org.freedesktop.NetworkManager.Device")
- interfaces.append(proxy.get_cached_property("Interface").unpack())
+ devices = _get_property(ac, "Devices", ".Connection.Active")
+ for device in devices:
+ iface = _get_property(device, "Interface", ".Device")
+ interfaces.append(iface)
return interfaces
@@ -181,18 +194,14 @@ def nm_device_property(name, prop):
raise
device = device.unpack()[0]
- proxy = _get_proxy(object_path=device, interface_name="org.freedesktop.NetworkManager.Device")
- if prop in proxy.get_cached_property_names():
- retval = proxy.get_cached_property(prop).unpack()
- else:
+ retval = _get_property(device, prop, ".Device")
+ if not retval:
# Look in device type based interface
interface = _device_type_specific_interface(device)
if interface:
- proxy = _get_proxy(object_path=device, interface_name=interface)
- if prop in proxy.get_cached_property_names():
- retval = proxy.get_cached_property(prop).unpack()
- else:
+ retval = _get_property(device, prop, interface[30:])
+ if not retval:
raise PropertyNotFoundError(prop)
else:
raise PropertyNotFoundError(prop)
@@ -284,10 +293,10 @@ def nm_device_ip_config(name, version=4):
return []
if version == 4:
- dbus_iface = "org.freedesktop.NetworkManager.IP4Config"
+ dbus_iface = ".IP4Config"
prop= "Ip4Config"
elif version == 6:
- dbus_iface = "org.freedesktop.NetworkManager.IP6Config"
+ dbus_iface = ".IP6Config"
prop= "Ip6Config"
else:
return []
@@ -296,9 +305,7 @@ def nm_device_ip_config(name, version=4):
if config == "/":
return []
- proxy = _get_proxy(object_path=config, interface_name=dbus_iface)
-
- addresses = proxy.get_cached_property("Addresses").unpack()
+ addresses = _get_property(config, "Addresses", dbus_iface)
addr_list = []
for addr, prefix, gateway in addresses:
# TODO - look for a library function (could have used IPy but byte order!)
@@ -310,7 +317,7 @@ def nm_device_ip_config(name, version=4):
gateway_str = nm_dbus_ay_to_ipv6(gateway)
addr_list.append([addr_str, prefix, gateway_str])
- nameservers = proxy.get_cached_property("Nameservers").unpack()
+ nameservers = _get_property(config, "Nameservers", dbus_iface)
ns_list = []
for ns in nameservers:
# TODO - look for a library function
@@ -322,7 +329,6 @@ def nm_device_ip_config(name, version=4):
return [addr_list, ns_list]
-
def nm_ntp_servers_from_dhcp():
"""Return a list of NTP servers that were specified the reply of the
DHCP server or empty list if no NTP servers were returned.
@@ -335,16 +341,15 @@ def nm_ntp_servers_from_dhcp():
for device in active_devices:
# harvest NTP server addresses from DHCPv4
dhcp4_path = nm_device_property(device, "Dhcp4Config")
- dhcp4_proxy = _get_proxy(object_path=dhcp4_path,
- interface_name="org.freedesktop.NetworkManager.DHCP4Config")
- options = dhcp4_proxy.get_cached_property("Options")
- if options and 'ntp_servers' in options.unpack():
+ options = _get_property(dhcp4_path, "Options", ".DHCP4Config")
+ if options and 'ntp_servers' in options:
# NTP server addresses returned by DHCP are whitespace delimited
- ntp_servers_string = options.unpack()["ntp_servers"]
+ ntp_servers_string = options["ntp_servers"]
for ip in ntp_servers_string.split(" "):
ntp_servers.append(ip)
# NetworkManager does not request NTP/SNTP options for DHCP6
+ print ntp_servers
return ntp_servers
def _device_settings(name):
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py
index f7c1275..132c7f2 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_activated_devices, nm_device_setting_value, nm_dbus_ay_to_ipv6
+from pyanaconda.nm import nm_device_setting_value, nm_device_ip_config
from gi.repository import GLib, GObject, Pango, Gio, NetworkManager, NMClient
import dbus
@@ -704,12 +704,9 @@ class NetworkControlBox(object):
self._refresh_parent_vlanid(device)
self._refresh_speed_hwaddr(device, state)
self._refresh_ap(device, state)
- self._refresh_device_cfg(device, state)
+ self._refresh_device_cfg(device)
- def _refresh_device_cfg(self, device, state):
-
- if state is None:
- state = device.get_state()
+ def _refresh_device_cfg(self, device):
dev_type = device.get_device_type()
if dev_type == NetworkManager.DeviceType.ETHERNET:
@@ -721,45 +718,28 @@ class NetworkControlBox(object):
elif dev_type == NetworkManager.DeviceType.VLAN:
dt = "wired"
- if state == NetworkManager.DeviceState.ACTIVATED:
- ipv4cfg = device.get_ip4_config()
- ipv6cfg = device.get_ip6_config()
- else:
- ipv4cfg = None
- ipv6cfg = None
-
- if ipv4cfg:
- addr = socket.inet_ntoa(struct.pack('=L',
- ipv4cfg.get_addresses()[0].get_address()))
- self._set_device_info_value(dt, "ipv4", addr)
- dnss = " ".join(socket.inet_ntoa(struct.pack('=L', addr))
- for addr in ipv4cfg.get_nameservers())
- self._set_device_info_value(dt, "dns", dnss)
- gateway = socket.inet_ntoa(struct.pack('=L',
- ipv4cfg.get_addresses()[0].get_gateway()))
- self._set_device_info_value(dt, "route", gateway)
- if dt == "wired":
- prefix = ipv4cfg.get_addresses()[0].get_prefix()
- nm_utils.nm_utils_ip4_prefix_to_netmask.argtypes = [ctypes.c_uint32]
- nm_utils.nm_utils_ip4_prefix_to_netmask.restype = ctypes.c_uint32
- netmask = nm_utils.nm_utils_ip4_prefix_to_netmask(prefix)
- netmask = socket.inet_ntoa(struct.pack('=L', netmask))
- self._set_device_info_value(dt, "subnet", netmask)
+ ipv4cfg = nm_device_ip_config(device.get_iface(), version=4)
+ ipv6cfg = nm_device_ip_config(device.get_iface(), version=6)
+
+ if ipv4cfg and ipv4cfg[0]:
+ addr_str, prefix, gateway_str = ipv4cfg[0][0]
+ netmask_str = network.prefix2netmask(prefix)
+ dnss_str = " ".join(ipv4cfg[1])
else:
- self._set_device_info_value(dt, "ipv4", None)
- self._set_device_info_value(dt, "dns", None)
- self._set_device_info_value(dt, "route", None)
- if dt == "wired":
- self._set_device_info_value(dt, "subnet", None)
+ addr_str = dnss_str = gateway_str = netmask_str = None
+ self._set_device_info_value(dt, "ipv4", addr_str)
+ self._set_device_info_value(dt, "dns", dnss_str)
+ self._set_device_info_value(dt, "route", gateway_str)
+ if dt == "wired":
+ self._set_device_info_value(dt, "subnet", netmask_str)
- # TODO NM_GI_BUGS - segfaults on get_addres(), get_prefix()
addr6_str = ""
- if ipv6cfg:
- config = dbus.SystemBus().get_object(NM_SERVICE, ipv6cfg.get_path())
- for addr, _prefix, _gw in getNMObjProperty(config, ".IP6Config", "Addresses"):
- ipv6_addr = nm_dbus_ay_to_ipv6(addr)
- if not ipv6_addr.startswith("fe80:"):
- addr6_str += "%s\n" % ipv6_addr
+ if ipv6cfg and ipv6cfg[0]:
+ for ipv6addr in ipv6cfg[0]:
+ addr_str, prefix, gateway_str = ipv6addr
+ # Do not display link-local addresses
+ if not addr_str.startswith("fe80:"):
+ addr6_str += "%s/%d\n" % (addr_str, prefix)
self._set_device_info_value(dt, "ipv6", addr6_str.strip() or None)
--
1.7.11.7
More information about the anaconda-patches
mailing list