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+ }
56+
4057
4158# pylint: disable=too-many-public-methods
4259class Shell :
@@ -555,24 +572,29 @@ def get_raspbian_version(self):
555572 """Return a string containing the raspbian version"""
556573 if self .get_os () != "Raspbian" :
557574 return None
558- raspbian_releases = (
559- "bookworm" ,
560- "bullseye" ,
561- "buster" ,
562- "stretch" ,
563- "jessie" ,
564- "wheezy" ,
565- )
566575 if os .path .exists ("/etc/os-release" ):
567576 with open ("/etc/os-release" , encoding = "utf-8" ) as f :
568577 release_file = f .read ()
569578 if "/sid" in release_file :
570579 return "unstable"
571- for raspbian in raspbian_releases :
580+ for raspbian in RASPI_VERSIONS :
572581 if raspbian in release_file :
573582 return raspbian
574583 return None
575584
585+ def is_minumum_version (self , version ):
586+ """Check if the version is at least the specified version"""
587+ # Check that version is a string
588+ if not isinstance (version , str ):
589+ raise ValueError ("Version must be a string" )
590+ # Check that version is in the list of valid versions
591+ if version .lower () not in RASPI_VERSIONS :
592+ raise ValueError ("Invalid version" )
593+ # Check that the current version is at least the specified version
594+ return RASPI_VERSIONS .index (
595+ self .get_raspbian_version ()
596+ ) >= RASPI_VERSIONS .index (version .lower ())
597+
576598 def prompt_reboot (self , default = "y" , ** kwargs ):
577599 """Prompt the user for a reboot"""
578600 if not self .prompt ("REBOOT NOW?" , default = default , ** kwargs ):
@@ -592,21 +614,64 @@ def check_kernel_update_reboot_required(self):
592614 )
593615 self .prompt_reboot ()
594616
595- def check_kernel_userspace_mismatch (self ):
617+ def check_kernel_userspace_mismatch (self , attempt_fix = True , fix_with_x11 = False ):
596618 """
597619 Check if the userspace is 64-bit and kernel is 32-bit
598620 """
599- if self .is_arm64 () and platform . architecture ()[ 0 ] == "32bit" :
621+ if self .is_kernel_userspace_mismatched () :
600622 print (
601623 "Unable to compile driver because kernel space is 64-bit, but user space is 32-bit."
602624 )
603- if self .is_raspberry_pi_os () and self .prompt (
604- "Add parameter to /boot/config.txt to use 32-bit kernel?"
625+ config = self .get_boot_config ()
626+ if (
627+ self .is_raspberry_pi_os ()
628+ and attempt_fix
629+ and config
630+ and self .prompt (f"Add parameter to { config } to use 32-bit kernel?" )
605631 ):
606- self .reconfig ("/boot/config.txt" , "^.*arm_64bit.*$" , "arm_64bit=0" )
632+ # Set to use 32-bit kernel
633+ self .reconfig (config , "^.*arm_64bit.*$" , "arm_64bit=0" )
634+ if fix_with_x11 :
635+ self .set_window_manager ("x11" )
607636 self .prompt_reboot ()
608637 else :
609- self .bail ("Unable to continue while mismatch is present." )
638+ raise RuntimeError ("Unable to continue while mismatch is present." )
639+
640+ def set_window_manager (self , manager ):
641+ """
642+ Call raspi-config to set a new window manager
643+ """
644+ if not self .is_minumum_version ("bullseye" ):
645+ return
646+
647+ if manager .lower () not in WINDOW_MANAGERS :
648+ raise ValueError ("Invalid window manager" )
649+
650+ if manager .lower () == "labwc" and not self .exists ("/usr/bin/labwc" ):
651+ raise RuntimeError ("labwc is not installed" )
652+
653+ print (f"Using { manager } as the window manager" )
654+ if not self .run_command (
655+ "sudo raspi-config nonint do_wayland " + WINDOW_MANAGERS [manager .lower ()]
656+ ):
657+ raise RuntimeError ("Unable to change window manager" )
658+
659+ def get_boot_config (self ):
660+ """
661+ Get the location of the boot config file
662+ """
663+ # check if /boot/firmware/config.txt exists
664+ if self .exists ("/boot/firmware/config.txt" ):
665+ return "/boot/firmware/config.txt"
666+ if self .exists ("/boot/config.txt" ):
667+ return "/boot/config.txt"
668+ return None
669+
670+ def is_kernel_userspace_mismatched (self ):
671+ """
672+ If the userspace 64-bit and kernel is 32-bit?
673+ """
674+ return self .is_arm64 () and platform .architecture ()[0 ] == "32bit"
610675
611676 # pylint: enable=invalid-name
612677
0 commit comments