doc: Migrating from cnetworkmanager to nmcli
[cnetworkmanager.git] / cnetworkmanager
blob8117f35c4db893322128ad7cbeaf702480f46ec6
1 #!/usr/bin/python
2 VERSION = "0.21.1"
4 # must be set before we ask for signals
5 from dbus.mainloop.glib import DBusGMainLoop
6 DBusGMainLoop(set_as_default=True)
8 import sys
9 import os
10 import time
11 import dbus
12 from networkmanager import NetworkManager
13 from networkmanager.monitor import Monitor
14 from networkmanager.applet import NetworkManagerSettings, SYSTEM_SERVICE, USER_SERVICE
15 from networkmanager.applet.service import NetworkManagerUserSettings
16 import networkmanager.applet.settings as settings
17 from networkmanager.util import Table
18 import networkmanager.base
20 # for calling quit
21 import gobject
22 loop = gobject.MainLoop()
23 LOOP = False
25 from optparse import OptionParser
27 op = OptionParser(version="%prog " + VERSION)
29 op.add_option("-t", "--terse",
30 action="store_true", default=False,
31 help="No table headings and padding, suitable for parsing")
33 # TODO http://docs.python.org/lib/optparse-adding-new-types.html
34 op.add_option("-w", "--wifi",
35 choices=["0","1","off","on","no","yes","false","true"],
36 metavar="BOOL",
37 help="Enable or disable wireless")
38 op.add_option("-o", "--online",
39 choices=["0","1","off","on","no","yes","false","true"],
40 metavar="BOOL",
41 help="Enable or disable network at all")
42 op.add_option("--state",
43 action="store_true", default=False,
44 help="Print the NM state")
45 op.add_option("--we", "--wireless-enabled",
46 action="store_true", default=False,
47 help="Print whether the WiFi is enabled")
48 op.add_option("--whe", "--wireless-hardware-enabled",
49 action="store_true", default=False,
50 help="Print whether the WiFi hardware is enabled")
52 op.add_option("-d", "--device-list", "--dev",
53 action="store_true", default=False,
54 help="List devices")
55 op.add_option("--device-info", "--di",
56 help="Info about device DEV (by interface or UDI(TODO))",
57 metavar="DEV")
59 op.add_option("-a", "--ap-list", "--ap", "-n", "--nets",# -n is a stopgap
60 action="store_true", default=False,
61 help="List access points")
62 op.add_option("--ap-info", "--ai",
63 help="Info about access point AP (by hw address or UDI(TODO))",
64 metavar="AP")
66 op.add_option("-u", "--usrcon",
67 action="store_true", default=False,
68 help="List user connection settings")
69 op.add_option("-s", "--syscon",
70 action="store_true", default=False,
71 help="List system connection settings")
72 op.add_option("--con-info", "--ci",
73 help="Info about connection settings ID (of the *user*/system KIND)",
74 metavar="[KIND,]ID")
76 op.add_option("-c", "--actcon",
77 action="store_true", default=False,
78 help="List active connections")
80 op.add_option("--demo",
81 action="store_true", default=False,
82 help="Run a random demonstration of the API")
83 op.add_option("--activate-connection",
84 help="activate the KIND(user/system) connection ID on device DEV using APMAC.",
85 metavar="[KIND],ID,[DEV],[APMAC]")
86 op.add_option("-m", "--monitor",
87 action="store_true", default=False,
88 help="loop to show dbus signals")
90 op.add_option("-C", "--connect",
91 help="Connect to a wireless network SSID (creating the configuration using the key options below)",
92 metavar="SSID")
93 op.add_option("--unprotected",
94 action="store_true", default=False,
95 help="network does not require a key")
96 op.add_option("--wep-hex",
97 metavar="KEY",
98 help="use this WEP key of 26 hex digits")
99 op.add_option("--wep-pass",
100 metavar="KEY",
101 help="use this WEP passphrase")
102 op.add_option("--wpa-psk-hex",
103 metavar="KEY",
104 help="use this WPA key of 64 hex digits")
105 op.add_option("--wpa-pass",
106 metavar="KEY",
107 help="use this WPA passphrase")
109 op.add_option("--session",
110 action="store_true", default=False,
111 help="Connect to the session bus for testing")
113 (options, args) = op.parse_args()
115 Table.terse = options.terse
117 # TODO: CNM_OPTS, like nmcli
118 if options.session or os.getenv("CNETWORKMANAGER_TEST") != None:
119 networkmanager.base.NM_BUS = dbus.SessionBus()
121 nm = NetworkManager()
123 true_choices = ["1", "on", "yes", "true"]
124 if options.wifi != None:
125 nm["WirelessEnabled"] = options.wifi in true_choices
126 if options.we:
127 print nm["WirelessEnabled"]
128 if options.online != None:
129 try:
130 nm.Sleep(not options.online in true_choices)
131 except dbus.exceptions.DBusException, e:
132 if e.get_dbus_name() != "org.freedesktop.NetworkManager.AlreadyAsleepOrAwake":
133 raise
135 if options.state:
136 print nm["State"]
137 if options.whe:
138 print nm["WirelessHardwareEnabled"]
139 # style option: pretend that properties are methods (er, python properties)
140 # nm["WirelessEnabled"] -> nm.WirelessEnabled() (er, nm.WirelessEnabled )
142 if options.device_list:
143 devs = nm.GetDevices()
144 t = Table("Interface", "Type", "State")
145 for dev in devs:
146 t.row(dev["Interface"], dev["DeviceType"], dev["State"])
147 print t
149 # --device-info, TODO clean up
150 def get_device(dev_spec, hint):
151 candidates = []
152 # print "Hint:", hint
153 devs = NetworkManager().GetDevices()
154 for dev in devs:
155 # print dev
156 if dev._settings_type() == hint:
157 candidates.append(dev)
158 # print "Candidates:", candidates
159 if len(candidates) == 1:
160 return candidates[0]
161 for dev in devs:
162 if dev["Interface"] == dev_spec:
163 return dev
164 print "Device '%s' not found" % dev_spec
165 return None
167 if options.device_info != None:
168 d = get_device(options.device_info, "no hint")
169 if d == None:
170 print "not found"
171 else:
172 props = ["Udi", "Interface", "Driver", "Capabilities",
173 # "Ip4Address", # bogus, remembers last addr even after disused
174 "State",
175 # "Ip4Config", "Dhcp4Config", # only __repr__
176 "Managed", "DeviceType"]
177 if d._settings_type() == "802-11-wireless":
178 props.extend(["Mode", "WirelessCapabilities"])
179 elif d._settings_type() == "802-3-ethernet":
180 props.extend(["Carrier"])
182 print Table.from_items(d, *props)
184 if options.ap_list:
185 devs = nm.GetDevices()
186 # nm.get_wifi_devices()
187 # nm.get_devices_by_type(Device.Type.WIRELESS)
188 for dev in filter(lambda d: d._settings_type() == "802-11-wireless", devs):
189 aap = dev["ActiveAccessPoint"]
190 t = Table("Active", "HwAddress", "Ssid")
191 for ap in dev.GetAccessPoints():
192 active = "*" if ap.object_path == aap.object_path else ""
193 t.row(active, ap["HwAddress"], ap["Ssid"])
194 print t
196 if options.ap_info != None:
197 devs = nm.GetDevices()
198 for dev in filter(lambda d: d._settings_type() == "802-11-wireless", devs):
199 aap = dev["ActiveAccessPoint"]
200 for ap in dev.GetAccessPoints():
201 if ap["HwAddress"] == options.ap_info:
202 t = Table.from_items(ap, "Flags", "WpaFlags", "RsnFlags",
203 "Ssid", "Frequency", "HwAddress",
204 "Mode", "MaxBitrate", "Strength")
205 t.row("Active", ap.object_path == aap.object_path)
206 print t
208 #def is_opath(x):
209 # return is_instance(x, str) and x[0] == "/"
211 def get_service_name(svc):
212 if svc == "" or svc == "user":
213 svc = USER_SERVICE
214 elif svc == "system":
215 svc = SYSTEM_SERVICE
216 return svc
218 # move this to networkmanagersettings
219 def get_connection(svc, conn_spec):
220 # if is_opath(conn_spec):
221 # return conn_spec
222 applet = NetworkManagerSettings(get_service_name(svc))
223 for conn in applet.ListConnections():
224 cs = conn.GetSettings()
225 if cs["connection"]["id"] == conn_spec:
226 return conn
227 print "Connection '%s' not found" % conn_spec
228 return None
230 def get_connection_devtype(conn):
231 cs = conn.GetSettings()
232 return cs["connection"]["type"]
234 def list_connections(svc):
235 acs = nm["ActiveConnections"]
236 acos = map(lambda a: a["Connection"].object_path, acs)
238 try:
239 applet = NetworkManagerSettings(svc)
240 except dbus.exceptions.DBusException, e:
241 print e
242 return
243 t = Table("Active", "Name", "Type")
244 for conn in applet.ListConnections():
245 cs = conn.GetSettings()
246 active = "*" if conn.object_path in acos else ""
247 t.row(active, cs["connection"]["id"], cs["connection"]["type"])
248 print t
250 if options.usrcon:
251 list_connections(USER_SERVICE)
252 if options.syscon:
253 list_connections(SYSTEM_SERVICE)
255 if options.con_info != None:
256 (svc, con) = ("", options.con_info)
257 if "," in con:
258 (svc, con) = con.split(",")
260 c = get_connection(svc, con)
261 cs = c.GetSettings()
262 print Table.from_nested_dict(cs)
263 type = cs["connection"]["type"]
264 secu = cs[type]["security"]
265 cse = c.GetSecrets(secu, [], False)
266 print Table.from_nested_dict(cse)
268 # this shows we do need to add __str__ to the objects
269 if options.actcon:
270 acs = nm["ActiveConnections"]
271 t = Table("State", "Name", "AP", "Devices", "Default route")
272 for ac in acs:
273 cid = ac["Connection"].GetSettings()["connection"]["id"]
274 try:
275 apmac = ac["SpecificObject"]["HwAddress"]
276 except: # no AP for wired. TODO figure out "/" object
277 apmac = ""
278 devs = ", ".join(map(lambda d: d["Interface"], ac["Devices"]))
279 hdr = "*" if ac["Default"] else ""
280 t.row(ac["State"], cid, apmac, devs, hdr)
281 print t
283 if options.monitor:
284 m = Monitor()
285 LOOP = True
287 def print_state_changed(*args):
288 print time.strftime("(%X)"),
289 print "State:", ", ".join(map(str,args))
291 if options.connect != None:
292 ssid = options.connect
293 try:
294 us = NetworkManagerUserSettings([]) # request_name may fail
295 except dbus.exceptions.NameExistsException, e:
296 print "Another applet is running:", e
297 sys.exit(1)
299 c = None
300 if options.unprotected:
301 c = settings.WiFi(ssid)
302 if options.wep_hex != None:
303 c = settings.Wep(ssid, "", options.wep_hex)
304 if options.wep_pass != None:
305 c = settings.Wep(ssid, options.wep_pass)
306 if options.wpa_psk_hex != None:
307 c = settings.WpaPsk(ssid, "", options.wpa_psk_hex)
308 if options.wpa_pass != None:
309 c = settings.WpaPsk(ssid, options.wpa_pass)
310 if c == None:
311 print "Error, connection settings not specified"
312 sys.exit(1)
314 svc = USER_SERVICE
315 svc_conn = us.addCon(c.conmap)
316 hint = svc_conn.settings["connection"]["type"]
317 dev = get_device("", hint)
318 appath = "/"
319 nm._connect_to_signal("StateChanged", print_state_changed)
320 # must be async because ourselves are providing the service
321 dummy_handler = lambda *args: None
322 nm.ActivateConnection(svc, svc_conn, dev, appath,
323 reply_handler=dummy_handler,
324 error_handler=dummy_handler)
325 LOOP = True
327 if options.activate_connection != None:
328 (svc, conpath, devpath, appath) = options.activate_connection.split(',')
329 svc = get_service_name(svc)
330 conn = get_connection(svc, conpath)
331 hint = get_connection_devtype(conn)
332 dev = get_device(devpath, hint)
333 if appath == "":
334 appath = "/"
335 nm._connect_to_signal("StateChanged", print_state_changed)
336 # TODO make it accept both objects and opaths
337 nm.ActivateConnection(svc, conn, dev, appath)
338 # TODO (optionally) block only until a stable state is reached
339 LOOP = True
342 ######## demo ##########
344 if options.demo:
345 from dbusclient import DBusMio
346 mio = DBusMio(networkmanager.base.Bus(), "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
347 i = mio.Introspect()
348 d = mio.GetDevices()
350 nm = NetworkManager()
352 # TODO: generic signal (adapt cnm monitor), print name and args
354 nm["WirelessEnabled"] = "yes"
356 devs = nm.GetDevices()
358 for d in devs:
359 print "\n DEVICE"
360 # TODO: find API for any object
361 d._connect_to_signal("StateChanged", print_state_changed)
363 LOOP = True
364 ######## demo end ##########
366 # TODO wrap this
367 if LOOP:
368 try:
369 print "Entering mainloop"
370 loop.run()
371 except KeyboardInterrupt:
372 print "Loop exited"