[go: up one dir, main page]

File: wificheck.py

package info (click to toggle)
comitup 1.43-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,252 kB
  • sloc: python: 3,093; javascript: 1,261; sh: 95; makefile: 34
file content (158 lines) | stat: -rwxr-xr-x 4,269 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/python3
# Copyright (c) 2017-2019 David Steele <dsteele@gmail.com>
#
# SPDX-License-Identifier: GPL-2.0-or-later
# License-Filename: LICENSE


import logging
import os
import re
import subprocess
import textwrap
from collections import namedtuple
from typing import List, Optional, Tuple

log = logging.getLogger("comitup")


class DevInfo(object):
    def __init__(self, primary_dev: str = ""):
        self.dev_list: List[Tuple[str, str]] = []
        for dev in os.listdir("/sys/class/net"):
            try:
                path = "/sys/class/net/{}/phy80211/name".format(dev)
                with open(path, "r") as fp:
                    phy = fp.read().strip()

                if dev == primary_dev:
                    self.dev_list.insert(0, (dev, phy))
                else:
                    self.dev_list.append((dev, phy))
            except (NotADirectoryError, FileNotFoundError):
                pass

    def get_devs(self) -> List[str]:
        return [x[0] for x in self.dev_list]

    def get_phy(self, dev: str) -> str:
        return [x[1] for x in self.dev_list if x[0] == dev][0]


dev_info: DevInfo = DevInfo()


def device_present() -> Optional[str]:
    if dev_info.get_devs():
        return None
    else:
        # Fail without comment
        return ""


def device_supports_ap() -> Optional[str]:
    dev: str

    for dev in dev_info.get_devs():
        phy: str = dev_info.get_phy(dev)

        try:
            cmd: str = "iw phy {} info".format(phy)
            deviceinfo: str = subprocess.check_output(cmd.split()).decode()
        except subprocess.CalledProcessError:
            return ""

        if "* AP\n" in deviceinfo:
            return None

    return ""


def device_nm_managed() -> Optional[str]:
    try:
        cmd: str = "nmcli device show"
        try:
            devsinfo: str = subprocess.check_output(
                cmd.split(), re.MULTILINE
            ).decode()
        except UnicodeDecodeError:
            # shouldn't happen, but it does. Move on
            return None

        for dev in dev_info.get_devs():
            if dev not in devsinfo:
                # Fail without comment
                return ""
    except subprocess.CalledProcessError:
        pass

    return None


testspec = namedtuple("testspec", ["testfn", "title", "description"])


testspecs = [
    testspec(
        device_present,
        "comitup-no-wifi - No wifi devices found",
        textwrap.dedent(
            """
            Comitup is a wifi device manager. 'sudo iw list' indicates that
            there are no devices to manage.
        """
        ),
    ),
    testspec(
        device_supports_ap,
        "comitup-no-ap - The Main wifi device doesn't support AP mode",
        textwrap.dedent(
            """
            Comitup uses the first wifi device to implement the comitup-<nnn>
            Access Point. For this to work, the device must include "AP" in
            list of "Supported interface modes" returned by "iw list".
        """
        ),
    ),
    testspec(
        device_nm_managed,
        "comitup-no-nm - Wifi device is not managed by NetworkManager",
        textwrap.dedent(
            """
            Comitup uses NetworkManager to manage the wifi devices, but the
            required devices are not listed. This usually means that the
            devices are listed in /etc/network/interfaces, and are therefore
            being managed elsewhere. Remove the references to wifi devices
            from that file.
        """
        ),
    ),
]


def run_checks(logit=True, printit=True, verbose=True, primary_dev="") -> bool:
    global dev_info

    dev_info = DevInfo(primary_dev)

    for testspec in testspecs:
        testresult = testspec.testfn()
        if testresult is not None:
            if logit:
                log.error(testspec.title)
                if testresult:
                    log.error("    " + testresult)

            if printit:
                print(testspec.title)
                if testresult:
                    print("    " + testresult)
                if verbose:
                    print(testspec.description)
            return True

    return False


if __name__ == "__main__":
    run_checks(logit=False)