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