Resolves: rhbz#1036047
Don't crash when the device is turned off. The items of device treeview are device configurations, not devices. --- pyanaconda/network.py | 29 +- pyanaconda/nm.py | 28 +- pyanaconda/ui/gui/spokes/network.glade | 2 +- pyanaconda/ui/gui/spokes/network.py | 508 +++++++++++++++++++-------------- 4 files changed, 333 insertions(+), 234 deletions(-)
diff --git a/pyanaconda/network.py b/pyanaconda/network.py index 4719450..8dc7893 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -484,7 +484,7 @@ def add_connection_for_ksdata(networkdata, devname): svalues.append(['connection', 'slave-type', 'bond', 's']) svalues.append(['connection', 'master', devname, 's']) svalues.append(['connection', 'type', '802-3-ethernet', 's']) - mac = nm.nm_device_hwaddress(slave) + mac = nm.nm_device_perm_hwaddress(slave) mac = [int(b, 16) for b in mac.split(":")] svalues.append(['802-3-ethernet', 'mac-address', mac, 'ay'])
@@ -518,7 +518,7 @@ def add_connection_for_ksdata(networkdata, devname): svalues.append(['connection', 'slave-type', 'team', 's']) svalues.append(['connection', 'master', devname, 's']) svalues.append(['connection', 'type', '802-3-ethernet', 's']) - mac = nm.nm_device_hwaddress(slave) + mac = nm.nm_device_perm_hwaddress(slave) mac = [int(b, 16) for b in mac.split(":")] svalues.append(['802-3-ethernet', 'mac-address', mac, 'ay']) svalues.append(['team-port', 'config', cfg, 's']) @@ -547,7 +547,7 @@ def add_connection_for_ksdata(networkdata, devname): else: values.append(['connection', 'type', '802-3-ethernet', 's']) values.append(['connection', 'id', devname, 's']) - mac = nm.nm_device_hwaddress(devname) + mac = nm.nm_device_perm_hwaddress(devname) mac = [int(b, 16) for b in mac.split(":")] values.append(['802-3-ethernet', 'mac-address', mac, 'ay']) dev_spec = devname @@ -556,20 +556,23 @@ def add_connection_for_ksdata(networkdata, devname): added_connections.insert(0, (con_uuid, dev_spec)) return added_connections
-def ksdata_from_ifcfg(devname): +def ksdata_from_ifcfg(devname, uuid=None):
if nm.nm_device_is_slave(devname): return None + if nm.nm_device_type_is_wifi(devname): + # wifi from kickstart is not supported yet + return None
- ifcfg_path = None + if not uuid: + # Find ifcfg file for the device. + # If the device is active, use uuid of its active connection. + uuid = nm.nm_device_active_con_uuid(devname)
- # Find ifcfg file for the device. - # If the device is active, use uuid of its active connection. - uuid = nm.nm_device_active_con_uuid(devname) if uuid: ifcfg_path = find_ifcfg_file([("UUID", uuid)]) else: - # If not, look it up by other values depending on its type + # look it up by other values depending on its type ifcfg_path = find_ifcfg_file_of_device(devname)
if not ifcfg_path: @@ -738,7 +741,7 @@ def find_ifcfg_file_of_device(devname, root_path=""): ifcfg_path = find_ifcfg_file([("DEVICE", devname)]) elif nm.nm_device_type_is_ethernet(devname): try: - hwaddr = nm.nm_device_hwaddress(devname) + hwaddr = nm.nm_device_perm_hwaddress(devname) except nm.PropertyNotFoundError: hwaddr = None if hwaddr: @@ -922,7 +925,7 @@ def ks_spec_to_device_name(ksspec=""): # "XX:XX:XX:XX:XX:XX" (mac address) elif ':' in ksdevice: try: - hwaddr = nm.nm_device_hwaddress(dev) + hwaddr = nm.nm_device_perm_hwaddress(dev) except ValueError as e: log.debug("ks_spec_to_device_name: %s" % e) continue @@ -932,7 +935,7 @@ def ks_spec_to_device_name(ksspec=""): # "bootif" and BOOTIF==XX:XX:XX:XX:XX:XX elif ksdevice == 'bootif': try: - hwaddr = nm.nm_device_hwaddress(dev) + hwaddr = nm.nm_device_perm_hwaddress(dev) except ValueError as e: log.debug("ks_spec_to_device_name: %s" % e) continue @@ -1146,7 +1149,7 @@ def get_device_name(devspec): if devname and devname not in devices: for d in devices: try: - hwaddr = nm.nm_device_hwaddress(d) + hwaddr = nm.nm_device_perm_hwaddress(d) except ValueError as e: log.debug("get_device_name: %s" % e) continue diff --git a/pyanaconda/nm.py b/pyanaconda/nm.py index 8f8256b..0d1d4a1 100644 --- a/pyanaconda/nm.py +++ b/pyanaconda/nm.py @@ -48,6 +48,11 @@ class UnmanagedDeviceError(Exception): def __str__(self): return self.__repr__()
+class DeviceNotActiveError(Exception): + """Device of specified name is not active""" + def __str__(self): + return self.__repr__() + class PropertyNotFoundError(ValueError): """Property of NM object was not found""" def __str__(self): @@ -267,6 +272,18 @@ def nm_device_hwaddress(name): """ return nm_device_property(name, "HwAddress")
+def nm_device_perm_hwaddress(name): + """Return active hardware address of device ('HwAddress' property) + + :param name: name of device + :type name: str + :return: active hardware address of device ('HwAddress' property) + :rtype: str + :raise UnknownDeviceError: if device is not found + :raise PropertyNotFoundError: if 'HwAddress' property is not found + """ + return nm_device_property(name, "PermHwAddress") + def nm_device_active_con_uuid(name): """Return uuid of device's active connection
@@ -433,7 +450,7 @@ def nm_hwaddr_to_device_name(hwaddr): :rtype: str """ for device in nm_devices(): - if nm_device_hwaddress(device).upper() == hwaddr.upper(): + if nm_device_perm_hwaddress(device).upper() == hwaddr.upper(): return device return None
@@ -478,7 +495,7 @@ def _device_settings(name): settings = _find_settings(name, 'connection', 'interface-name') if not settings: try: - hwaddr_str = nm_device_hwaddress(name) + hwaddr_str = nm_device_perm_hwaddress(name) except PropertyNotFoundError: settings = [] else: @@ -618,7 +635,12 @@ def nm_disconnect_device(name): raise
device_proxy = _get_proxy(object_path=device, interface_name="org.freedesktop.NetworkManager.Device") - device_proxy.Disconnect() + try: + device_proxy.Disconnect() + except GLib.GError as e: + if "org.freedesktop.NetworkManager.Device.NotActive" in e.message: + raise DeviceNotActiveError(name, e) + raise
def nm_activate_device_connection(dev_name, con_uuid): """Activate device with specified connection. diff --git a/pyanaconda/ui/gui/spokes/network.glade b/pyanaconda/ui/gui/spokes/network.glade index 1b65d83..d9d945e 100644 --- a/pyanaconda/ui/gui/spokes/network.glade +++ b/pyanaconda/ui/gui/spokes/network.glade @@ -136,7 +136,7 @@ <!-- column-name sort --> <column type="gchararray"/> <!-- column-name object --> - <column type="GObject"/> + <column type="PyObject"/> </columns> </object> <object class="GtkListStore" id="liststore_wireless_network"> diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index bbfb75a..0c822b7 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -58,10 +58,6 @@ import string from dbus.mainloop.glib import DBusGMainLoop dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-import ctypes -ctypes.cdll.LoadLibrary("libnm-util.so.2") -nm_utils = ctypes.CDLL("libnm-util.so.2") - import logging log = logging.getLogger("anaconda")
@@ -96,7 +92,9 @@ def localized_string_of_device_state(device, state): elif state == NetworkManager.DeviceState.UNMANAGED: str = _("Unmanaged") elif state == NetworkManager.DeviceState.UNAVAILABLE: - if device.get_firmware_missing(): + if not device: + str = _("Unavailable") + elif device.get_firmware_missing(): str = _("Firmware missing") elif (device.get_device_type() == NetworkManager.DeviceType.ETHERNET and not device.get_carrier()): @@ -212,7 +210,65 @@ class CellRendererSecurity(Gtk.CellRendererPixbuf):
self.set_property("icon-name", self.icon_name)
-class NetworkControlBox(object): +class DeviceConfiguration(object): + + setting_types = { + '802-11-wireless': NetworkManager.DeviceType.WIFI, + '802-3-ethernet': NetworkManager.DeviceType.ETHERNET, + 'vlan': NetworkManager.DeviceType.VLAN, + 'bond': NetworkManager.DeviceType.BOND, + 'team': NetworkManager.DeviceType.TEAM, + } + + def __init__(self, device=None, con_uuid=None): + self.device = device + self.con_uuid = con_uuid + + if device: + self.device_type = self.device.get_device_type() + elif con_uuid: + self.device_type = self._setting_device_type(self.con_uuid) + + if not self.con_uuid: + if self.device_type != NetworkManager.DeviceType.WIFI: + uuid = nm.nm_device_setting_value(device.get_iface(), "connection", "uuid") + settings = nm.nm_get_settings(uuid, "connection", "uuid") + if settings and 'slave-type' not in settings[0]['connection']: + self.con_uuid = uuid + + def _setting_device_type(self, uuid): + settings = nm.nm_get_settings(uuid, "connection", "uuid") + if not settings: + return None + dev_type = self.setting_types.get(settings[0]["connection"]["type"], None) + return dev_type + + def get_iface(self): + if self.device: + iface = self.device.get_iface() + else: + iface = self.setting_value("connection", "interface-name") + return iface + + def setting_value(self, key1, key2): + settings = nm.nm_get_settings(self.con_uuid, "connection", "uuid") + try: + value = settings[0][key1][key2] + except IndexError as e: + log.debug("network: can't find connection with uuid %s" + % self.con_uuid) + except KeyError as e: + log.debug("network: can't find '%s' '%s' in connection %s" + % (key1, key2, self.con_uuid)) + else: + return value + +class NetworkControlBox(GObject.GObject): + + __gsignals__ = { + "nm-state-changed": (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, []), + "device-state-changed": (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, [str, int, int, int]), + }
supported_device_types = [ NetworkManager.DeviceType.ETHERNET, @@ -229,8 +285,24 @@ class NetworkControlBox(object): NetworkManager.DeviceType.VLAN, ]
+ device_type_sort_value = { + NetworkManager.DeviceType.ETHERNET : "1", + NetworkManager.DeviceType.WIFI : "2", + } + + device_type_name = { + NetworkManager.DeviceType.UNKNOWN: _("Unknown"), + NetworkManager.DeviceType.ETHERNET: _("Ethernet"), + NetworkManager.DeviceType.WIFI: _("Wireless"), + NetworkManager.DeviceType.BOND: _("Bond"), + NetworkManager.DeviceType.VLAN: _("Vlan"), + NetworkManager.DeviceType.TEAM: _("Team"), + } + def __init__(self, builder, spoke=None):
+ GObject.GObject.__init__(self) + self.builder = builder self._running_nmce = None self.spoke = spoke @@ -306,6 +378,8 @@ class NetworkControlBox(object): self.on_edit_connection) self.entry_hostname = self.builder.get_object("entry_hostname")
+ self.client.connect("notify::%s" % NMClient.CLIENT_STATE, + self.on_nm_state_changed)
@property def vbox(self): @@ -340,10 +414,18 @@ class NetworkControlBox(object):
def initialize(self): for device in self.client.get_devices(): - device.connect("notify::ip4-config", self.on_device_config_changed) - device.connect("notify::ip6-config", self.on_device_config_changed) self.add_device_to_list(device)
+ for setting in nm.nm_get_all_settings(): + uuid = setting["connection"]["uuid"] + log.debug("network: GUI, connection %s found" % uuid) + if self.dev_cfg(uuid=uuid): + continue + dev_cfg = DeviceConfiguration(con_uuid=uuid) + if dev_cfg.device_type in self.supported_device_types: + self.add_dev_cfg(dev_cfg) + + # select the first device treeview = self.builder.get_object("treeview_devices") devices_store = self.builder.get_object("liststore_devices") selection = treeview.get_selection() @@ -352,30 +434,28 @@ class NetworkControlBox(object): selection.select_iter(itr)
def refresh(self): - device = self.selected_device() - self.refresh_ui(device) + self.refresh_ui()
# Signal handlers. - def on_device_selection_changed(self, *args): - device = self.selected_device() - if not device: - return + def on_nm_state_changed(self, *args): + self.emit("nm-state-changed")
- log.debug("network: selected device %s" % device.get_iface()) - self.refresh_ui(device) + def on_device_selection_changed(self, *args): + self.refresh_ui()
- def on_device_state_changed(self, *args): - device = args[0] - new_state = args[1] + def on_device_state_changed(self, device, new_state, *args): + self.emit("device-state-changed", device.get_iface(), new_state, *args) if new_state == NetworkManager.DeviceState.SECONDARIES: return self._refresh_carrier_info() - if device == self.selected_device(): - self.refresh_ui(device, new_state) + dev_cfg = self.selected_dev_cfg() + if dev_cfg and dev_cfg.device == device: + self.refresh_ui(state=new_state)
def on_device_config_changed(self, device, *args): - if device == self.selected_device(): - self.refresh_ui(device) + dev_cfg = self.selected_dev_cfg() + if dev_cfg and dev_cfg.device == device: + self.refresh_ui()
def on_wireless_ap_changed_cb(self, combobox, *args): if self._updating_device: @@ -384,13 +464,13 @@ class NetworkControlBox(object): if not iter: return
- device = self.selected_device() + device = self.selected_dev_cfg().device ap_obj_path, ssid_target = combobox.get_model().get(iter, 0, 1) self.selected_ssid = ssid_target if ap_obj_path == "ap-other...": return
- log.info("network: access point changed: %s" % ssid_target) + log.info("network: selected access point: %s" % ssid_target)
try: uuid = nm.nm_ap_setting_value(ssid_target, "connection", "uuid") @@ -409,40 +489,32 @@ class NetworkControlBox(object): self.remove_device(device)
def on_edit_connection(self, *args): - device = self.selected_device() - if not device: + dev_cfg = self.selected_dev_cfg() + if not dev_cfg: return
- devname = device.get_iface() - uuid = None - try: - uuid = nm.nm_device_active_con_uuid(devname) - except nm.UnknownDeviceError as e: - log.debug("network: on_edit_connection: %s" % e) - if not uuid: - if device.get_device_type() == NetworkManager.DeviceType.WIFI: - if self.selected_ssid: - try: - uuid = nm.nm_ap_setting_value(self.selected_ssid, "connection", "uuid") - except nm.SettingsNotFoundError as e: - log.debug("network: on_edit_connection: %s" % e) - else: - uuid = nm.nm_device_setting_value(devname, "connection", "uuid") + uuid = dev_cfg.con_uuid + devname = dev_cfg.get_iface() + activate = None + + if dev_cfg.device_type == NetworkManager.DeviceType.WIFI: + if self.selected_ssid: + try: + uuid = nm.nm_ap_setting_value(self.selected_ssid, "connection", "uuid") + except nm.SettingsNotFoundError as e: + log.debug("network: on_edit_connection: %s" % e) + else: + # 871132 auto activate wireless connection after editing if it is not + # already activated (assume entering secrets) + if self.selected_ssid != nm.nm_device_active_ssid(devname): + activate = (uuid, devname)
if not uuid: log.debug("network: on_edit_connection: can't find connection for device %s" % devname) return
- # 871132 auto activate wireless connection after editing if it is not - # already activated (assume entering secrets) - activate = None - if (device.get_device_type() == NetworkManager.DeviceType.WIFI - and self.selected_ssid - and self.selected_ssid != nm.nm_device_active_ssid(devname)): - activate = (uuid, devname) - log.info("network: configuring connection %s device %s ssid %s" % - (uuid, devname, self.selected_ssid)) + uuid, devname, self.selected_ssid) self.kill_nmce(msg="Configure button clicked") proc = subprocess.Popen(["nm-connection-editor", "--edit", "%s" % uuid]) self._running_nmce = proc @@ -483,28 +555,29 @@ class NetworkControlBox(object): return
active = switch.get_active() - device = self.selected_device() + dev_cfg = self.selected_dev_cfg()
log.info("network: device %s switched %s" % - (device.get_iface(), "on" if active else "off")) + (dev_cfg.get_iface(), "on" if active else "off"))
- dev_type = device.get_device_type() - if dev_type in self.wired_ui_device_types: + if dev_cfg.device_type == NetworkManager.DeviceType.WIFI: + self.client.wireless_set_enabled(active) + else: if active: - uuid = nm.nm_device_setting_value(device.get_iface(), "connection", "uuid") - if uuid: - try: - nm.nm_activate_device_connection(device.get_iface(), uuid) - except nm.UnmanagedDeviceError as e: - log.debug("network: on_device_off_toggled: %s" % e) - else: - self.client.add_and_activate_connection(None, device, None, - None, None) + dev_name = dev_cfg.device and dev_cfg.device.get_iface() + if not dev_cfg.con_uuid: + log.debug("network: on_device_off_toggled: no connection for %s" + % dev_name) + return + try: + nm.nm_activate_device_connection(dev_name, dev_cfg.con_uuid) + except (nm.UnmanagedDeviceError, nm.UnknownDeviceError) as e: + log.debug("network: on_device_off_toggled: %s" % e) else: - device.disconnect(None, None) - elif dev_type == NetworkManager.DeviceType.WIFI: - self.client.wireless_set_enabled(active) - + try: + nm.nm_disconnect_device(dev_cfg.get_iface()) + except (nm.UnmanagedDeviceError, nm.DeviceNotActiveError) as e: + log.debug("network: on_device_off_toggled: %s" % e)
def on_add_device_clicked(self, *args): dialog = self.builder.get_object("add_device_dialog") @@ -532,130 +605,129 @@ class NetworkControlBox(object): self._running_nmce = None network.logIfcfgFiles("nm-c-e run")
- def selected_device(self): + def selected_dev_cfg(self): selection = self.builder.get_object("treeview_devices").get_selection() - (model, iter) = selection.get_selected() + model, iter = selection.get_selected() if not iter: return None - return model.get(iter, DEVICES_COLUMN_OBJECT)[0] + return model[iter][DEVICES_COLUMN_OBJECT]
- def _device_is_stored(self, nm_device): - """Check that device with Udi of nm_device is already in liststore""" - udi = nm_device.get_udi() - model = self.builder.get_object("liststore_devices") - for row in model: - if udi == row[DEVICES_COLUMN_OBJECT].get_udi(): - return True - return False + def add_dev_cfg(self, dev_cfg): + log.debug ("network: GUI, device configuration added: connection %s device %s" + % (dev_cfg.con_uuid, dev_cfg.get_iface())) + self.builder.get_object("liststore_devices").append([ + self._dev_icon_name(dev_cfg), + self.device_type_sort_value.get(dev_cfg.device_type, "100"), + self._dev_title(dev_cfg), + dev_cfg + ])
def add_device_to_list(self, device): - if self._device_is_stored(device): - return - if device.get_device_type() not in self.supported_device_types: return
- device.connect("state-changed", self.on_device_state_changed) + try: + con_uuid = nm.nm_device_setting_value(device.get_iface(), "connection", "uuid") + dev_cfg = self.dev_cfg(uuid=con_uuid) + except nm.SettingsNotFoundError: + # wireless devices + dev_cfg = None + if dev_cfg: + dev_cfg.device = device + else: + dev_cfg = DeviceConfiguration(device=device) + self.add_dev_cfg(dev_cfg)
- self.builder.get_object("liststore_devices").append([ - self._dev_icon_name(device), - self._dev_type_sort_value(device), - self._dev_title(device), - device, - ]) + device.connect("notify::ip4-config", self.on_device_config_changed) + device.connect("notify::ip6-config", self.on_device_config_changed) + device.connect("state-changed", self.on_device_state_changed)
- def _dev_icon_name(self, device): + def _dev_icon_name(self, dev_cfg): icon_name = "" - dev_type = device.get_device_type() - if dev_type in self.wired_ui_device_types: - if device.get_state() == NetworkManager.DeviceState.UNAVAILABLE: - icon_name = "network-wired-disconnected" + if dev_cfg.device_type in self.wired_ui_device_types: + if dev_cfg.device: + if dev_cfg.device.get_state() == NetworkManager.DeviceState.UNAVAILABLE: + icon_name = "network-wired-disconnected" + else: + icon_name = "network-wired" else: - icon_name = "network-wired" - elif dev_type == NetworkManager.DeviceType.WIFI: + icon_name = "network-wired-disconnected" + elif dev_cfg.device_type == NetworkManager.DeviceType.WIFI: icon_name = "network-wireless"
return icon_name
- def _dev_type_sort_value(self, device): - dev_type = device.get_device_type() - if dev_type == NetworkManager.DeviceType.ETHERNET: - str = "1" - elif dev_type == NetworkManager.DeviceType.WIFI: - str = "2" - else: - str = "3" - return str - - def _dev_title(self, device): + def _dev_title(self, dev_cfg): unplugged = '' - if (device.get_state() == NetworkManager.DeviceState.UNAVAILABLE - and device.get_device_type() == NetworkManager.DeviceType.ETHERNET - and not device.get_carrier()): - # Translators: ethernet cable is unplugged - unplugged = ', <i>%s</i>' % _("unplugged") - title = '<span size="large">%s (%s%s)</span>' % (self._dev_type_str(device), - device.get_iface(), - unplugged) - title += '\n<span size="small">%s %s</span>' % (device.get_vendor() or "", - device.get_product() or "") + if dev_cfg.device: + if (dev_cfg.device.get_state() == NetworkManager.DeviceState.UNAVAILABLE + and dev_cfg.device.get_device_type() == NetworkManager.DeviceType.ETHERNET + and not dev_cfg.device.get_carrier()): + # Translators: ethernet cable is unplugged + unplugged = ', <i>%s</i>' % _("unplugged") + title = '<span size="large">%s (%s%s)</span>' % \ + (self.device_type_name.get(dev_cfg.device_type, ""), + dev_cfg.get_iface(), + unplugged) + + if dev_cfg.device: + title += '\n<span size="small">%s %s</span>' % \ + (dev_cfg.device.get_vendor() or "", + dev_cfg.device.get_product() or "") return title
- def _dev_type_str(self, device): - dev_type = device.get_device_type() - if dev_type == NetworkManager.DeviceType.UNKNOWN: - title = _("Unknown") - elif dev_type == NetworkManager.DeviceType.ETHERNET: - title = _("Ethernet") - elif dev_type == NetworkManager.DeviceType.WIFI: - title = _("Wireless") - elif dev_type == NetworkManager.DeviceType.BOND: - title = _("Bond") - elif dev_type == NetworkManager.DeviceType.VLAN: - title = _("Vlan") - elif dev_type == NetworkManager.DeviceType.TEAM: - title = _("Team") - else: - title = "" - return title + def dev_cfg(self, uuid=None, device=None): + model = self.builder.get_object("liststore_devices") + for row in model: + dev_cfg = row[DEVICES_COLUMN_OBJECT] + if uuid: + if uuid != dev_cfg.con_uuid: + continue + if device: + if not dev_cfg.device \ + or dev_cfg.device.get_udi() != device.get_udi(): + continue + return dev_cfg + return None
def remove_device(self, device): # This should not concern wifi and ethernet devices, # just virtual devices e.g. vpn probably - # TODO test!, remove perhaps - model = self.builder.get_object("liststore_devices") - rows_to_remove = [] - for row in model: - if (device.get_udi() == row[DEVICES_COLUMN_OBJECT].get_udi()): - rows_to_remove.append(row) - for row in rows_to_remove: - del(row) + log.debug("network: GUI, device removed: %s" % (device.get_iface())) + self.dev_cfg(device=device).device = None
- def refresh_ui(self, device, state=None): + def refresh_ui(self, state=None):
- if not device: + dev_cfg = self.selected_dev_cfg() + if not dev_cfg: + # the list is empty (no supported devices) notebook = self.builder.get_object("notebook_types") notebook.set_current_page(5) return
- self._refresh_device_type_page(device) - self._refresh_header_ui(device, state) - self._refresh_slaves(device) - self._refresh_parent_vlanid(device) - self._refresh_speed_hwaddr(device, state) - self._refresh_ap(device, state) - self._refresh_device_cfg(device) + self._refresh_device_type_page(dev_cfg.device_type) + self._refresh_header_ui(dev_cfg, state) + self._refresh_slaves(dev_cfg) + self._refresh_parent_vlanid(dev_cfg) + self._refresh_speed_hwaddr(dev_cfg, state) + self._refresh_ap(dev_cfg, state) + self._refresh_device_cfg(dev_cfg)
- def _refresh_device_cfg(self, device): + def _refresh_device_cfg(self, dev_cfg):
- dev_type = device.get_device_type() - if dev_type in self.wired_ui_device_types: + if dev_cfg.device_type in self.wired_ui_device_types: dt = "wired" - elif dev_type == NetworkManager.DeviceType.WIFI: + elif dev_cfg.device_type == NetworkManager.DeviceType.WIFI: dt = "wireless"
- ipv4cfg = nm.nm_device_ip_config(device.get_iface(), version=4) - ipv6cfg = nm.nm_device_ip_config(device.get_iface(), version=6) + if dev_cfg.device: + try: + ipv4cfg = nm.nm_device_ip_config(dev_cfg.device.get_iface(), version=4) + ipv6cfg = nm.nm_device_ip_config(dev_cfg.device.get_iface(), version=6) + except nm.UnknownDeviceError: + ipv4cfg = ipv6cfg = None + else: + ipv4cfg = ipv6cfg = None
if ipv4cfg and ipv4cfg[0]: addr_str, prefix, gateway_str = ipv4cfg[0][0] @@ -689,16 +761,16 @@ class NetworkControlBox(object):
return False
- def _refresh_ap(self, device, state=None): - if device.get_device_type() != NetworkManager.DeviceType.WIFI: + def _refresh_ap(self, dev_cfg, state=None): + if dev_cfg.device_type != NetworkManager.DeviceType.WIFI: return
if state is None: - state = device.get_state() + state = dev_cfg.device.get_state() if state == NetworkManager.DeviceState.UNAVAILABLE: ap_str = None else: - active_ap = device.get_active_access_point() + active_ap = dev_cfg.device.get_active_access_point() if active_ap: active_ap_dbus = dbus.SystemBus().get_object(NM_SERVICE, active_ap.get_path()) @@ -722,7 +794,7 @@ class NetworkControlBox(object): store = self.builder.get_object("liststore_wireless_network") self._updating_device = True store.clear() - aps = self._get_strongest_unique_aps(device.get_access_points()) + aps = self._get_strongest_unique_aps(dev_cfg.device.get_access_points()) for ap in aps: active = active_ap and active_ap.get_path() == ap.get_path() self._add_ap(ap, active) @@ -736,47 +808,53 @@ class NetworkControlBox(object): break self._updating_device = False
- def _refresh_slaves(self, device): - dev_type = device.get_device_type() - if dev_type in [NetworkManager.DeviceType.BOND, - NetworkManager.DeviceType.TEAM]: - slaves = ",".join(s.get_iface() - for s in device.get_slaves()) + def _refresh_slaves(self, dev_cfg): + if dev_cfg.device_type in [NetworkManager.DeviceType.BOND, + NetworkManager.DeviceType.TEAM]: + slaves = "" + if dev_cfg.device: + slaves = ",".join(s.get_iface() for s in dev_cfg.device.get_slaves()) self._set_device_info_value("wired", "slaves", slaves)
- def _refresh_parent_vlanid(self, device): - dev_type = device.get_device_type() - if dev_type == NetworkManager.DeviceType.VLAN: - self._set_device_info_value("wired", "vlanid", str(device.get_vlan_id())) - parent = nm.nm_device_setting_value(device.get_iface(), "vlan", "parent") - self._set_device_info_value("wired", "parent", parent) + def _refresh_parent_vlanid(self, dev_cfg): + if dev_cfg.device_type == NetworkManager.DeviceType.VLAN: + if dev_cfg.device: + vlanid = dev_cfg.device.get_vlan_id() + else: + vlanid = dev_cfg.setting_value("vlan", "id") + parent = dev_cfg.setting_value("vlan", "parent") + self._set_device_info_value("wired", "vlanid", str(vlanid))
- def _refresh_speed_hwaddr(self, device, state=None): - dev_type = device.get_device_type() + def _refresh_speed_hwaddr(self, dev_cfg, state=None): + dev_type = dev_cfg.device_type if dev_type in self.wired_ui_device_types: dt = "wired" elif dev_type == NetworkManager.DeviceType.WIFI: dt = "wireless" - speed = None - if dev_type == NetworkManager.DeviceType.ETHERNET: - speed = device.get_speed() - elif dev_type == NetworkManager.DeviceType.WIFI: - speed = device.get_bitrate() / 1000
- if state is None: - state = device.get_state() - if state == NetworkManager.DeviceState.UNAVAILABLE: + # Speed + speed = None + if dev_cfg.device: + if dev_type == NetworkManager.DeviceType.ETHERNET: + speed = dev_cfg.device.get_speed() + elif dev_type == NetworkManager.DeviceType.WIFI: + speed = dev_cfg.device.get_bitrate() / 1000 + if state is None: + state = dev_cfg.device.get_state() + + if not dev_cfg.device or state == NetworkManager.DeviceState.UNAVAILABLE: speed_str = None elif speed: speed_str = _("%d Mb/s") % speed else: speed_str = "" self._set_device_info_value(dt, "speed", speed_str) - self._set_device_info_value(dt, "mac", device.get_hw_address()) + # Hardware address + hwaddr = dev_cfg.device and dev_cfg.device.get_hw_address() + self._set_device_info_value(dt, "mac", hwaddr)
- def _refresh_device_type_page(self, device): + def _refresh_device_type_page(self, dev_type): notebook = self.builder.get_object("notebook_types") - dev_type = device.get_device_type() if dev_type == NetworkManager.DeviceType.ETHERNET: notebook.set_current_page(0) self.builder.get_object("heading_wired_slaves").hide() @@ -798,10 +876,10 @@ class NetworkControlBox(object): notebook.set_current_page(0) self.builder.get_object("heading_wired_slaves").hide() self.builder.get_object("label_wired_slaves").hide() - self.builder.get_object("heading_wired_vlanid").hide() - self.builder.get_object("label_wired_vlanid").hide() - self.builder.get_object("heading_wired_parent").hide() - self.builder.get_object("label_wired_parent").hide() + self.builder.get_object("heading_wired_vlanid").show() + self.builder.get_object("label_wired_vlanid").show() + self.builder.get_object("heading_wired_parent").show() + self.builder.get_object("label_wired_parent").show() elif dev_type == NetworkManager.DeviceType.WIFI: notebook.set_current_page(1) self.builder.get_object("button_wireless_options").set_sensitive(self.selected_ssid is not None) @@ -810,29 +888,29 @@ class NetworkControlBox(object): for i in self.builder.get_object("liststore_devices"): i[DEVICES_COLUMN_TITLE] = self._dev_title(i[DEVICES_COLUMN_OBJECT])
- def _refresh_header_ui(self, device, state=None): - dev_type = device.get_device_type() - if dev_type in (NetworkManager.DeviceType.ETHERNET, - NetworkManager.DeviceType.TEAM, - NetworkManager.DeviceType.BOND, - NetworkManager.DeviceType.VLAN): + def _refresh_header_ui(self, dev_cfg, state=None): + if dev_cfg.device_type in self.wired_ui_device_types: dev_type_str = "wired" - elif dev_type == NetworkManager.DeviceType.WIFI: + elif dev_cfg.device_type == NetworkManager.DeviceType.WIFI: dev_type_str = "wireless"
if dev_type_str == "wired": # update icon according to device status img = self.builder.get_object("image_wired_device") - img.set_from_icon_name(self._dev_icon_name(device), Gtk.IconSize.DIALOG) + img.set_from_icon_name(self._dev_icon_name(dev_cfg), Gtk.IconSize.DIALOG)
# TODO: is this necessary? Isn't it static from glade? self.builder.get_object("label_%s_device" % dev_type_str).set_label( - "%s (%s)" % (self._dev_type_str(device), device.get_iface())) + "%s (%s)" % (self.device_type_name.get(dev_cfg.device_type, ""), dev_cfg.get_iface()))
if state is None: - state = device.get_state() + if not dev_cfg.device: + state = NetworkManager.DeviceState.DISCONNECTED + else: + state = dev_cfg.device.get_state() + self.builder.get_object("label_%s_status" % dev_type_str).set_label( - localized_string_of_device_state(device, state)) + localized_string_of_device_state(dev_cfg.device, state))
switch = self.builder.get_object("device_%s_off_switch" % dev_type_str) if dev_type_str == "wired": @@ -987,7 +1065,7 @@ class NetworkControlBox(object): return sec_str
@property - def listed_devices(self): + def dev_cfgs(self): return [row[DEVICES_COLUMN_OBJECT] for row in self.builder.get_object("liststore_devices")]
@@ -1195,11 +1273,10 @@ class NetworkSpoke(FirstbootSpokeMixIn, NormalSpoke): NormalSpoke.__init__(self, *args, **kwargs) self.network_control_box = NetworkControlBox(self.builder, spoke=self) self.network_control_box.hostname = self.data.network.hostname - self.network_control_box.client.connect("notify::%s" % - NMClient.CLIENT_STATE, - self.on_nm_state_changed) - for device in self.network_control_box.client.get_devices(): - device.connect("state-changed", self.on_device_state_changed) + self.network_control_box.connect("nm-state-changed", + self.on_nm_state_changed) + self.network_control_box.connect("device-state-changed", + self.on_device_state_changed)
def apply(self): _update_network_data(self.data, self.network_control_box) @@ -1243,8 +1320,7 @@ class NetworkSpoke(FirstbootSpokeMixIn, NormalSpoke): gtk_call_once(self._update_status) gtk_call_once(self._update_hostname)
- def on_device_state_changed(self, *args): - new_state = args[1] + def on_device_state_changed(self, source, device, new_state, *args): if new_state in (NetworkManager.DeviceState.ACTIVATED, NetworkManager.DeviceState.DISCONNECTED, NetworkManager.DeviceState.UNAVAILABLE): @@ -1288,9 +1364,8 @@ class NetworkStandaloneSpoke(StandaloneSpoke): parent = self.builder.get_object("AnacondaStandaloneWindow-action_area5") parent.add(self.network_control_box.vbox)
- self.network_control_box.client.connect("notify::%s" % - NMClient.CLIENT_STATE, - self.on_nm_state_changed) + self.network_control_box.connect("nm-state-changed", + self.on_nm_state_changed)
self._initially_available = self.completed log.debug("network standalone spoke (init): completed: %s" % self._initially_available) @@ -1353,9 +1428,9 @@ class NetworkStandaloneSpoke(StandaloneSpoke):
def _update_network_data(data, ncb): data.network.network = [] - for dev in ncb.listed_devices: - devname = dev.get_iface() - nd = network.ksdata_from_ifcfg(devname) + for dev_cfg in ncb.dev_cfgs: + devname = dev_cfg.get_iface() + nd = network.ksdata_from_ifcfg(devname, dev_cfg.con_uuid) if not nd: continue if devname in nm.nm_activated_devices(): @@ -1365,7 +1440,6 @@ def _update_network_data(data, ncb): network.update_hostname_data(data, hostname)
if __name__ == "__main__": - win = Gtk.Window() win.connect("delete-event", Gtk.main_quit)
On Fri, 2013-11-29 at 13:17 +0100, Radek Vykydal wrote:
Resolves: rhbz#1036047
Don't crash when the device is turned off. The items of device treeview are device configurations, not devices.
pyanaconda/network.py | 29 +- pyanaconda/nm.py | 28 +- pyanaconda/ui/gui/spokes/network.glade | 2 +- pyanaconda/ui/gui/spokes/network.py | 508 +++++++++++++++++++-------------- 4 files changed, 333 insertions(+), 234 deletions(-)
diff --git a/pyanaconda/network.py b/pyanaconda/network.py index 4719450..8dc7893 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -484,7 +484,7 @@ def add_connection_for_ksdata(networkdata, devname): svalues.append(['connection', 'slave-type', 'bond', 's']) svalues.append(['connection', 'master', devname, 's']) svalues.append(['connection', 'type', '802-3-ethernet', 's'])
mac = nm.nm_device_hwaddress(slave)
mac = nm.nm_device_perm_hwaddress(slave) mac = [int(b, 16) for b in mac.split(":")] svalues.append(['802-3-ethernet', 'mac-address', mac, 'ay'])
@@ -518,7 +518,7 @@ def add_connection_for_ksdata(networkdata, devname): svalues.append(['connection', 'slave-type', 'team', 's']) svalues.append(['connection', 'master', devname, 's']) svalues.append(['connection', 'type', '802-3-ethernet', 's'])
mac = nm.nm_device_hwaddress(slave)
mac = nm.nm_device_perm_hwaddress(slave) mac = [int(b, 16) for b in mac.split(":")] svalues.append(['802-3-ethernet', 'mac-address', mac, 'ay']) svalues.append(['team-port', 'config', cfg, 's'])
@@ -547,7 +547,7 @@ def add_connection_for_ksdata(networkdata, devname): else: values.append(['connection', 'type', '802-3-ethernet', 's']) values.append(['connection', 'id', devname, 's'])
mac = nm.nm_device_hwaddress(devname)
mac = nm.nm_device_perm_hwaddress(devname) mac = [int(b, 16) for b in mac.split(":")] values.append(['802-3-ethernet', 'mac-address', mac, 'ay']) dev_spec = devname
@@ -556,20 +556,23 @@ def add_connection_for_ksdata(networkdata, devname): added_connections.insert(0, (con_uuid, dev_spec)) return added_connections
-def ksdata_from_ifcfg(devname): +def ksdata_from_ifcfg(devname, uuid=None):
if nm.nm_device_is_slave(devname): return None
- if nm.nm_device_type_is_wifi(devname):
# wifi from kickstart is not supported yet
return None
- ifcfg_path = None
- if not uuid:
# Find ifcfg file for the device.
# If the device is active, use uuid of its active connection.
uuid = nm.nm_device_active_con_uuid(devname)
- # Find ifcfg file for the device.
- # If the device is active, use uuid of its active connection.
- uuid = nm.nm_device_active_con_uuid(devname) if uuid: ifcfg_path = find_ifcfg_file([("UUID", uuid)]) else:
# If not, look it up by other values depending on its type
# look it up by other values depending on its type ifcfg_path = find_ifcfg_file_of_device(devname)
if not ifcfg_path:
@@ -738,7 +741,7 @@ def find_ifcfg_file_of_device(devname, root_path=""): ifcfg_path = find_ifcfg_file([("DEVICE", devname)]) elif nm.nm_device_type_is_ethernet(devname): try:
hwaddr = nm.nm_device_hwaddress(devname)
hwaddr = nm.nm_device_perm_hwaddress(devname) except nm.PropertyNotFoundError: hwaddr = None if hwaddr:
@@ -922,7 +925,7 @@ def ks_spec_to_device_name(ksspec=""): # "XX:XX:XX:XX:XX:XX" (mac address) elif ':' in ksdevice: try:
hwaddr = nm.nm_device_hwaddress(dev)
hwaddr = nm.nm_device_perm_hwaddress(dev) except ValueError as e: log.debug("ks_spec_to_device_name: %s" % e) continue
@@ -932,7 +935,7 @@ def ks_spec_to_device_name(ksspec=""): # "bootif" and BOOTIF==XX:XX:XX:XX:XX:XX elif ksdevice == 'bootif': try:
hwaddr = nm.nm_device_hwaddress(dev)
hwaddr = nm.nm_device_perm_hwaddress(dev) except ValueError as e: log.debug("ks_spec_to_device_name: %s" % e) continue
@@ -1146,7 +1149,7 @@ def get_device_name(devspec): if devname and devname not in devices: for d in devices: try:
hwaddr = nm.nm_device_hwaddress(d)
hwaddr = nm.nm_device_perm_hwaddress(d) except ValueError as e: log.debug("get_device_name: %s" % e) continue
diff --git a/pyanaconda/nm.py b/pyanaconda/nm.py index 8f8256b..0d1d4a1 100644 --- a/pyanaconda/nm.py +++ b/pyanaconda/nm.py @@ -48,6 +48,11 @@ class UnmanagedDeviceError(Exception): def __str__(self): return self.__repr__()
+class DeviceNotActiveError(Exception):
- """Device of specified name is not active"""
- def __str__(self):
return self.__repr__()
class PropertyNotFoundError(ValueError): """Property of NM object was not found""" def __str__(self): @@ -267,6 +272,18 @@ def nm_device_hwaddress(name): """ return nm_device_property(name, "HwAddress")
+def nm_device_perm_hwaddress(name):
- """Return active hardware address of device ('HwAddress' property)
:param name: name of device
:type name: str
:return: active hardware address of device ('HwAddress' property)
:rtype: str
:raise UnknownDeviceError: if device is not found
:raise PropertyNotFoundError: if 'HwAddress' property is not found
- """
- return nm_device_property(name, "PermHwAddress")
def nm_device_active_con_uuid(name): """Return uuid of device's active connection
@@ -433,7 +450,7 @@ def nm_hwaddr_to_device_name(hwaddr): :rtype: str """ for device in nm_devices():
if nm_device_hwaddress(device).upper() == hwaddr.upper():
return Noneif nm_device_perm_hwaddress(device).upper() == hwaddr.upper(): return device
@@ -478,7 +495,7 @@ def _device_settings(name): settings = _find_settings(name, 'connection', 'interface-name') if not settings: try:
hwaddr_str = nm_device_hwaddress(name)
hwaddr_str = nm_device_perm_hwaddress(name) except PropertyNotFoundError: settings = [] else:
@@ -618,7 +635,12 @@ def nm_disconnect_device(name): raise
device_proxy = _get_proxy(object_path=device, interface_name="org.freedesktop.NetworkManager.Device")
- device_proxy.Disconnect()
- try:
device_proxy.Disconnect()
- except GLib.GError as e:
if "org.freedesktop.NetworkManager.Device.NotActive" in e.message:
raise DeviceNotActiveError(name, e)
raise
def nm_activate_device_connection(dev_name, con_uuid): """Activate device with specified connection. diff --git a/pyanaconda/ui/gui/spokes/network.glade b/pyanaconda/ui/gui/spokes/network.glade index 1b65d83..d9d945e 100644 --- a/pyanaconda/ui/gui/spokes/network.glade +++ b/pyanaconda/ui/gui/spokes/network.glade @@ -136,7 +136,7 @@ <!-- column-name sort --> <column type="gchararray"/> <!-- column-name object -->
<column type="GObject"/>
<column type="PyObject"/>
</columns> </object> <object class="GtkListStore" id="liststore_wireless_network">
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index bbfb75a..0c822b7 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -58,10 +58,6 @@ import string from dbus.mainloop.glib import DBusGMainLoop dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-import ctypes -ctypes.cdll.LoadLibrary("libnm-util.so.2") -nm_utils = ctypes.CDLL("libnm-util.so.2")
import logging log = logging.getLogger("anaconda")
@@ -96,7 +92,9 @@ def localized_string_of_device_state(device, state): elif state == NetworkManager.DeviceState.UNMANAGED: str = _("Unmanaged") elif state == NetworkManager.DeviceState.UNAVAILABLE:
if device.get_firmware_missing():
if not device:
str = _("Unavailable")
elif device.get_firmware_missing(): str = _("Firmware missing") elif (device.get_device_type() == NetworkManager.DeviceType.ETHERNET and not device.get_carrier()):
@@ -212,7 +210,65 @@ class CellRendererSecurity(Gtk.CellRendererPixbuf):
self.set_property("icon-name", self.icon_name)
-class NetworkControlBox(object): +class DeviceConfiguration(object):
- setting_types = {
'802-11-wireless': NetworkManager.DeviceType.WIFI,
'802-3-ethernet': NetworkManager.DeviceType.ETHERNET,
'vlan': NetworkManager.DeviceType.VLAN,
'bond': NetworkManager.DeviceType.BOND,
'team': NetworkManager.DeviceType.TEAM,
}
- def __init__(self, device=None, con_uuid=None):
self.device = device
self.con_uuid = con_uuid
if device:
self.device_type = self.device.get_device_type()
elif con_uuid:
self.device_type = self._setting_device_type(self.con_uuid)
if not self.con_uuid:
if self.device_type != NetworkManager.DeviceType.WIFI:
uuid = nm.nm_device_setting_value(device.get_iface(), "connection", "uuid")
settings = nm.nm_get_settings(uuid, "connection", "uuid")
if settings and 'slave-type' not in settings[0]['connection']:
self.con_uuid = uuid
- def _setting_device_type(self, uuid):
settings = nm.nm_get_settings(uuid, "connection", "uuid")
if not settings:
return None
dev_type = self.setting_types.get(settings[0]["connection"]["type"], None)
return dev_type
- def get_iface(self):
if self.device:
iface = self.device.get_iface()
else:
iface = self.setting_value("connection", "interface-name")
return iface
- def setting_value(self, key1, key2):
settings = nm.nm_get_settings(self.con_uuid, "connection", "uuid")
try:
value = settings[0][key1][key2]
except IndexError as e:
log.debug("network: can't find connection with uuid %s"
% self.con_uuid)
except KeyError as e:
log.debug("network: can't find '%s' '%s' in connection %s"
% (key1, key2, self.con_uuid))
else:
return value
+class NetworkControlBox(GObject.GObject):
__gsignals__ = {
"nm-state-changed": (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, []),
"device-state-changed": (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, [str, int, int, int]),
}
supported_device_types = [ NetworkManager.DeviceType.ETHERNET,
@@ -229,8 +285,24 @@ class NetworkControlBox(object): NetworkManager.DeviceType.VLAN, ]
device_type_sort_value = {
NetworkManager.DeviceType.ETHERNET : "1",
NetworkManager.DeviceType.WIFI : "2",
}
device_type_name = {
NetworkManager.DeviceType.UNKNOWN: _("Unknown"),
NetworkManager.DeviceType.ETHERNET: _("Ethernet"),
NetworkManager.DeviceType.WIFI: _("Wireless"),
NetworkManager.DeviceType.BOND: _("Bond"),
NetworkManager.DeviceType.VLAN: _("Vlan"),
NetworkManager.DeviceType.TEAM: _("Team"),
}
def __init__(self, builder, spoke=None):
GObject.GObject.__init__(self)
self.builder = builder self._running_nmce = None self.spoke = spoke
@@ -306,6 +378,8 @@ class NetworkControlBox(object): self.on_edit_connection) self.entry_hostname = self.builder.get_object("entry_hostname")
self.client.connect("notify::%s" % NMClient.CLIENT_STATE,
self.on_nm_state_changed)
@property def vbox(self):
@@ -340,10 +414,18 @@ class NetworkControlBox(object):
def initialize(self): for device in self.client.get_devices():
device.connect("notify::ip4-config", self.on_device_config_changed)
device.connect("notify::ip6-config", self.on_device_config_changed) self.add_device_to_list(device)
for setting in nm.nm_get_all_settings():
uuid = setting["connection"]["uuid"]
log.debug("network: GUI, connection %s found" % uuid)
if self.dev_cfg(uuid=uuid):
continue
dev_cfg = DeviceConfiguration(con_uuid=uuid)
if dev_cfg.device_type in self.supported_device_types:
self.add_dev_cfg(dev_cfg)
# select the first device treeview = self.builder.get_object("treeview_devices") devices_store = self.builder.get_object("liststore_devices") selection = treeview.get_selection()
@@ -352,30 +434,28 @@ class NetworkControlBox(object): selection.select_iter(itr)
def refresh(self):
device = self.selected_device()
self.refresh_ui(device)
self.refresh_ui()
# Signal handlers.
- def on_device_selection_changed(self, *args):
device = self.selected_device()
if not device:
return
- def on_nm_state_changed(self, *args):
self.emit("nm-state-changed")
log.debug("network: selected device %s" % device.get_iface())
self.refresh_ui(device)
- def on_device_selection_changed(self, *args):
self.refresh_ui()
- def on_device_state_changed(self, *args):
device = args[0]
new_state = args[1]
- def on_device_state_changed(self, device, new_state, *args):
self.emit("device-state-changed", device.get_iface(), new_state, *args) if new_state == NetworkManager.DeviceState.SECONDARIES: return self._refresh_carrier_info()
if device == self.selected_device():
self.refresh_ui(device, new_state)
dev_cfg = self.selected_dev_cfg()
if dev_cfg and dev_cfg.device == device:
self.refresh_ui(state=new_state)
def on_device_config_changed(self, device, *args):
if device == self.selected_device():
self.refresh_ui(device)
dev_cfg = self.selected_dev_cfg()
if dev_cfg and dev_cfg.device == device:
self.refresh_ui()
def on_wireless_ap_changed_cb(self, combobox, *args): if self._updating_device:
@@ -384,13 +464,13 @@ class NetworkControlBox(object): if not iter: return
device = self.selected_device()
device = self.selected_dev_cfg().device
The value returned from self.selected_dev_cfg() should be checked for not being None first. At least that's what is done in all the other places.
ap_obj_path, ssid_target = combobox.get_model().get(iter, 0, 1) self.selected_ssid = ssid_target if ap_obj_path == "ap-other...": return
log.info("network: access point changed: %s" % ssid_target)
log.info("network: selected access point: %s" % ssid_target) try: uuid = nm.nm_ap_setting_value(ssid_target, "connection", "uuid")
@@ -409,40 +489,32 @@ class NetworkControlBox(object): self.remove_device(device)
def on_edit_connection(self, *args):
device = self.selected_device()
if not device:
dev_cfg = self.selected_dev_cfg()
if not dev_cfg: return
devname = device.get_iface()
uuid = None
try:
uuid = nm.nm_device_active_con_uuid(devname)
except nm.UnknownDeviceError as e:
log.debug("network: on_edit_connection: %s" % e)
if not uuid:
if device.get_device_type() == NetworkManager.DeviceType.WIFI:
if self.selected_ssid:
try:
uuid = nm.nm_ap_setting_value(self.selected_ssid, "connection", "uuid")
except nm.SettingsNotFoundError as e:
log.debug("network: on_edit_connection: %s" % e)
else:
uuid = nm.nm_device_setting_value(devname, "connection", "uuid")
uuid = dev_cfg.con_uuid
devname = dev_cfg.get_iface()
activate = None
if dev_cfg.device_type == NetworkManager.DeviceType.WIFI:
if self.selected_ssid:
try:
uuid = nm.nm_ap_setting_value(self.selected_ssid, "connection", "uuid")
except nm.SettingsNotFoundError as e:
log.debug("network: on_edit_connection: %s" % e)
else:
# 871132 auto activate wireless connection after editing if it is not
# already activated (assume entering secrets)
if self.selected_ssid != nm.nm_device_active_ssid(devname):
activate = (uuid, devname) if not uuid: log.debug("network: on_edit_connection: can't find connection for device %s" % devname) return
# 871132 auto activate wireless connection after editing if it is not
# already activated (assume entering secrets)
activate = None
if (device.get_device_type() == NetworkManager.DeviceType.WIFI
and self.selected_ssid
and self.selected_ssid != nm.nm_device_active_ssid(devname)):
activate = (uuid, devname)
log.info("network: configuring connection %s device %s ssid %s" %
(uuid, devname, self.selected_ssid))
uuid, devname, self.selected_ssid) self.kill_nmce(msg="Configure button clicked") proc = subprocess.Popen(["nm-connection-editor", "--edit", "%s" % uuid]) self._running_nmce = proc
@@ -483,28 +555,29 @@ class NetworkControlBox(object): return
active = switch.get_active()
device = self.selected_device()
dev_cfg = self.selected_dev_cfg()
Same check here? Or is it for sure some device will be selected here? `
log.info("network: device %s switched %s" %
(device.get_iface(), "on" if active else "off"))
(dev_cfg.get_iface(), "on" if active else "off"))
dev_type = device.get_device_type()
if dev_type in self.wired_ui_device_types:
if dev_cfg.device_type == NetworkManager.DeviceType.WIFI:
self.client.wireless_set_enabled(active)
else: if active:
uuid = nm.nm_device_setting_value(device.get_iface(), "connection", "uuid")
if uuid:
try:
nm.nm_activate_device_connection(device.get_iface(), uuid)
except nm.UnmanagedDeviceError as e:
log.debug("network: on_device_off_toggled: %s" % e)
else:
self.client.add_and_activate_connection(None, device, None,
None, None)
dev_name = dev_cfg.device and dev_cfg.device.get_iface()
if not dev_cfg.con_uuid:
log.debug("network: on_device_off_toggled: no connection for %s"
% dev_name)
return
try:
nm.nm_activate_device_connection(dev_name, dev_cfg.con_uuid)
except (nm.UnmanagedDeviceError, nm.UnknownDeviceError) as e:
log.debug("network: on_device_off_toggled: %s" % e) else:
device.disconnect(None, None)
elif dev_type == NetworkManager.DeviceType.WIFI:
self.client.wireless_set_enabled(active)
try:
nm.nm_disconnect_device(dev_cfg.get_iface())
except (nm.UnmanagedDeviceError, nm.DeviceNotActiveError) as e:
log.debug("network: on_device_off_toggled: %s" % e)
def on_add_device_clicked(self, *args): dialog = self.builder.get_object("add_device_dialog")
@@ -532,130 +605,129 @@ class NetworkControlBox(object): self._running_nmce = None network.logIfcfgFiles("nm-c-e run")
- def selected_device(self):
- def selected_dev_cfg(self): selection = self.builder.get_object("treeview_devices").get_selection()
(model, iter) = selection.get_selected()
model, iter = selection.get_selected() if not iter: return None
return model.get(iter, DEVICES_COLUMN_OBJECT)[0]
return model[iter][DEVICES_COLUMN_OBJECT]
- def _device_is_stored(self, nm_device):
"""Check that device with Udi of nm_device is already in liststore"""
udi = nm_device.get_udi()
model = self.builder.get_object("liststore_devices")
for row in model:
if udi == row[DEVICES_COLUMN_OBJECT].get_udi():
return True
return False
- def add_dev_cfg(self, dev_cfg):
log.debug ("network: GUI, device configuration added: connection %s device %s"
% (dev_cfg.con_uuid, dev_cfg.get_iface()))
self.builder.get_object("liststore_devices").append([
self._dev_icon_name(dev_cfg),
self.device_type_sort_value.get(dev_cfg.device_type, "100"),
self._dev_title(dev_cfg),
dev_cfg
])
The "liststore_devices" store should be pulled only once from the builder, not with every single item added.
def add_device_to_list(self, device):
if self._device_is_stored(device):
return
if device.get_device_type() not in self.supported_device_types: return
device.connect("state-changed", self.on_device_state_changed)
try:
con_uuid = nm.nm_device_setting_value(device.get_iface(), "connection", "uuid")
dev_cfg = self.dev_cfg(uuid=con_uuid)
except nm.SettingsNotFoundError:
# wireless devices
dev_cfg = None
if dev_cfg:
dev_cfg.device = device
else:
dev_cfg = DeviceConfiguration(device=device)
self.add_dev_cfg(dev_cfg)
self.builder.get_object("liststore_devices").append([
self._dev_icon_name(device),
self._dev_type_sort_value(device),
self._dev_title(device),
device,
])
device.connect("notify::ip4-config", self.on_device_config_changed)
device.connect("notify::ip6-config", self.on_device_config_changed)
device.connect("state-changed", self.on_device_state_changed)
- def _dev_icon_name(self, device):
- def _dev_icon_name(self, dev_cfg): icon_name = ""
dev_type = device.get_device_type()
if dev_type in self.wired_ui_device_types:
if device.get_state() == NetworkManager.DeviceState.UNAVAILABLE:
icon_name = "network-wired-disconnected"
if dev_cfg.device_type in self.wired_ui_device_types:
if dev_cfg.device:
if dev_cfg.device.get_state() == NetworkManager.DeviceState.UNAVAILABLE:
icon_name = "network-wired-disconnected"
else:
icon_name = "network-wired" else:
icon_name = "network-wired"
elif dev_type == NetworkManager.DeviceType.WIFI:
icon_name = "network-wired-disconnected"
elif dev_cfg.device_type == NetworkManager.DeviceType.WIFI: icon_name = "network-wireless" return icon_name
- def _dev_type_sort_value(self, device):
dev_type = device.get_device_type()
if dev_type == NetworkManager.DeviceType.ETHERNET:
str = "1"
elif dev_type == NetworkManager.DeviceType.WIFI:
str = "2"
else:
str = "3"
return str
- def _dev_title(self, device):
- def _dev_title(self, dev_cfg): unplugged = ''
if (device.get_state() == NetworkManager.DeviceState.UNAVAILABLE
and device.get_device_type() == NetworkManager.DeviceType.ETHERNET
and not device.get_carrier()):
# Translators: ethernet cable is unplugged
unplugged = ', <i>%s</i>' % _("unplugged")
title = '<span size="large">%s (%s%s)</span>' % (self._dev_type_str(device),
device.get_iface(),
unplugged)
title += '\n<span size="small">%s %s</span>' % (device.get_vendor() or "",
device.get_product() or "")
if dev_cfg.device:
if (dev_cfg.device.get_state() == NetworkManager.DeviceState.UNAVAILABLE
and dev_cfg.device.get_device_type() == NetworkManager.DeviceType.ETHERNET
and not dev_cfg.device.get_carrier()):
# Translators: ethernet cable is unplugged
We use TRANSLATORS in other places.
unplugged = ', <i>%s</i>' % _("unplugged")
title = '<span size="large">%s (%s%s)</span>' % \
(self.device_type_name.get(dev_cfg.device_type, ""),
dev_cfg.get_iface(),
unplugged)
if dev_cfg.device:
title += '\n<span size="small">%s %s</span>' % \
(dev_cfg.device.get_vendor() or "",
dev_cfg.device.get_product() or "") return title
- def _dev_type_str(self, device):
dev_type = device.get_device_type()
if dev_type == NetworkManager.DeviceType.UNKNOWN:
title = _("Unknown")
elif dev_type == NetworkManager.DeviceType.ETHERNET:
title = _("Ethernet")
elif dev_type == NetworkManager.DeviceType.WIFI:
title = _("Wireless")
elif dev_type == NetworkManager.DeviceType.BOND:
title = _("Bond")
elif dev_type == NetworkManager.DeviceType.VLAN:
title = _("Vlan")
elif dev_type == NetworkManager.DeviceType.TEAM:
title = _("Team")
else:
title = ""
return title
- def dev_cfg(self, uuid=None, device=None):
model = self.builder.get_object("liststore_devices")
Should be self._liststore_devices pulled only once.
for row in model:
dev_cfg = row[DEVICES_COLUMN_OBJECT]
if uuid:
if uuid != dev_cfg.con_uuid:
continue
if device:
if not dev_cfg.device \
or dev_cfg.device.get_udi() != device.get_udi():
continue
return dev_cfg
return None
def remove_device(self, device): # This should not concern wifi and ethernet devices, # just virtual devices e.g. vpn probably
# TODO test!, remove perhaps
model = self.builder.get_object("liststore_devices")
rows_to_remove = []
for row in model:
if (device.get_udi() == row[DEVICES_COLUMN_OBJECT].get_udi()):
rows_to_remove.append(row)
for row in rows_to_remove:
del(row)
log.debug("network: GUI, device removed: %s" % (device.get_iface()))
self.dev_cfg(device=device).device = None
- def refresh_ui(self, device, state=None):
- def refresh_ui(self, state=None):
if not device:
dev_cfg = self.selected_dev_cfg()
if not dev_cfg:
# the list is empty (no supported devices) notebook = self.builder.get_object("notebook_types") notebook.set_current_page(5) return
self._refresh_device_type_page(device)
self._refresh_header_ui(device, state)
self._refresh_slaves(device)
self._refresh_parent_vlanid(device)
self._refresh_speed_hwaddr(device, state)
self._refresh_ap(device, state)
self._refresh_device_cfg(device)
self._refresh_device_type_page(dev_cfg.device_type)
self._refresh_header_ui(dev_cfg, state)
self._refresh_slaves(dev_cfg)
self._refresh_parent_vlanid(dev_cfg)
self._refresh_speed_hwaddr(dev_cfg, state)
self._refresh_ap(dev_cfg, state)
self._refresh_device_cfg(dev_cfg)
- def _refresh_device_cfg(self, device):
- def _refresh_device_cfg(self, dev_cfg):
dev_type = device.get_device_type()
if dev_type in self.wired_ui_device_types:
if dev_cfg.device_type in self.wired_ui_device_types: dt = "wired"
elif dev_type == NetworkManager.DeviceType.WIFI:
elif dev_cfg.device_type == NetworkManager.DeviceType.WIFI: dt = "wireless"
ipv4cfg = nm.nm_device_ip_config(device.get_iface(), version=4)
ipv6cfg = nm.nm_device_ip_config(device.get_iface(), version=6)
if dev_cfg.device:
try:
ipv4cfg = nm.nm_device_ip_config(dev_cfg.device.get_iface(), version=4)
ipv6cfg = nm.nm_device_ip_config(dev_cfg.device.get_iface(), version=6)
except nm.UnknownDeviceError:
ipv4cfg = ipv6cfg = None
else:
ipv4cfg = ipv6cfg = None if ipv4cfg and ipv4cfg[0]: addr_str, prefix, gateway_str = ipv4cfg[0][0]
@@ -689,16 +761,16 @@ class NetworkControlBox(object):
return False
- def _refresh_ap(self, device, state=None):
if device.get_device_type() != NetworkManager.DeviceType.WIFI:
def _refresh_ap(self, dev_cfg, state=None):
if dev_cfg.device_type != NetworkManager.DeviceType.WIFI: return if state is None:
state = device.get_state()
state = dev_cfg.device.get_state() if state == NetworkManager.DeviceState.UNAVAILABLE: ap_str = None else:
active_ap = device.get_active_access_point()
active_ap = dev_cfg.device.get_active_access_point() if active_ap: active_ap_dbus = dbus.SystemBus().get_object(NM_SERVICE, active_ap.get_path())
@@ -722,7 +794,7 @@ class NetworkControlBox(object): store = self.builder.get_object("liststore_wireless_network") self._updating_device = True store.clear()
aps = self._get_strongest_unique_aps(device.get_access_points())
aps = self._get_strongest_unique_aps(dev_cfg.device.get_access_points()) for ap in aps: active = active_ap and active_ap.get_path() == ap.get_path() self._add_ap(ap, active)
@@ -736,47 +808,53 @@ class NetworkControlBox(object): break self._updating_device = False
- def _refresh_slaves(self, device):
dev_type = device.get_device_type()
if dev_type in [NetworkManager.DeviceType.BOND,
NetworkManager.DeviceType.TEAM]:
slaves = ",".join(s.get_iface()
for s in device.get_slaves())
- def _refresh_slaves(self, dev_cfg):
if dev_cfg.device_type in [NetworkManager.DeviceType.BOND,
NetworkManager.DeviceType.TEAM]:
slaves = ""
if dev_cfg.device:
slaves = ",".join(s.get_iface() for s in dev_cfg.device.get_slaves()) self._set_device_info_value("wired", "slaves", slaves)
- def _refresh_parent_vlanid(self, device):
dev_type = device.get_device_type()
if dev_type == NetworkManager.DeviceType.VLAN:
self._set_device_info_value("wired", "vlanid", str(device.get_vlan_id()))
parent = nm.nm_device_setting_value(device.get_iface(), "vlan", "parent")
self._set_device_info_value("wired", "parent", parent)
- def _refresh_parent_vlanid(self, dev_cfg):
if dev_cfg.device_type == NetworkManager.DeviceType.VLAN:
if dev_cfg.device:
vlanid = dev_cfg.device.get_vlan_id()
else:
vlanid = dev_cfg.setting_value("vlan", "id")
parent = dev_cfg.setting_value("vlan", "parent")
self._set_device_info_value("wired", "vlanid", str(vlanid))
- def _refresh_speed_hwaddr(self, device, state=None):
dev_type = device.get_device_type()
- def _refresh_speed_hwaddr(self, dev_cfg, state=None):
dev_type = dev_cfg.device_type if dev_type in self.wired_ui_device_types: dt = "wired" elif dev_type == NetworkManager.DeviceType.WIFI: dt = "wireless"
speed = None
if dev_type == NetworkManager.DeviceType.ETHERNET:
speed = device.get_speed()
elif dev_type == NetworkManager.DeviceType.WIFI:
speed = device.get_bitrate() / 1000
if state is None:
state = device.get_state()
if state == NetworkManager.DeviceState.UNAVAILABLE:
# Speed
speed = None
if dev_cfg.device:
if dev_type == NetworkManager.DeviceType.ETHERNET:
speed = dev_cfg.device.get_speed()
elif dev_type == NetworkManager.DeviceType.WIFI:
speed = dev_cfg.device.get_bitrate() / 1000
if state is None:
state = dev_cfg.device.get_state()
if not dev_cfg.device or state == NetworkManager.DeviceState.UNAVAILABLE: speed_str = None elif speed: speed_str = _("%d Mb/s") % speed else: speed_str = "" self._set_device_info_value(dt, "speed", speed_str)
self._set_device_info_value(dt, "mac", device.get_hw_address())
# Hardware address
hwaddr = dev_cfg.device and dev_cfg.device.get_hw_address()
self._set_device_info_value(dt, "mac", hwaddr)
- def _refresh_device_type_page(self, device):
- def _refresh_device_type_page(self, dev_type): notebook = self.builder.get_object("notebook_types")
dev_type = device.get_device_type() if dev_type == NetworkManager.DeviceType.ETHERNET: notebook.set_current_page(0) self.builder.get_object("heading_wired_slaves").hide()
@@ -798,10 +876,10 @@ class NetworkControlBox(object): notebook.set_current_page(0) self.builder.get_object("heading_wired_slaves").hide() self.builder.get_object("label_wired_slaves").hide()
self.builder.get_object("heading_wired_vlanid").hide()
self.builder.get_object("label_wired_vlanid").hide()
self.builder.get_object("heading_wired_parent").hide()
self.builder.get_object("label_wired_parent").hide()
self.builder.get_object("heading_wired_vlanid").show()
self.builder.get_object("label_wired_vlanid").show()
self.builder.get_object("heading_wired_parent").show()
self.builder.get_object("label_wired_parent").show() elif dev_type == NetworkManager.DeviceType.WIFI: notebook.set_current_page(1) self.builder.get_object("button_wireless_options").set_sensitive(self.selected_ssid is not None)
@@ -810,29 +888,29 @@ class NetworkControlBox(object): for i in self.builder.get_object("liststore_devices"): i[DEVICES_COLUMN_TITLE] = self._dev_title(i[DEVICES_COLUMN_OBJECT])
- def _refresh_header_ui(self, device, state=None):
dev_type = device.get_device_type()
if dev_type in (NetworkManager.DeviceType.ETHERNET,
NetworkManager.DeviceType.TEAM,
NetworkManager.DeviceType.BOND,
NetworkManager.DeviceType.VLAN):
- def _refresh_header_ui(self, dev_cfg, state=None):
if dev_cfg.device_type in self.wired_ui_device_types: dev_type_str = "wired"
elif dev_type == NetworkManager.DeviceType.WIFI:
elif dev_cfg.device_type == NetworkManager.DeviceType.WIFI: dev_type_str = "wireless" if dev_type_str == "wired": # update icon according to device status img = self.builder.get_object("image_wired_device")
img.set_from_icon_name(self._dev_icon_name(device), Gtk.IconSize.DIALOG)
img.set_from_icon_name(self._dev_icon_name(dev_cfg), Gtk.IconSize.DIALOG) # TODO: is this necessary? Isn't it static from glade? self.builder.get_object("label_%s_device" % dev_type_str).set_label(
"%s (%s)" % (self._dev_type_str(device), device.get_iface()))
"%s (%s)" % (self.device_type_name.get(dev_cfg.device_type, ""), dev_cfg.get_iface()))
I think a temporary variable for the label would clarify this piece of code a bit.
if state is None:
state = device.get_state()
if not dev_cfg.device:
state = NetworkManager.DeviceState.DISCONNECTED
else:
state = dev_cfg.device.get_state()
self.builder.get_object("label_%s_status" % dev_type_str).set_label(
localized_string_of_device_state(device, state))
localized_string_of_device_state(dev_cfg.device, state)) switch = self.builder.get_object("device_%s_off_switch" % dev_type_str) if dev_type_str == "wired":
@@ -987,7 +1065,7 @@ class NetworkControlBox(object): return sec_str
@property
- def listed_devices(self):
- def dev_cfgs(self): return [row[DEVICES_COLUMN_OBJECT] for row in self.builder.get_object("liststore_devices")]
@@ -1195,11 +1273,10 @@ class NetworkSpoke(FirstbootSpokeMixIn, NormalSpoke): NormalSpoke.__init__(self, *args, **kwargs) self.network_control_box = NetworkControlBox(self.builder, spoke=self) self.network_control_box.hostname = self.data.network.hostname
self.network_control_box.client.connect("notify::%s" %
NMClient.CLIENT_STATE,
self.on_nm_state_changed)
for device in self.network_control_box.client.get_devices():
device.connect("state-changed", self.on_device_state_changed)
self.network_control_box.connect("nm-state-changed",
self.on_nm_state_changed)
self.network_control_box.connect("device-state-changed",
self.on_device_state_changed)
def apply(self): _update_network_data(self.data, self.network_control_box)
@@ -1243,8 +1320,7 @@ class NetworkSpoke(FirstbootSpokeMixIn, NormalSpoke): gtk_call_once(self._update_status) gtk_call_once(self._update_hostname)
- def on_device_state_changed(self, *args):
new_state = args[1]
- def on_device_state_changed(self, source, device, new_state, *args): if new_state in (NetworkManager.DeviceState.ACTIVATED, NetworkManager.DeviceState.DISCONNECTED, NetworkManager.DeviceState.UNAVAILABLE):
@@ -1288,9 +1364,8 @@ class NetworkStandaloneSpoke(StandaloneSpoke): parent = self.builder.get_object("AnacondaStandaloneWindow-action_area5") parent.add(self.network_control_box.vbox)
self.network_control_box.client.connect("notify::%s" %
NMClient.CLIENT_STATE,
self.on_nm_state_changed)
self.network_control_box.connect("nm-state-changed",
self.on_nm_state_changed) self._initially_available = self.completed log.debug("network standalone spoke (init): completed: %s" % self._initially_available)
@@ -1353,9 +1428,9 @@ class NetworkStandaloneSpoke(StandaloneSpoke):
def _update_network_data(data, ncb): data.network.network = []
- for dev in ncb.listed_devices:
devname = dev.get_iface()
nd = network.ksdata_from_ifcfg(devname)
- for dev_cfg in ncb.dev_cfgs:
devname = dev_cfg.get_iface()
nd = network.ksdata_from_ifcfg(devname, dev_cfg.con_uuid) if not nd: continue if devname in nm.nm_activated_devices():
@@ -1365,7 +1440,6 @@ def _update_network_data(data, ncb): network.update_hostname_data(data, hostname)
if __name__ == "__main__":
- win = Gtk.Window() win.connect("delete-event", Gtk.main_quit)
Do you still use this main block for testing?
On 12/02/2013 01:37 PM, Vratislav Podzimek wrote:
On Fri, 2013-11-29 at 13:17 +0100, Radek Vykydal wrote:
@@ -352,30 +434,28 @@ class NetworkControlBox(object): selection.select_iter(itr)
def refresh(self):
device = self.selected_device()
self.refresh_ui(device)
self.refresh_ui() # Signal handlers.
- def on_device_selection_changed(self, *args):
device = self.selected_device()
if not device:
return
- def on_nm_state_changed(self, *args):
self.emit("nm-state-changed")
log.debug("network: selected device %s" % device.get_iface())
self.refresh_ui(device)
- def on_device_selection_changed(self, *args):
self.refresh_ui()
- def on_device_state_changed(self, *args):
device = args[0]
new_state = args[1]
- def on_device_state_changed(self, device, new_state, *args):
self.emit("device-state-changed", device.get_iface(), new_state, *args) if new_state == NetworkManager.DeviceState.SECONDARIES: return self._refresh_carrier_info()
if device == self.selected_device():
self.refresh_ui(device, new_state)
dev_cfg = self.selected_dev_cfg()
if dev_cfg and dev_cfg.device == device:
self.refresh_ui(state=new_state) def on_device_config_changed(self, device, *args):
if device == self.selected_device():
self.refresh_ui(device)
dev_cfg = self.selected_dev_cfg()
if dev_cfg and dev_cfg.device == device:
self.refresh_ui() def on_wireless_ap_changed_cb(self, combobox, *args): if self._updating_device:
@@ -384,13 +464,13 @@ class NetworkControlBox(object): if not iter: return
device = self.selected_device()
device = self.selected_dev_cfg().device
The value returned from self.selected_dev_cfg() should be checked for not being None first. At least that's what is done in all the other places.
Unlike in other places the race condition the check is for shouldn't occur here, but adding the check to be on safe side won't hurt.
@@ -483,28 +555,29 @@ class NetworkControlBox(object): return
active = switch.get_active()
device = self.selected_device()
dev_cfg = self.selected_dev_cfg()
Same check here? Or is it for sure some device will be selected here? `
I'd think so, but I'll add the check.
log.info("network: device %s switched %s" %
(device.get_iface(), "on" if active else "off"))
(dev_cfg.get_iface(), "on" if active else "off"))
dev_type = device.get_device_type()
if dev_type in self.wired_ui_device_types:
if dev_cfg.device_type == NetworkManager.DeviceType.WIFI:
self.client.wireless_set_enabled(active)
else: if active:
uuid = nm.nm_device_setting_value(device.get_iface(), "connection", "uuid")
if uuid:
try:
nm.nm_activate_device_connection(device.get_iface(), uuid)
except nm.UnmanagedDeviceError as e:
log.debug("network: on_device_off_toggled: %s" % e)
else:
self.client.add_and_activate_connection(None, device, None,
None, None)
dev_name = dev_cfg.device and dev_cfg.device.get_iface()
if not dev_cfg.con_uuid:
log.debug("network: on_device_off_toggled: no connection for %s"
% dev_name)
return
try:
nm.nm_activate_device_connection(dev_name, dev_cfg.con_uuid)
except (nm.UnmanagedDeviceError, nm.UnknownDeviceError) as e:
log.debug("network: on_device_off_toggled: %s" % e) else:
device.disconnect(None, None)
elif dev_type == NetworkManager.DeviceType.WIFI:
self.client.wireless_set_enabled(active)
try:
nm.nm_disconnect_device(dev_cfg.get_iface())
except (nm.UnmanagedDeviceError, nm.DeviceNotActiveError) as e:
log.debug("network: on_device_off_toggled: %s" % e) def on_add_device_clicked(self, *args): dialog = self.builder.get_object("add_device_dialog")
@@ -532,130 +605,129 @@ class NetworkControlBox(object): self._running_nmce = None network.logIfcfgFiles("nm-c-e run")
- def selected_device(self):
- def selected_dev_cfg(self): selection = self.builder.get_object("treeview_devices").get_selection()
(model, iter) = selection.get_selected()
model, iter = selection.get_selected() if not iter: return None
return model.get(iter, DEVICES_COLUMN_OBJECT)[0]
return model[iter][DEVICES_COLUMN_OBJECT]
- def _device_is_stored(self, nm_device):
"""Check that device with Udi of nm_device is already in liststore"""
udi = nm_device.get_udi()
model = self.builder.get_object("liststore_devices")
for row in model:
if udi == row[DEVICES_COLUMN_OBJECT].get_udi():
return True
return False
- def add_dev_cfg(self, dev_cfg):
log.debug ("network: GUI, device configuration added: connection %s device %s"
% (dev_cfg.con_uuid, dev_cfg.get_iface()))
self.builder.get_object("liststore_devices").append([
self._dev_icon_name(dev_cfg),
self.device_type_sort_value.get(dev_cfg.device_type, "100"),
self._dev_title(dev_cfg),
dev_cfg
])
The "liststore_devices" store should be pulled only once from the builder, not with every single item added.
Okay, adding the item happens only a couple of times, but the dev_cfg below is more frequent, and other places are calling for it too, I'll add it.
if dev_cfg.device:
if (dev_cfg.device.get_state() == NetworkManager.DeviceState.UNAVAILABLE
and dev_cfg.device.get_device_type() == NetworkManager.DeviceType.ETHERNET
and not dev_cfg.device.get_carrier()):
# Translators: ethernet cable is unplugged
We use TRANSLATORS in other places.
I'll make it consistent.
title = ""
return title
- def dev_cfg(self, uuid=None, device=None):
model = self.builder.get_object("liststore_devices")
Should be self._liststore_devices pulled only once.
Yep.
# TODO: is this necessary? Isn't it static from glade? self.builder.get_object("label_%s_device" % dev_type_str).set_label(
"%s (%s)" % (self._dev_type_str(device), device.get_iface()))
"%s (%s)" % (self.device_type_name.get(dev_cfg.device_type, ""), dev_cfg.get_iface()))
I think a temporary variable for the label would clarify this piece of code a bit.
I agree.
if __name__ == "__main__":
win = Gtk.Window() win.connect("delete-event", Gtk.main_quit)
Do you still use this main block for testing?
Yes, this should more or less work, perhaps requires some paths tweaking. I'll look at it some time.
Related: rhbz#1036047 --- dracut/parse-kickstart | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/dracut/parse-kickstart b/dracut/parse-kickstart index c006073..9c94af2 100755 --- a/dracut/parse-kickstart +++ b/dracut/parse-kickstart @@ -397,11 +397,7 @@ def ksnet_to_ifcfg(net, filename=None): 'MASTER' : dev, 'HWADDR' : readsysfile("/sys/class/net/%s/address" % slave), } - # not using NM naming conventions, following dracut so that it does not - # override kickstart config by generating its own ifcfg files for slaves - #slave_filename = "/tmp/ifcfg/ifcfg-%s" % "_".join(slave_ifcfg['NAME'].split(" ")) - # FIXME - change in dracut? - slave_filename = "/tmp/ifcfg/ifcfg-%s" % slave + slave_filename = "/tmp/ifcfg/ifcfg-%s" % "_".join(slave_ifcfg['NAME'].split(" ")) log.info("writing ifcfg %s for slave %s of bond %s" % (slave_filename, slave, dev)) write_ifcfg(slave_filename, slave_ifcfg)
@@ -425,11 +421,7 @@ def ksnet_to_ifcfg(net, filename=None): if cfg: slave_ifcfg['TEAM_PORT_CONFIG'] = "'" + cfg + "'"
- # not using NM naming conventions, following dracut so that it does not - # override kickstart config by generating its own ifcfg files for slaves - #slave_filename = "/tmp/ifcfg/ifcfg-%s" % "_".join(slave_ifcfg['NAME'].split(" ")) - # FIXME - change in dracut? - slave_filename = "/tmp/ifcfg/ifcfg-%s" % slave + slave_filename = "/tmp/ifcfg/ifcfg-%s" % "_".join(slave_ifcfg['NAME'].split(" ")) log.info("writing ifcfg %s for slave %s of team %s" % (slave_filename, slave, dev)) write_ifcfg(slave_filename, slave_ifcfg)
Resolves: rhbz#1030870 --- pyanaconda/nm.py | 15 +++++++++++++++ pyanaconda/ui/gui/spokes/network.py | 33 +++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/nm.py b/pyanaconda/nm.py index 0d1d4a1..ceeb8fb 100644 --- a/pyanaconda/nm.py +++ b/pyanaconda/nm.py @@ -707,6 +707,21 @@ def nm_add_connection(values): connection = proxy.AddConnection('(a{sa{sv}})', settings) return connection
+def nm_delete_connection(uuid): + """Delete connection specified by uuid. + + :param uuid: uuid of connection to be deleted + :type uuid: str + :return: True if connection was deleted, False if it was not found + :rtype: bool + """ + + settings_paths = _find_settings(uuid, "connection", "uuid") + if not settings_paths: + return False + proxy = _get_proxy(object_path=settings_paths[0], interface_name="org.freedesktop.NetworkManager.Settings.Connection") + settings = proxy.Delete() + def nm_update_settings_of_device(name, new_values): """Update setting of device.
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index 0c822b7..fe89b7a 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -248,6 +248,11 @@ class DeviceConfiguration(object): iface = self.device.get_iface() else: iface = self.setting_value("connection", "interface-name") + if not iface: + hwaddr = self.setting_value("802-3-ethernet","mac-address") + if hwaddr: + hwaddr = ":".join("%02X" % b for b in hwaddr) + iface = nm.nm_hwaddr_to_device_name(hwaddr) return iface
def setting_value(self, key1, key2): @@ -312,6 +317,8 @@ class NetworkControlBox(GObject.GObject): self.builder.get_object("add_toolbutton").connect("clicked", self.on_add_device_clicked) self.builder.get_object("remove_toolbutton").set_sensitive(False) + self.builder.get_object("remove_toolbutton").connect("clicked", + self.on_remove_device_clicked)
not_supported = ["start_hotspot_button", "stop_hotspot_button", @@ -423,6 +430,10 @@ class NetworkControlBox(GObject.GObject): continue dev_cfg = DeviceConfiguration(con_uuid=uuid) if dev_cfg.device_type in self.supported_device_types: + # Configs for ethernet has been already added, + # this must be some slave. + if dev_cfg.device_type == NetworkManager.DeviceType.ETHERNET: + continue self.add_dev_cfg(dev_cfg)
# select the first device @@ -591,10 +602,19 @@ class NetworkControlBox(GObject.GObject): dev_type = model[ai][1] self.add_device(dev_type)
- def add_device(self, type): - log.info("network: adding device of type %s" % type) + def on_remove_device_clicked(self, *args): + selection = self.builder.get_object("treeview_devices").get_selection() + model, itr = selection.get_selected() + if not itr: + return None + dev_cfg = model[itr][DEVICES_COLUMN_OBJECT] + model.remove(itr) + nm.nm_delete_connection(dev_cfg.con_uuid) + + def add_device(self, ty): + log.info("network: adding device of type %s" % ty) self.kill_nmce(msg="Add device button clicked") - proc = subprocess.Popen(["nm-connection-editor", "--create", "--type=%s" % type]) + proc = subprocess.Popen(["nm-connection-editor", "--create", "--ty=%s" % ty]) self._running_nmce = proc
GLib.child_watch_add(proc.pid, self.on_nmce_adding_exited) @@ -694,7 +714,9 @@ class NetworkControlBox(GObject.GObject): # This should not concern wifi and ethernet devices, # just virtual devices e.g. vpn probably log.debug("network: GUI, device removed: %s" % (device.get_iface())) - self.dev_cfg(device=device).device = None + dev_cfg = self.dev_cfg(device=device) + if dev_cfg: + dev_cfg.device = None
def refresh_ui(self, state=None):
@@ -863,6 +885,7 @@ class NetworkControlBox(GObject.GObject): self.builder.get_object("label_wired_vlanid").hide() self.builder.get_object("heading_wired_parent").hide() self.builder.get_object("label_wired_parent").hide() + self.builder.get_object("remove_toolbutton").set_sensitive(False) elif dev_type in [NetworkManager.DeviceType.BOND, NetworkManager.DeviceType.TEAM]: notebook.set_current_page(0) @@ -872,6 +895,7 @@ class NetworkControlBox(GObject.GObject): self.builder.get_object("label_wired_vlanid").hide() self.builder.get_object("heading_wired_parent").hide() self.builder.get_object("label_wired_parent").hide() + self.builder.get_object("remove_toolbutton").set_sensitive(True) elif dev_type == NetworkManager.DeviceType.VLAN: notebook.set_current_page(0) self.builder.get_object("heading_wired_slaves").hide() @@ -880,6 +904,7 @@ class NetworkControlBox(GObject.GObject): self.builder.get_object("label_wired_vlanid").show() self.builder.get_object("heading_wired_parent").show() self.builder.get_object("label_wired_parent").show() + self.builder.get_object("remove_toolbutton").set_sensitive(True) elif dev_type == NetworkManager.DeviceType.WIFI: notebook.set_current_page(1) self.builder.get_object("button_wireless_options").set_sensitive(self.selected_ssid is not None)
Resolves: rhbz#1033073 --- pyanaconda/ui/gui/spokes/network.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index fe89b7a..7bc2af0 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -67,6 +67,7 @@ NM_SERVICE = "org.freedesktop.NetworkManager" NM_802_11_AP_FLAGS_PRIVACY = 0x1 NM_802_11_AP_SEC_NONE = 0x0 NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x200 +NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1 DBUS_PROPS_IFACE = "org.freedesktop.DBus.Properties" SECRET_AGENT_IFACE = 'org.freedesktop.NetworkManager.SecretAgent' AGENT_MANAGER_IFACE = 'org.freedesktop.NetworkManager.AgentManager' @@ -1184,15 +1185,17 @@ class SecretAgent(dbus.service.Object): in_signature='a{sa{sv}}osasb', out_signature='a{sa{sv}}', sender_keyword='sender') - def GetSecrets(self, connection_hash, connection_path, setting_name, hints, request_new, sender=None): + def GetSecrets(self, connection_hash, connection_path, setting_name, hints, flags, sender=None): if not sender: raise NotAuthorizedException("Internal error: couldn't get sender") uid = self._bus.get_unix_user(sender) if uid != 0: raise NotAuthorizedException("UID %d not authorized" % uid)
- log.debug("Secrets requested path '%s' setting '%s' hints '%s' new %d" - % (connection_path, setting_name, str(hints), request_new)) + log.debug("network: secrets requested path '%s' setting '%s' hints '%s' new %d" + % (connection_path, setting_name, str(hints), flags)) + if not (flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION): + return
content = self._get_content(setting_name, connection_hash) dialog = SecretAgentDialog(self.spoke.data, content=content)
Except for the few minor comments this all looks good to me.
anaconda-patches@lists.fedorahosted.org