~ubuntu-branches/ubuntu/trusty/plainbox-provider-checkbox/trusty

« back to all changes in this revision

Viewing changes to bin/network_device_info

  • Committer: Package Import Robot
  • Author(s): Zygmunt Krynicki
  • Date: 2014-04-07 19:00:31 UTC
  • mfrom: (3.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140407190031-rf836grml6oilfyt
Tags: 0.4-1
* New upstream release. List of bugfixes:
  https://launchpad.net/plainbox-provider-checkbox/14.04/0.4
* debian/watch: look for new releases on launchpad
* debian/rules: stop using pybuild and use manage.py
  {i18n,build,install,validate} instead. This also drops dependency on
  python3-distutils-extra and replaces that with intltool
* debian/control: drop X-Python3-Version
* debian/control: make plainbox-provider-checkbox depend on python and
  python2.7 (for some scripts) rather than suggesting them.
* debian/upstream/signing-key.asc: Use armoured gpg keys to avoid having to
  keep binary files in Debian packaging. Also, replace that with my key
  since I made the 0.3 release upstream.
* debian/source/lintian-overrides: add an override for warning about no
  source for flash movie with reference to a bug report that discusses that
  issue.
* debian/source/include-binaries: drop (no longer needed)
* debian/patches: drop (no longer needed)
* debian/plainbox-provider-checkbox.lintian-overrides: drop (no longer
  needed)
* Stop being a python3 module, move to from DPMT to PAPT

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python3
 
2
#
 
3
# This program is free software: you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License version 3,
 
5
# as published by the Free Software Foundation.
 
6
#
 
7
# This program is distributed in the hope that it will be useful,
 
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
# GNU General Public License for more details.
 
11
#
 
12
# You should have received a copy of the GNU General Public License
 
13
# along with this program; if not, write to the Free Software Foundation,
 
14
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
15
#
 
16
# Parts of this are based on the example python code that ships with
 
17
# NetworkManager
 
18
# http://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python
 
19
#
 
20
# Copyright (C) 2012 Canonical, Ltd.
 
21
 
 
22
from subprocess import check_output, CalledProcessError, STDOUT
 
23
import sys
 
24
 
 
25
import dbus
 
26
 
 
27
from checkbox_support.parsers.modinfo import ModinfoParser
 
28
from checkbox_support.parsers.udevadm import UdevadmParser
 
29
 
 
30
 
 
31
# This example lists basic information about network interfaces known to NM
 
32
devtypes = {1: "Ethernet",
 
33
            2: "WiFi",
 
34
            5: "Bluetooth",
 
35
            6: "OLPC",
 
36
            7: "WiMAX",
 
37
            8: "Modem"}
 
38
 
 
39
states = {0: "Unknown",
 
40
          10: "Unmanaged",
 
41
          20: "Unavailable",
 
42
          30: "Disconnected",
 
43
          40: "Prepare",
 
44
          50: "Config",
 
45
          60: "Need Auth",
 
46
          70: "IP Config",
 
47
          80: "IP Check",
 
48
          90: "Secondaries",
 
49
          100: "Activated",
 
50
          110: "Deactivating",
 
51
          120: "Failed"}
 
52
 
 
53
attributes = ("category", "interface", "product", "vendor", "driver", "path")
 
54
 
 
55
udev_devices = []
 
56
nm_devices = []
 
57
 
 
58
 
 
59
class UdevResult:
 
60
    def addDevice(self, device):
 
61
        if device.interface:
 
62
            udev_devices.append(device)
 
63
 
 
64
 
 
65
class NetworkingDevice():
 
66
    def __init__(self, devtype, props, dev_proxy, bus):
 
67
        self._devtype = devtype
 
68
        try:
 
69
            self._interface = props['Interface']
 
70
        except KeyError:
 
71
            self._interface = "Unknown"
 
72
 
 
73
        try:
 
74
            self._ip = self._int_to_ip(props['Ip4Address'])
 
75
        except KeyError:
 
76
            self._ip = "Unknown"
 
77
 
 
78
        try:
 
79
            self._driver = props['Driver']
 
80
        except KeyError:
 
81
            self._driver = "Unknown"
 
82
            self._driver_ver = "Unknown"
 
83
 
 
84
        if self._driver != "Unknown":
 
85
            self._modinfo = self._modinfo_parser(props['Driver'])
 
86
            if self._modinfo:
 
87
                self._driver_ver = self._find_driver_ver()
 
88
            else:
 
89
                self._driver_ver = "Unknown"
 
90
 
 
91
        try:
 
92
            self._firmware_missing = props['FirmwareMissing']
 
93
        except KeyError:
 
94
            self._firmware_missing = False
 
95
 
 
96
        try:
 
97
            self._state = states[props['State']]
 
98
        except KeyError:
 
99
            self._state = "Unknown"
 
100
 
 
101
    def __str__(self):
 
102
        ret = "Category: %s\n" % self._devtype
 
103
        ret += "Interface: %s\n" % self._interface
 
104
        ret += "IP: %s\n" % self._ip
 
105
        ret += "Driver: %s (ver: %s)\n" % (self._driver, self._driver_ver)
 
106
        if self._firmware_missing:
 
107
            ret += "Warning: Required Firmware Missing for device\n"
 
108
        ret += "State: %s\n" % self._state
 
109
        return ret
 
110
 
 
111
    def getstate(self):
 
112
        return self._state
 
113
 
 
114
    def gettype(self):
 
115
        return self._devtype
 
116
 
 
117
    def _bitrate_to_mbps(self, bitrate):
 
118
        try:
 
119
            intbr = int(bitrate)
 
120
            return str(intbr / 1000)
 
121
        except Exception:
 
122
            return "NaN"
 
123
 
 
124
    def _modinfo_parser(self, driver):
 
125
        cmd = ['/sbin/modinfo', driver]
 
126
        try:
 
127
            stream = check_output(cmd, stderr=STDOUT, universal_newlines=True)
 
128
        except CalledProcessError as err:
 
129
            print("Error running %s:" % ' '.join(cmd), file=sys.stderr)
 
130
            print(err.output, file=sys.stderr)
 
131
            return None
 
132
 
 
133
        if not stream:
 
134
            print("Error: modinfo returned nothing", file=sys.stderr)
 
135
            return None
 
136
        else:
 
137
            parser = ModinfoParser(stream)
 
138
            modinfo = parser.get_all()
 
139
 
 
140
        return modinfo
 
141
 
 
142
    def _find_driver_ver(self):
 
143
        # try the version field first, then vermagic second, some audio
 
144
        # drivers don't report version if the driver is in-tree
 
145
        if self._modinfo['version'] and self._modinfo['version'] != 'in-tree:':
 
146
            return self._modinfo['version']
 
147
        else:
 
148
            # vermagic will look like this (below) and we only care about the
 
149
            # first part:
 
150
            # "3.2.0-29-generic SMP mod_unload modversions"
 
151
            return self._modinfo['vermagic'].split()[0]
 
152
 
 
153
    def _int_to_ip(self, int_ip):
 
154
        ip = [0, 0, 0, 0]
 
155
        ip[0] = int_ip & 0xff
 
156
        ip[1] = (int_ip >> 8) & 0xff
 
157
        ip[2] = (int_ip >> 16) & 0xff
 
158
        ip[3] = (int_ip >> 24) & 0xff
 
159
        return "%d.%d.%d.%d" % (ip[0], ip[1], ip[2], ip[3])
 
160
 
 
161
 
 
162
def get_nm_devices():
 
163
    devices = []
 
164
    bus = dbus.SystemBus()
 
165
 
 
166
    # Get a proxy for the base NetworkManager object
 
167
    proxy = bus.get_object("org.freedesktop.NetworkManager",
 
168
                           "/org/freedesktop/NetworkManager")
 
169
    manager = dbus.Interface(proxy, "org.freedesktop.NetworkManager")
 
170
 
 
171
    # Get all devices known to NM and print their properties
 
172
    nm_devices = manager.GetDevices()
 
173
    for d in nm_devices:
 
174
        dev_proxy = bus.get_object("org.freedesktop.NetworkManager", d)
 
175
        prop_iface = dbus.Interface(dev_proxy,
 
176
                                    "org.freedesktop.DBus.Properties")
 
177
        props = prop_iface.GetAll("org.freedesktop.NetworkManager.Device")
 
178
        try:
 
179
            devtype = devtypes[props['DeviceType']]
 
180
        except KeyError:
 
181
            devtype = "Unknown"
 
182
 
 
183
        # only return WiFi, Ethernet and Modem devices
 
184
        if devtype in ("WiFi", "Ethernet", "Modem"):
 
185
            devices.append(NetworkingDevice(devtype, props, dev_proxy, bus))
 
186
    return devices
 
187
 
 
188
 
 
189
def match_counts(nm_devices, udev_devices, devtype):
 
190
    """
 
191
    Ensures that the count of devices matching devtype is the same for the
 
192
    two passed in lists, devices from Network Manager and devices from lspci.
 
193
    """
 
194
    # now check that the count (by type) matches
 
195
    nm_type_devices = [dev for dev in nm_devices if dev.gettype() in devtype]
 
196
    udevtype = 'WIRELESS' if devtype == 'WiFi' else 'NETWORK'
 
197
    udev_type_devices = [
 
198
        udev
 
199
        for udev in udev_devices
 
200
        if udev.category == udevtype]
 
201
    if len(nm_type_devices) != len(udev_type_devices):
 
202
        print("ERROR: devices missing - udev showed %d %s devices, but "
 
203
              "NetworkManager saw %d devices in %s" % (len(udev_type_devices), 
 
204
              udevtype, len(nm_type_devices), devtype), file=sys.stderr)
 
205
        return False
 
206
    else:
 
207
        return True
 
208
 
 
209
 
 
210
def main(args):
 
211
    try:
 
212
        output = check_output(['udevadm', 'info', '--export-db'])
 
213
    except CalledProcessError as err:
 
214
        raise SystemExit(err)
 
215
    try:
 
216
        output = output.decode("UTF-8", errors='ignore')
 
217
    except UnicodeDecodeError as err:
 
218
        raise SystemExit("udevadm output is not valid UTF-8")
 
219
    udev = UdevadmParser(output)
 
220
    result = UdevResult()
 
221
    udev.run(result)
 
222
 
 
223
    if udev_devices:
 
224
        print("[ Devices found by udev ]".center(80, '-'))
 
225
        for device in udev_devices:
 
226
            for attribute in attributes:
 
227
                value = getattr(device, attribute)
 
228
                if value is not None:
 
229
                    if attribute == 'driver':
 
230
                        props = {}
 
231
                        props['Driver'] = value
 
232
                        network_dev = NetworkingDevice(None, props, None, None)
 
233
                        print("%s: %s (ver: %s)" % (attribute.capitalize(),
 
234
                              value, network_dev._driver_ver))
 
235
                    else:
 
236
                        print("%s: %s" % (attribute.capitalize(), value))
 
237
 
 
238
            print()
 
239
 
 
240
    try:
 
241
        nm_devices = get_nm_devices()
 
242
    except dbus.exceptions.DBusException as e:
 
243
        # server's don't have network manager installed
 
244
        print("Warning: Exception while talking to Network Manager over dbus."
 
245
              " Skipping the remainder of this test. If this is a server, this"
 
246
              " is expected.", file=sys.stderr)
 
247
        print("The Error Generated was:\n %s" % e, file=sys.stderr)
 
248
        return 0
 
249
 
 
250
    print("[ Devices found by Network Manager ]".center(80, '-'))
 
251
    for nm_dev in nm_devices:
 
252
        print(nm_dev)
 
253
 
 
254
    if not match_counts(nm_devices, udev_devices, "WiFi"):
 
255
        return 1
 
256
    elif not match_counts(nm_devices, udev_devices, ("Ethernet","Modem")):
 
257
        return 1
 
258
    else:
 
259
        return 0
 
260
 
 
261
if __name__ == "__main__":
 
262
    sys.exit(main(sys.argv[1:]))