37
37
__version__ = "0.0.0+auto.0"
38
38
__repo__ = "https://github.com/adafruit/Adafruit_Python_Shell.git"
39
39
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
+ }
40
56
41
57
# pylint: disable=too-many-public-methods
42
58
class Shell :
@@ -555,24 +571,29 @@ def get_raspbian_version(self):
555
571
"""Return a string containing the raspbian version"""
556
572
if self .get_os () != "Raspbian" :
557
573
return None
558
- raspbian_releases = (
559
- "bookworm" ,
560
- "bullseye" ,
561
- "buster" ,
562
- "stretch" ,
563
- "jessie" ,
564
- "wheezy" ,
565
- )
566
574
if os .path .exists ("/etc/os-release" ):
567
575
with open ("/etc/os-release" , encoding = "utf-8" ) as f :
568
576
release_file = f .read ()
569
577
if "/sid" in release_file :
570
578
return "unstable"
571
- for raspbian in raspbian_releases :
579
+ for raspbian in RASPI_VERSIONS :
572
580
if raspbian in release_file :
573
581
return raspbian
574
582
return None
575
583
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
+
576
597
def prompt_reboot (self , default = "y" , ** kwargs ):
577
598
"""Prompt the user for a reboot"""
578
599
if not self .prompt ("REBOOT NOW?" , default = default , ** kwargs ):
@@ -592,21 +613,59 @@ def check_kernel_update_reboot_required(self):
592
613
)
593
614
self .prompt_reboot ()
594
615
595
- def check_kernel_userspace_mismatch (self ):
616
+ def check_kernel_userspace_mismatch (self , attempt_fix = True , fix_with_x11 = False ):
596
617
"""
597
618
Check if the userspace is 64-bit and kernel is 32-bit
598
619
"""
599
- if self .is_arm64 () and platform . architecture ()[ 0 ] == "32bit" :
620
+ if self .is_kernel_userspace_mismatched () :
600
621
print (
601
622
"Unable to compile driver because kernel space is 64-bit, but user space is 32-bit."
602
623
)
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?"
605
627
):
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" )
607
632
self .prompt_reboot ()
608
633
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"
610
669
611
670
# pylint: enable=invalid-name
612
671
0 commit comments