3737__version__ = "0.0.0+auto.0"
3838__repo__ = "https://github.com/adafruit/Adafruit_Python_Shell.git"
3939
40+ # This must be by order of release
41+ RASPI_VERSIONS = (
42+ "wheezy" ,
43+ "jessie" ,
44+ "stretch" ,
45+ "buster" ,
46+ "bullseye" ,
47+ "bookworm" ,
48+ "trixie" ,
49+ )
50+
51+ WINDOW_MANAGERS = {
52+ "x11" : "W1" ,
53+ "wayland" : "W2" ,
54+ "labwc" : "W3" ,
55+ }
4056
4157# pylint: disable=too-many-public-methods
4258class Shell :
@@ -555,24 +571,29 @@ def get_raspbian_version(self):
555571 """Return a string containing the raspbian version"""
556572 if self .get_os () != "Raspbian" :
557573 return None
558- raspbian_releases = (
559- "bookworm" ,
560- "bullseye" ,
561- "buster" ,
562- "stretch" ,
563- "jessie" ,
564- "wheezy" ,
565- )
566574 if os .path .exists ("/etc/os-release" ):
567575 with open ("/etc/os-release" , encoding = "utf-8" ) as f :
568576 release_file = f .read ()
569577 if "/sid" in release_file :
570578 return "unstable"
571- for raspbian in raspbian_releases :
579+ for raspbian in RASPI_VERSIONS :
572580 if raspbian in release_file :
573581 return raspbian
574582 return None
575583
584+ def is_minumum_version (self , version ):
585+ """Check if the version is at least the specified version"""
586+ # Check that version is a string
587+ if not isinstance (version , str ):
588+ raise ValueError ("Version must be a string" )
589+ # Check that version is in the list of valid versions
590+ if version .lower () not in RASPI_VERSIONS :
591+ raise ValueError ("Invalid version" )
592+ # Check that the current version is at least the specified version
593+ return RASPI_VERSIONS .index (self .get_raspbian_version ()) >= RASPI_VERSIONS .index (
594+ version .lower ()
595+ )
596+
576597 def prompt_reboot (self , default = "y" , ** kwargs ):
577598 """Prompt the user for a reboot"""
578599 if not self .prompt ("REBOOT NOW?" , default = default , ** kwargs ):
@@ -592,21 +613,59 @@ def check_kernel_update_reboot_required(self):
592613 )
593614 self .prompt_reboot ()
594615
595- def check_kernel_userspace_mismatch (self ):
616+ def check_kernel_userspace_mismatch (self , attempt_fix = True , fix_with_x11 = False ):
596617 """
597618 Check if the userspace is 64-bit and kernel is 32-bit
598619 """
599- if self .is_arm64 () and platform . architecture ()[ 0 ] == "32bit" :
620+ if self .is_kernel_userspace_mismatched () :
600621 print (
601622 "Unable to compile driver because kernel space is 64-bit, but user space is 32-bit."
602623 )
603- if self .is_raspberry_pi_os () and self .prompt (
604- "Add parameter to /boot/config.txt to use 32-bit kernel?"
624+ config = self .get_boot_config ()
625+ if self .is_raspberry_pi_os () and attempt_fix and config and self .prompt (
626+ f"Add parameter to { config } to use 32-bit kernel?"
605627 ):
606- self .reconfig ("/boot/config.txt" , "^.*arm_64bit.*$" , "arm_64bit=0" )
628+ # Set to use 32-bit kernel
629+ self .reconfig (config , "^.*arm_64bit.*$" , "arm_64bit=0" )
630+ if fix_with_x11 :
631+ self .set_window_manager ("x11" )
607632 self .prompt_reboot ()
608633 else :
609- self .bail ("Unable to continue while mismatch is present." )
634+ raise RuntimeError ("Unable to continue while mismatch is present." )
635+
636+ def set_window_manager (self , manager ):
637+ """
638+ Call raspi-config to set a new window manager
639+ """
640+ if not self .is_minumum_version ("bullseye" ):
641+ return
642+
643+ if manager .lower () not in WINDOW_MANAGERS .keys ():
644+ raise ValueError ("Invalid window manager" )
645+
646+ if manager .lower () == "labwc" and not self .exists ("/usr/bin/labwc" ):
647+ raise RuntimeError ("labwc is not installed" )
648+
649+ print (f"Using { manager } as the window manager" )
650+ if not self .run_command ("sudo raspi-config nonint do_wayland " + WINDOW_MANAGERS [manager .lower ()]):
651+ raise RuntimeError ("Unable to change window manager" )
652+
653+ def get_boot_config (self ):
654+ """
655+ Get the location of the boot config file
656+ """
657+ # check if /boot/firmware/config.txt exists
658+ if self .exists ("/boot/firmware/config.txt" ):
659+ return "/boot/firmware/config.txt"
660+ elif self .exists ("/boot/config.txt" ):
661+ return "/boot/config.txt"
662+ return None
663+
664+ def is_kernel_userspace_mismatched (self ):
665+ """
666+ If the userspace 64-bit and kernel is 32-bit?
667+ """
668+ return self .is_arm64 () and platform .architecture ()[0 ] == "32bit"
610669
611670 # pylint: enable=invalid-name
612671
0 commit comments