Skip to content

Commit 7475378

Browse files
committed
Merge branch 'settings-helper'
Thank you @bernhardkaindl
2 parents 6815cea + 34e5013 commit 7475378

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+4635
-1770
lines changed

examples/async/list-connections-async.py

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
# | ipv6: method: disabled
2020
import asyncio
2121
import sdbus
22+
import pprint
2223
from sdbus_async.networkmanager import (
2324
NetworkManagerSettings,
2425
NetworkConnectionSettings,
@@ -29,33 +30,30 @@
2930
async def list_connection_profiles_async() -> None:
3031
networkmanager_settings = NetworkManagerSettings()
3132
connections_paths: List[str] = await networkmanager_settings.connections
32-
for connection_path in connections_paths:
33-
connection_settings = NetworkConnectionSettings(connection_path)
34-
settings = await connection_settings.get_settings()
35-
connection = settings["connection"]
36-
37-
# Skip connection profiles for bridges and wireless networks
38-
if connection["type"][1] in ("bridge", "802-11-wireless"):
39-
continue
40-
41-
print("-------------------------------------------------------------")
42-
print("name:", connection["id"][1])
43-
print("uuid:", connection["uuid"][1])
44-
print("type:", connection["type"][1])
45-
if "interface-name" in connection:
46-
print(" interface-name:", connection["interface-name"][1])
47-
48-
if "ipv4" in settings:
49-
ipv4 = settings["ipv4"]
50-
print("ipv4: method:", ipv4["method"][1])
51-
if "address-data" in ipv4:
52-
for a in ipv4["address-data"][1]:
53-
print(f' ipaddr: {a["address"][1]}/{a["prefix"][1]}')
54-
if "route-metric" in ipv4:
55-
print(f' route-metric: {ipv4["route-metric"][1]}')
56-
57-
if "ipv6" in settings:
58-
print("ipv6: method:", settings["ipv6"]["method"][1])
33+
for dbus_connection_path in connections_paths:
34+
await print_connection_profile(dbus_connection_path)
35+
36+
37+
async def print_connection_profile(connection_path: str) -> None:
38+
connectionsettings_service = NetworkConnectionSettings(connection_path)
39+
profile = await connectionsettings_service.connection_profile()
40+
connection = profile.connection
41+
print("-------------------------------------------------------------")
42+
print("name:", connection.connection_id)
43+
print("uuid:", connection.uuid)
44+
print("type:", connection.connection_type)
45+
if connection.interface_name:
46+
print(" interface-name:", connection.interface_name)
47+
if profile.ipv4:
48+
print("ipv4: method:", profile.ipv4.method)
49+
if profile.ipv4.address_data:
50+
for address in profile.ipv4.address_data:
51+
print(f' ipaddr: {address.address}/{address.prefix}')
52+
if profile.ipv4.route_metric:
53+
print(f' route-metric: {profile.ipv4.route_metric}')
54+
if profile.ipv6:
55+
print("ipv6: method:", profile.ipv6.method)
56+
pprint.pprint(profile.to_settings_dict(), sort_dicts=False)
5957

6058

6159
if __name__ == "__main__":

examples/async/update-connection-async.py

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,21 @@
33
#
44
# Update a property of a connection profile, looked up by connection id
55
#
6+
# This version uses connection_manager.connection_profile().to_settings_dict()
7+
# to retrieve the connection profile from NetworkManager as a settings dict.
8+
#
9+
# It then updates it dynamically using the given arguments:
10+
# The default is to set ipv4.dns-search to ["domain1.com", "domain2.com"].
11+
#
12+
# The dynamically updated dict is then used to update connection profile of NM.
13+
#
614
# The IPv4 settings of connections profiles are documented here:
715
# https://networkmanager.dev/docs/api/latest/settings-ipv4.html
816
#
917
import asyncio
1018
import sdbus
1119
from functools import partial
20+
from sdbus_async.networkmanager import ConnectionProfile
1221
from sdbus_async.networkmanager import NetworkManagerSettings
1322
from sdbus_async.networkmanager import NetworkConnectionSettings
1423
from pprint import pprint
@@ -17,24 +26,34 @@
1726

1827
async def update_connection_async(args: Dict[str, Any]) -> None:
1928
"""Update the settings for [key][entry] of the 1st matching connection"""
29+
30+
# Get the connection path of the connection(s) with the recieved id
2031
fn = NetworkManagerSettings().get_connections_by_id(args["connection_id"])
2132
connection_paths = await fn
22-
settings_domain, setting = args["connection_setting"]
23-
if connection_paths:
24-
connection_settings = NetworkConnectionSettings(connection_paths[0])
25-
properties = await connection_settings.get_settings()
26-
# For compatibility with old tools, NM adds and prefers them, delete:
27-
properties["ipv4"].pop("addresses") # -> Use ["ipv4"]["address-data"]
28-
properties["ipv4"].pop("routes") # ----> Use ["ipv4"]["route-data"]
33+
if not connection_paths:
34+
print(f"No connection {id}, create with add-wifi-psk-connection-async")
35+
return
36+
37+
# Get the profile settings of the first connecttion with given id
38+
connection_manager = NetworkConnectionSettings(connection_paths[0])
39+
existing_connection_profile = await connection_manager.connection_profile()
40+
settings = existing_connection_profile.to_settings_dict()
41+
42+
# Update the given setting's property using the given value
43+
setting, property = args["connection_setting"]
44+
settings[setting][property] = args["value"]
45+
46+
# Get a new ConnectionProfile with the change incorporated
47+
new_connection_profile = ConnectionProfile.from_settings_dict(settings)
48+
49+
# Update the new ConnectionProfile in NetworkManager's configuration
50+
await connection_manager.update(new_connection_profile.to_dbus())
2951

30-
# Update the setting's value in the given configuration group:
31-
properties[settings_domain][setting] = args["value"]
32-
await connection_settings.update(properties)
52+
print(f'Updated {new_connection_profile.connection.uuid}.{setting}:')
53+
partial(pprint, sort_dicts=False)(settings)
3354

34-
print(f'Updated {properties["connection"]["uuid"]}.{settings_domain}:')
35-
partial(pprint, sort_dicts=False)(properties[settings_domain])
36-
else:
37-
print(f"No connection matching {id}")
55+
# Restore the previous connection profile:
56+
await connection_manager.update(existing_connection_profile.to_dbus())
3857

3958

4059
if __name__ == "__main__":
@@ -43,7 +62,6 @@ async def update_connection_async(args: Dict[str, Any]) -> None:
4362
# Set MyConnectionExample.ipv4.dns-search to "domain1.com,domain2.com":
4463
"connection_id": "MyConnectionExample",
4564
"connection_setting": ("ipv4", "dns-search"),
46-
# "as" is the so-called DBus signature, it means "array of strings":
47-
"value": ("as", ["domain1.com", "domain2.com"]),
65+
"value": ["domain1.com", "domain2.com"],
4866
}
4967
asyncio.run(update_connection_async(args))

pytest.ini

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[pytest]
2+
#
3+
# Newer version of pytest-asyncio issue a DeprecationWarning unless
4+
# asyncio_mode is specified. This is because it is planned to change
5+
# the legacy default of automatically decorating async fixtures from
6+
# automatc to strict (only all functions and fixtures have to be marked).
7+
#
8+
# But only very recent versions of pytest-asyncio versions support
9+
# the asyncio_mode configuration setting and then issue a config warning,
10+
# which can't be filtered.
11+
#
12+
# Thus, filter the Deprecationwarning of pytest-asyncio for some time
13+
# until all users can be assumed to use the latest pytest-asyncio.
14+
#
15+
filterwarnings =
16+
ignore:The 'asyncio_mode' default value will change to 'strict' in future, please explicitly use 'asyncio_mode=strict' or 'asyncio_mode=auto' in pytest configuration file.:DeprecationWarning
17+

0 commit comments

Comments
 (0)