seveas / python-networkmanager

Easy communication with NetworkManager
http://packages.python.org/python-networkmanager/
Other
163 stars 90 forks source link

NetworkManager >= 1.34 causes GetConnectionByUuid to fail with KeyError: 'dns' #93

Closed michael-schaller closed 1 year ago

michael-schaller commented 2 years ago

NetworkManager >= 1.34 only provides the dns field as part of the org.freedesktop.NetworkManager.Settings.Connection.GetSettings reply if a custom DNS server is set in the connection config. This in turn causes python-networkmanager to fail as it always expects the dns field:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 9, in GetConnectionByUuid
  File "/usr/lib/python3/dist-packages/NetworkManager.py", line 583, in to_python
    val = fixups.base_to_python(val)
  File "/usr/lib/python3/dist-packages/NetworkManager.py", line 653, in base_to_python
    return globals()[classname](val)
  File "/usr/lib/python3/dist-packages/NetworkManager.py", line 309, in __init__
    self.uuid = self.GetSettings()['connection']['uuid']
  File "<string>", line 8, in GetSettings
  File "/usr/lib/python3/dist-packages/NetworkManager.py", line 624, in to_python
    val['ipv4']['dns'] = [fixups.addr_to_python(addr,socket.AF_INET) for addr in val['ipv4']['dns']]
KeyError: 'dns'

This can be reproduced easily by adding/removing a custom DNS server to a connection config and then using dbus-send.

This in turn means that this code part shouldn't assume that the dns field is available:
https://github.com/seveas/python-networkmanager/blob/main/NetworkManager.py#L616-L623

The code part probably also shouldn't assume that the other fields are available either. ;-)

michael-schaller commented 2 years ago

Reproduction instructions in case your Linux install doesn't have Network Manager >= 1.34 yet: 1) Download the daily Ubuntu Jammy (22.04) live image from https://cdimage.ubuntu.com/daily-live/current/jammy-desktop-amd64.iso. 2) Boot live image in a VM or on real hardware (the live image can be written as it to a flash drive with dd). 3) Choose Try Ubuntu. 4) Make sure you have a network connection. The Network Manager applet is in the upper right corner. 5) Open Terminal with Ctrl+Alt+T. 6) Edit /etc/apt/sources.list as root and add universe after main restricted to all the lines that with ubuntu.com (the last 3 lines). This makes python-networkmanager available to the package manager. 7) Update/download the package index with sudo apt update. 8) Install python-networkmanager with sudo apt python3-networkmanager. 9) Get active connection UUID with nmcli connection show --active. In my case the UUID was 4f3ac129-de0c-43be-9926-0958ac0517a7. 10) Run python3 and repeat the following interactive Python session:

$ python3
Python 3.9.9 (main, Jan 12 2022, 16:10:51) 
[GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from dbus.mainloop.glib import DBusGMainLoop
>>> DBusGMainLoop(set_as_default=True)
<dbus.mainloop.NativeMainLoop object at 0x7fc48ea91f60>
>>> import NetworkManager
>>> NetworkManager.Settings.GetConnectionByUuid("4f3ac129-de0c-43be-9926-0958ac0517a7")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 9, in GetConnectionByUuid
  File "/usr/lib/python3/dist-packages/NetworkManager.py", line 583, in to_python
    val = fixups.base_to_python(val)
  File "/usr/lib/python3/dist-packages/NetworkManager.py", line 653, in base_to_python
    return globals()[classname](val)
  File "/usr/lib/python3/dist-packages/NetworkManager.py", line 309, in __init__
    self.uuid = self.GetSettings()['connection']['uuid']
  File "<string>", line 8, in GetSettings
  File "/usr/lib/python3/dist-packages/NetworkManager.py", line 624, in to_python
    val['ipv4']['dns'] = [fixups.addr_to_python(addr,socket.AF_INET) for addr in val['ipv4']['dns']]
KeyError: 'dns'
michael-schaller commented 2 years ago

The following Network Manager commit is the culprit:
https://github.com/NetworkManager/NetworkManager/commit/d652e0f53487cf3f5b1f64038d9ff4a2f5947213

Quote from the commit description:
Now, empty dns properties are omitted from D-Bus.

michael-schaller commented 2 years ago

The pending pull request #94 fixes this issue. It would also be great to have a new python-networkmanager release once this bug is fixed so that Linux distributions can update their packages. The upcoming Ubuntu 22.04 will definitely be affected.

seveas commented 1 year ago

Closing all PR's and issues prior to archiving this repository.