44from time import monotonic , sleep
55
66import gi
7- gi .require_version ('NM' , '1.0' )
7+
8+ gi .require_version ("NM" , "1.0" )
89from gi .repository import GLib , NM
910
1011# ensure all wrapper objects for Settings types are created
1112for _name in dir (NM ):
12- if _name .startswith (' Setting' ):
13+ if _name .startswith (" Setting" ):
1314 getattr (NM , _name )
1415
16+
1517class Future :
1618 def __init__ (self ):
1719 self ._event = threading .Event ()
@@ -38,6 +40,7 @@ def run(self):
3840 GLib .MainLoop (None ).run ()
3941 except Exception :
4042 import traceback
43+
4144 traceback .print_exc (file = sys .stderr )
4245 sys .exit (1 )
4346
@@ -53,13 +56,11 @@ def cb(data):
5356 done .wait ()
5457 return result [0 ]
5558
59+
5660def address_from_str (s ):
57- assert '/' in s , "IP address must be in the form address/prefix"
58- (addr , prefix ) = s .split ('/' , 1 )
59- return NM .IPAddress .new (
60- socket .AF_INET6 if ':' in addr else socket .AF_INET ,
61- addr ,
62- int (prefix ))
61+ assert "/" in s , "IP address must be in the form address/prefix"
62+ (addr , prefix ) = s .split ("/" , 1 )
63+ return NM .IPAddress .new (socket .AF_INET6 if ":" in addr else socket .AF_INET , addr , int (prefix ))
6364
6465
6566def connection_from_dict (data ):
@@ -71,13 +72,13 @@ def connection_from_dict(data):
7172 if not v :
7273 continue
7374
74- if k == ' mac-address' :
75- v = ':' .join (f"{ x :02X} " for x in v )
76- elif k == ' ssid' :
75+ if k == " mac-address" :
76+ v = ":" .join (f"{ x :02X} " for x in v )
77+ elif k == " ssid" :
7778 if isinstance (v , str ):
7879 v = v .encode ()
7980 v = GLib .Bytes (v )
80- elif k == ' addresses' :
81+ elif k == " addresses" :
8182 # setting addresses via the property doesn't seem to work
8283 for x in v :
8384 setting .add_address (address_from_str (x ))
@@ -92,13 +93,15 @@ def connection_from_dict(data):
9293 con .add_setting (setting )
9394 return con
9495
96+
9597class NMDev :
9698 def __init__ (self , interface ):
9799 self ._interface = interface
98- self ._nm_dev = nm .get_device_by_iface (interface ) # pylint: disable=possibly-used-before-assignment
100+ self ._nm_dev = nm .get_device_by_iface (interface ) # pylint: disable=possibly-used-before-assignment
99101
100102 def _delete_connection (self , con ):
101103 future = Future ()
104+
102105 def cb (con , res , error ):
103106 assert error is None
104107 try :
@@ -114,7 +117,7 @@ def cb(con, res, error):
114117 )
115118
116119 def get_settings (self ):
117- lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
120+ lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
118121 if lg_con :
119122 return dict (lg_con .to_dbus (NM .ConnectionSerializationFlags .ALL ))
120123
@@ -125,26 +128,29 @@ def get_active_settings(self):
125128 return dict (con .to_dbus (NM .ConnectionSerializationFlags .ALL ))
126129
127130 def configure (self , data ):
128- lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
131+ lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
129132 if lg_con :
130133 self ._delete_connection (lg_con )
131- data ['connection' ].update ({
132- 'id' : f"labgrid-{ self ._interface } " ,
133- 'autoconnect' : False ,
134- 'interface-name' : self ._interface ,
135- })
134+ data ["connection" ].update (
135+ {
136+ "id" : f"labgrid-{ self ._interface } " ,
137+ "autoconnect" : False ,
138+ "interface-name" : self ._interface ,
139+ }
140+ )
136141 con = connection_from_dict (data )
137142
138143 future = Future ()
144+
139145 def cb (dev , res , error ):
140146 assert error is None
141147 try :
142- res = nm .add_and_activate_connection_finish (res ) # pylint: disable=possibly-used-before-assignment
148+ res = nm .add_and_activate_connection_finish (res ) # pylint: disable=possibly-used-before-assignment
143149 future .set (res )
144150 except Exception as e :
145151 future .set (e )
146152
147- nm .add_and_activate_connection_async ( # pylint: disable=possibly-used-before-assignment
153+ nm .add_and_activate_connection_async ( # pylint: disable=possibly-used-before-assignment
148154 con ,
149155 self ._nm_dev ,
150156 None , # specific_object
@@ -172,7 +178,7 @@ def wait_state(self, expected, timeout):
172178 )
173179
174180 def disable (self ):
175- lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
181+ lg_con = nm .get_connection_by_id (f"labgrid-{ self ._interface } " ) # pylint: disable=possibly-used-before-assignment
176182 if lg_con :
177183 self ._delete_connection (lg_con )
178184
@@ -182,58 +188,59 @@ def _flags_to_str(self, flags):
182188 def _accesspoint_to_dict (self , ap ):
183189 res = {}
184190
185- res [' flags' ] = self ._flags_to_str (ap .get_flags ())
186- res [' wpa-flags' ] = self ._flags_to_str (ap .get_wpa_flags ())
187- res [' rsn-flags' ] = self ._flags_to_str (ap .get_rsn_flags ())
188- res [' bssid' ] = ap .get_bssid ()
189- res [' ssid' ] = ap .get_ssid ().get_data ().decode (errors = ' surrogateescape' )
190- res [' frequency' ] = ap .get_frequency ()
191- res [' mode' ] = self ._flags_to_str (ap .get_mode ())
192- res [' max-bitrate' ] = ap .get_max_bitrate ()
193- res [' strength' ] = ap .get_strength ()
191+ res [" flags" ] = self ._flags_to_str (ap .get_flags ())
192+ res [" wpa-flags" ] = self ._flags_to_str (ap .get_wpa_flags ())
193+ res [" rsn-flags" ] = self ._flags_to_str (ap .get_rsn_flags ())
194+ res [" bssid" ] = ap .get_bssid ()
195+ res [" ssid" ] = ap .get_ssid ().get_data ().decode (errors = " surrogateescape" )
196+ res [" frequency" ] = ap .get_frequency ()
197+ res [" mode" ] = self ._flags_to_str (ap .get_mode ())
198+ res [" max-bitrate" ] = ap .get_max_bitrate ()
199+ res [" strength" ] = ap .get_strength ()
194200
195201 return res
196202
197203 def get_state (self ):
198204 state = {}
199205
200206 device = {}
201- device [' capabilities' ] = self ._flags_to_str (self ._nm_dev .get_capabilities ())
202- device [' device-type' ] = self ._flags_to_str (self ._nm_dev .get_device_type ())
203- device [' state' ] = self ._flags_to_str (self ._nm_dev .get_state ())
204- device [' state-reason' ] = self ._flags_to_str (self ._nm_dev .get_state_reason ())
205- device [' hw-address' ] = self ._nm_dev .get_hw_address ()
206- device [' driver' ] = self ._nm_dev .get_driver ()
207- device [' udi' ] = self ._nm_dev .get_udi ()
208- device [' mtu' ] = self ._nm_dev .get_mtu ()
209- device [' vendor' ] = self ._nm_dev .get_vendor ()
210- device [' product' ] = self ._nm_dev .get_product ()
211- state [' device' ] = device
207+ device [" capabilities" ] = self ._flags_to_str (self ._nm_dev .get_capabilities ())
208+ device [" device-type" ] = self ._flags_to_str (self ._nm_dev .get_device_type ())
209+ device [" state" ] = self ._flags_to_str (self ._nm_dev .get_state ())
210+ device [" state-reason" ] = self ._flags_to_str (self ._nm_dev .get_state_reason ())
211+ device [" hw-address" ] = self ._nm_dev .get_hw_address ()
212+ device [" driver" ] = self ._nm_dev .get_driver ()
213+ device [" udi" ] = self ._nm_dev .get_udi ()
214+ device [" mtu" ] = self ._nm_dev .get_mtu ()
215+ device [" vendor" ] = self ._nm_dev .get_vendor ()
216+ device [" product" ] = self ._nm_dev .get_product ()
217+ state [" device" ] = device
212218
213219 for name , ip_cfg in (
214- ( ' ip4-config' , self ._nm_dev .get_ip4_config ()),
215- ( ' ip6-config' , self ._nm_dev .get_ip6_config ()),
216- ):
220+ ( " ip4-config" , self ._nm_dev .get_ip4_config ()),
221+ ( " ip6-config" , self ._nm_dev .get_ip6_config ()),
222+ ):
217223 if ip_cfg is None :
218224 continue
219225 cfg = {}
220- cfg [' addresses' ] = []
226+ cfg [" addresses" ] = []
221227 for address in ip_cfg .get_addresses ():
222- cfg [' addresses' ].append (f"{ address .get_address ()} /{ address .get_prefix ()} " )
223- cfg [' gateway' ] = ip_cfg .get_gateway ()
228+ cfg [" addresses" ].append (f"{ address .get_address ()} /{ address .get_prefix ()} " )
229+ cfg [" gateway" ] = ip_cfg .get_gateway ()
224230 state [name ] = cfg
225231
226232 try :
227233 ap = self ._nm_dev .get_active_access_point ()
228234 except AttributeError :
229235 ap = None
230236 if ap :
231- state [' active-access-point' ] = self ._accesspoint_to_dict (ap )
237+ state [" active-access-point" ] = self ._accesspoint_to_dict (ap )
232238
233239 return state
234240
235241 def request_scan (self ):
236242 future = Future ()
243+
237244 def cb (dev , res , error ):
238245 assert error is None
239246 try :
@@ -251,7 +258,7 @@ def cb(dev, res, error):
251258 future .wait () # we must wait, but don't need to return it here
252259
253260 def get_access_points (self , scan ):
254- if scan is None : # automatically scan if needed
261+ if scan is None : # automatically scan if needed
255262 age = NM .utils_get_timestamp_msec () - self ._nm_dev .get_last_scan ()
256263 scan = bool (age > 30_000 )
257264
@@ -275,80 +282,93 @@ def get_dhcpd_leases(self):
275282 with open (f"/var/lib/NetworkManager/dnsmasq-{ self ._interface } .leases" ) as f :
276283 for line in f :
277284 line = line .strip ().split ()
278- if line [3 ] == '*' :
285+ if line [3 ] == "*" :
279286 line [3 ] = None
280- if line [4 ] == '*' :
287+ if line [4 ] == "*" :
281288 line [4 ] = None
282- leases .append ({
283- 'expire' : int (line [0 ]),
284- 'mac' : line [1 ],
285- 'ip' : line [2 ],
286- 'hostname' : line [3 ],
287- 'id' : line [4 ],
288- })
289+ leases .append (
290+ {
291+ "expire" : int (line [0 ]),
292+ "mac" : line [1 ],
293+ "ip" : line [2 ],
294+ "hostname" : line [3 ],
295+ "id" : line [4 ],
296+ }
297+ )
289298 return leases
290299
291- if getattr (NM .Client , '__gtype__' , None ):
300+
301+ if getattr (NM .Client , "__gtype__" , None ):
292302 # hide this from sphinx autodoc
293303 bl = BackgroundLoop ()
294304 bl .start ()
295305 nm = bl .block_on (NM .Client .new , None )
296306
297307_nmdevs = {}
298308
309+
299310def _get_nmdev (interface ):
300311 if interface not in _nmdevs :
301312 _nmdevs [interface ] = NMDev (interface )
302313 return _nmdevs [interface ]
303314
315+
304316def handle_configure (interface , settings ):
305317 nmdev = _get_nmdev (interface )
306318 return nmdev .configure (settings )
307319
320+
308321def handle_wait_state (interface , expected , timeout = 60 ):
309322 nmdev = _get_nmdev (interface )
310323 return nmdev .wait_state (expected , timeout )
311324
325+
312326def handle_disable (interface ):
313327 nmdev = _get_nmdev (interface )
314328 return nmdev .disable ()
315329
330+
316331def handle_get_active_settings (interface ):
317332 nmdev = _get_nmdev (interface )
318333 return nmdev .get_active_settings ()
319334
335+
320336def handle_get_settings (interface ):
321337 nmdev = _get_nmdev (interface )
322338 return nmdev .get_settings ()
323339
340+
324341def handle_get_state (interface ):
325342 nmdev = _get_nmdev (interface )
326343 return nmdev .get_state ()
327344
345+
328346def handle_get_dhcpd_leases (interface ):
329347 nmdev = _get_nmdev (interface )
330348 return nmdev .get_dhcpd_leases ()
331349
350+
332351def handle_request_scan (interface ):
333352 nmdev = _get_nmdev (interface )
334353 return nmdev .request_scan ()
335354
355+
336356def handle_get_access_points (interface , scan = None ):
337357 nmdev = _get_nmdev (interface )
338358 return nmdev .get_access_points (scan )
339359
340360
341361methods = {
342362 # basic
343- ' configure' : handle_configure ,
344- ' wait_state' : handle_wait_state ,
345- ' disable' : handle_disable ,
346- ' get_active_settings' : handle_get_active_settings ,
347- ' get_settings' : handle_get_settings ,
348- ' get_state' : handle_get_state ,
363+ " configure" : handle_configure ,
364+ " wait_state" : handle_wait_state ,
365+ " disable" : handle_disable ,
366+ " get_active_settings" : handle_get_active_settings ,
367+ " get_settings" : handle_get_settings ,
368+ " get_state" : handle_get_state ,
349369 # dhcpd
350- ' get_dhcpd_leases' : handle_get_dhcpd_leases ,
370+ " get_dhcpd_leases" : handle_get_dhcpd_leases ,
351371 # wireless
352- ' request_scan' : handle_request_scan ,
353- ' get_access_points' : handle_get_access_points ,
372+ " request_scan" : handle_request_scan ,
373+ " get_access_points" : handle_get_access_points ,
354374}
0 commit comments