linux.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. """OS-specific functions for: Linux
  2. """
  3. import platform
  4. from pathlib import Path
  5. from milc import cli
  6. from qmk.constants import QMK_FIRMWARE
  7. from .check import CheckStatus, release_info
  8. QMK_UDEV_INSTALL_SCRIPT = 'util/install_udev.sh'
  9. def _is_wsl():
  10. return 'microsoft' in platform.uname().release.lower()
  11. def check_udev_rules():
  12. """Make sure the udev rules look good.
  13. """
  14. udev_dirs = [
  15. Path("/usr/lib/udev/rules.d/"),
  16. Path("/usr/local/lib/udev/rules.d/"),
  17. Path("/run/udev/rules.d/"),
  18. Path("/etc/udev/rules.d/"),
  19. ]
  20. if not any(udev_dir.exists() for udev_dir in udev_dirs):
  21. cli.log.warning("{fg_yellow}Can't find udev rules directories, skipping udev rule checking...")
  22. cli.log.debug("Checked directories: %s", ', '.join(str(udev_dir) for udev_dir in udev_dirs))
  23. return CheckStatus.WARNING
  24. # Collect all non-comment lines from QMK-related rules files
  25. current_rules = set()
  26. for udev_dir in udev_dirs:
  27. for rule_file in udev_dir.glob('*qmk*'):
  28. try:
  29. for line in rule_file.read_text(encoding='utf-8').split('\n'):
  30. line = line.strip()
  31. if not line.startswith("#") and len(line):
  32. current_rules.add(line)
  33. except (PermissionError, FileNotFoundError):
  34. cli.log.debug("Failed to read: %s", rule_file)
  35. if not current_rules:
  36. cli.log.warning("{fg_yellow}Missing udev rules for QMK boards. Please run '%s' to install the rules", QMK_UDEV_INSTALL_SCRIPT)
  37. return CheckStatus.WARNING
  38. # Check for the qmk_udev ID_QMK marker
  39. if any('ID_QMK' in rule for rule in current_rules):
  40. return CheckStatus.OK
  41. # Legacy rules found (TAG+="uaccess" without ID_QMK)
  42. cli.log.warning("{fg_yellow}Found legacy udev rules. Please run '%s' to install the latest rules", QMK_UDEV_INSTALL_SCRIPT)
  43. return CheckStatus.WARNING
  44. def os_test_linux():
  45. """Run the Linux specific tests.
  46. """
  47. info = release_info()
  48. release_id = info.get('PRETTY_NAME', info.get('ID', 'Unknown'))
  49. plat = 'WSL, ' if _is_wsl() else ''
  50. cli.log.info(f"Detected {{fg_cyan}}Linux ({plat}{release_id}){{fg_reset}}.")
  51. # Don't bother with udev on WSL, for now
  52. if _is_wsl():
  53. # https://github.com/microsoft/WSL/issues/4197
  54. if QMK_FIRMWARE.as_posix().startswith("/mnt"):
  55. cli.log.warning("I/O performance on /mnt may be extremely slow.")
  56. return CheckStatus.WARNING
  57. else:
  58. rc = check_udev_rules()
  59. if rc != CheckStatus.OK:
  60. return rc
  61. return CheckStatus.OK