1""" 2Manage and query udev info 3 4.. versionadded:: 2015.8.0 5 6""" 7 8import logging 9 10import salt.modules.cmdmod 11import salt.utils.path 12from salt.exceptions import CommandExecutionError 13 14__salt__ = { 15 "cmd.run_all": salt.modules.cmdmod.run_all, 16} 17 18log = logging.getLogger(__name__) 19 20 21def __virtual__(): 22 """ 23 Only work when udevadm is installed. 24 """ 25 return salt.utils.path.which_bin(["udevadm"]) is not None 26 27 28def _parse_udevadm_info(udev_info): 29 """ 30 Parse the info returned by udevadm command. 31 """ 32 devices = [] 33 dev = {} 34 35 for line in (line.strip() for line in udev_info.splitlines()): 36 if line: 37 line = line.split(":", 1) 38 if len(line) != 2: 39 continue 40 query, data = line 41 if query == "E": 42 if query not in dev: 43 dev[query] = {} 44 key, val = data.strip().split("=", 1) 45 46 try: 47 val = int(val) 48 except ValueError: 49 try: 50 val = float(val) 51 except ValueError: 52 pass # Quiet, this is not a number. 53 54 dev[query][key] = val 55 else: 56 if query not in dev: 57 dev[query] = [] 58 dev[query].append(data.strip()) 59 else: 60 if dev: 61 devices.append(_normalize_info(dev)) 62 dev = {} 63 if dev: 64 _normalize_info(dev) 65 devices.append(_normalize_info(dev)) 66 67 return devices 68 69 70def _normalize_info(dev): 71 """ 72 Replace list with only one element to the value of the element. 73 74 :param dev: 75 :return: 76 """ 77 for sect, val in dev.items(): 78 if len(val) == 1: 79 dev[sect] = val[0] 80 81 return dev 82 83 84def info(dev): 85 """ 86 Extract all info delivered by udevadm 87 88 CLI Example: 89 90 .. code-block:: bash 91 92 salt '*' udev.info /dev/sda 93 salt '*' udev.info /sys/class/net/eth0 94 """ 95 if "sys" in dev: 96 qtype = "path" 97 else: 98 qtype = "name" 99 100 cmd = "udevadm info --export --query=all --{}={}".format(qtype, dev) 101 udev_result = __salt__["cmd.run_all"](cmd, output_loglevel="quiet") 102 103 if udev_result["retcode"] != 0: 104 raise CommandExecutionError(udev_result["stderr"]) 105 106 return _parse_udevadm_info(udev_result["stdout"])[0] 107 108 109def env(dev): 110 """ 111 Return all environment variables udev has for dev 112 113 CLI Example: 114 115 .. code-block:: bash 116 117 salt '*' udev.env /dev/sda 118 salt '*' udev.env /sys/class/net/eth0 119 """ 120 return info(dev).get("E", None) 121 122 123def name(dev): 124 """ 125 Return the actual dev name(s?) according to udev for dev 126 127 CLI Example: 128 129 .. code-block:: bash 130 131 salt '*' udev.dev /dev/sda 132 salt '*' udev.dev /sys/class/net/eth0 133 """ 134 return info(dev).get("N", None) 135 136 137def path(dev): 138 """ 139 Return the physical device path(s?) according to udev for dev 140 141 CLI Example: 142 143 .. code-block:: bash 144 145 salt '*' udev.path /dev/sda 146 salt '*' udev.path /sys/class/net/eth0 147 """ 148 return info(dev).get("P", None) 149 150 151def links(dev): 152 """ 153 Return all udev-created device symlinks 154 155 CLI Example: 156 157 .. code-block:: bash 158 159 salt '*' udev.links /dev/sda 160 salt '*' udev.links /sys/class/net/eth0 161 """ 162 return info(dev).get("S", None) 163 164 165def exportdb(): 166 """ 167 Return all the udev database 168 169 CLI Example: 170 171 .. code-block:: bash 172 173 salt '*' udev.exportdb 174 """ 175 176 cmd = "udevadm info --export-db" 177 udev_result = __salt__["cmd.run_all"](cmd, output_loglevel="quiet") 178 179 if udev_result["retcode"]: 180 raise CommandExecutionError(udev_result["stderr"]) 181 182 return _parse_udevadm_info(udev_result["stdout"]) 183