diff --git a/home/stormux/.xinitrc b/home/stormux/.xinitrc index c323d7e..3f9d978 100755 --- a/home/stormux/.xinitrc +++ b/home/stormux/.xinitrc @@ -306,6 +306,20 @@ case "$GAME" in orca & exec steam -bigpicture ;; + "thunderbird") + if ! command -v thunderbird &> /dev/null; then + yay -Sy --noconfirm thunderbird + fi + orca & + exec thunderbird + ;; + "libreoffice") + if ! command -v libreoffice &> /dev/null; then + yay -Sy --noconfirm libreoffice-still + fi + orca & + exec libreoffice + ;; "Super Egg Hunt") run_wine "super egg hunt" "superegghunt.exe" ;; diff --git a/usr/local/bin/game_launcher.py b/usr/local/bin/game_launcher.py index a14b37e..3e67a8d 100755 --- a/usr/local/bin/game_launcher.py +++ b/usr/local/bin/game_launcher.py @@ -416,29 +416,10 @@ class VoicedMenu: self.add_item("System", f"Enable {friendlyName}", lambda fn=friendlyName: self.toggle_service(fn)) - def install_and_launch(self, package_name, executable_name, launch_mode="gui"): - """Install package if needed and launch it""" + def install_and_launch(self, executable_name, launch_mode="gui"): + """Launch application via xinitrc (which handles installation if needed)""" try: - # Check if executable exists - check_cmd = f"command -v {executable_name}" - result = subprocess.run(check_cmd, shell=True, capture_output=True) - - if result.returncode != 0: - # Package not installed, inform user and install - self.speak(f"Installing {executable_name}. This may take a few minutes.", interrupt=False) - - # Install using yay - install_cmd = f"yay -Sy --noconfirm {package_name}" - install_result = subprocess.run(install_cmd, shell=True, capture_output=True, text=True) - - if install_result.returncode != 0: - error_msg = f"Could not install {package_name}. {install_result.stderr}" - self.speak(error_msg, interrupt=False) - return - - self.speak(f"{executable_name} installed successfully. Launching now.", interrupt=False) - - # Launch the application + # Launch the application - xinitrc will handle installation if launch_mode == "gui": command = f"GAME='{executable_name}' startx" else: # cli mode @@ -470,7 +451,7 @@ class VoicedMenu: self.menuSections = original_items except Exception as e: - error_msg = f"Error installing or launching {executable_name}: {e}" + error_msg = f"Error launching {executable_name}: {e}" self.speak(error_msg, interrupt=False) def update_bluetooth_menu_items(self): @@ -1096,8 +1077,8 @@ if __name__ == "__main__": menu.add_item("Accessories", "Local IP Address", "/usr/local/bin/ip_info.py local") menu.add_item("Accessories", "Remote IP Address", "/usr/local/bin/ip_info.py remote") menu.add_item("Accessories", "Web Browser", "GAME=Brave startx") - menu.add_item("Accessories", "LibreOffice", lambda: menu.install_and_launch("libreoffice-still", "libreoffice", "gui")) - menu.add_item("Accessories", "Thunderbird", lambda: menu.install_and_launch("thunderbird", "thunderbird", "gui")) + menu.add_item("Accessories", "LibreOffice", lambda: menu.install_and_launch("libreoffice", "gui")) + menu.add_item("Accessories", "Thunderbird", lambda: menu.install_and_launch("thunderbird", "gui")) # Add system section menu.add_section("System") diff --git a/usr/local/bin/install_to_disk.sh b/usr/local/bin/install_to_disk.sh index e8d00bd..4684172 100755 --- a/usr/local/bin/install_to_disk.sh +++ b/usr/local/bin/install_to_disk.sh @@ -13,13 +13,15 @@ error_exit() { # Function to find the source USB device find_source_device() { # Look for the device we're currently running from - local root_device=$(findmnt -n -o SOURCE /) + local root_device + root_device=$(findmnt -n -o SOURCE /) if [[ "$root_device" =~ ^/dev/(sd[a-z]|nvme[0-9]n[0-9]|mmcblk[0-9]) ]]; then # Extract just the device name (remove partition number) echo "$root_device" | sed 's/[0-9]*$//' | sed 's/p$//' else # Fallback: look for devices with STORMUX label - local labeled_device=$(lsblk -no NAME,LABEL | grep -i stormux | head -1 | awk '{print "/dev/" $1}' | sed 's/[0-9]*$//' | sed 's/p$//') + local labeled_device + labeled_device=$(lsblk -no NAME,LABEL | grep -i stormux | head -1 | awk '{print "/dev/" $1}' | sed 's/[0-9]*$//' | sed 's/p$//') if [[ -n "$labeled_device" ]]; then echo "$labeled_device" else @@ -49,15 +51,21 @@ detect_target_disks() { # Function to get disk info get_disk_info() { local disk="$1" - local size=$(lsblk -dpno SIZE "$disk" 2>/dev/null | tr -d ' ') - local model=$(lsblk -dpno MODEL "$disk" 2>/dev/null | tr -d ' ' || echo "Unknown") + local size + local model + size=$(lsblk -dpno SIZE "$disk" 2>/dev/null | tr -d ' ') + model=$(lsblk -dpno MODEL "$disk" 2>/dev/null | tr -d ' ' || echo "Unknown") echo "$size - $model" } -# Function to rename partition labels to prevent boot conflicts -rename_partition_labels() { +# Function to regenerate UUIDs and rename partition labels to prevent boot conflicts +regenerate_partition_identifiers() { local target_device="$1" - echo "Renaming partition labels to prevent boot conflicts..." + echo "Regenerating partition UUIDs and labels to prevent boot conflicts..." + + # Arrays to store old and new UUIDs for fstab update + declare -A old_uuids + declare -A new_uuids # Get all partitions on the target device local partitions=() @@ -67,68 +75,155 @@ rename_partition_labels() { fi done < <(lsblk -lpno NAME "$target_device" 2>/dev/null | grep "^${target_device}") - # Rename each partition based on filesystem type + # Process each partition for partition in "${partitions[@]}"; do local fstype local current_label + local current_uuid fstype=$(lsblk -no FSTYPE "$partition" 2>/dev/null) current_label=$(lsblk -no LABEL "$partition" 2>/dev/null) + current_uuid=$(lsblk -no UUID "$partition" 2>/dev/null) - # Skip if no filesystem or no current label - [[ -z "$fstype" || -z "$current_label" ]] && continue + # Skip if no filesystem + [[ -z "$fstype" ]] && continue + + # Store old UUID if it exists + [[ -n "$current_uuid" ]] && old_uuids["$partition"]="$current_uuid" # Determine new label based on current label and add -HDD suffix local new_label="" - case "$current_label" in - "STORMUX"|"stormux") - new_label="STORMUX-HDD" - ;; - "BOOT"|"boot"|"ESP") - new_label="BOOT-HDD" - ;; - *) - # For any other label, just add -HDD suffix, truncate if too long - new_label="${current_label}-HDD" - ;; - esac + if [[ -n "$current_label" ]]; then + case "$current_label" in + "STORMUX"|"stormux") + new_label="STORMUX-HDD" + ;; + "BOOT"|"boot"|"ESP") + new_label="BOOT-HDD" + ;; + *) + # For any other label, just add -HDD suffix, truncate if too long + new_label="${current_label}-HDD" + ;; + esac + fi - # Truncate label if too long (filesystem limits) + # Generate new UUID and update label based on filesystem type case "$fstype" in "vfat"|"fat32"|"fat16") - # FAT32 has 11 character limit - new_label="${new_label:0:11}" - if command -v fatlabel >/dev/null 2>&1; then - sudo fatlabel "$partition" "$new_label" 2>/dev/null || echo "Warning: Could not rename FAT partition $partition" + # FAT32 has 11 character limit for labels + if [[ -n "$new_label" ]]; then + new_label="${new_label:0:11}" + if command -v fatlabel >/dev/null 2>&1; then + sudo fatlabel "$partition" "$new_label" 2>/dev/null || echo "Warning: Could not rename FAT partition $partition" + fi + fi + # Generate new UUID for FAT - mlabel -s generates a new random serial + if command -v mlabel >/dev/null 2>&1; then + sudo mlabel -s -i "$partition" :: 2>/dev/null || echo "Warning: Could not change FAT serial on $partition" fi ;; "ext2"|"ext3"|"ext4") - # ext* has 16 character limit - new_label="${new_label:0:16}" + # ext* has 16 character limit for labels + if [[ -n "$new_label" ]]; then + new_label="${new_label:0:16}" + if command -v tune2fs >/dev/null 2>&1; then + sudo tune2fs -L "$new_label" "$partition" 2>/dev/null || echo "Warning: Could not rename ext partition $partition" + fi + fi + # Generate new UUID for ext filesystems if command -v tune2fs >/dev/null 2>&1; then - sudo tune2fs -L "$new_label" "$partition" 2>/dev/null || echo "Warning: Could not rename ext partition $partition" + sudo tune2fs -U random "$partition" 2>/dev/null || echo "Warning: Could not change UUID on $partition" fi ;; "ntfs") - # NTFS has 32 character limit - new_label="${new_label:0:32}" - if command -v ntfslabel >/dev/null 2>&1; then - sudo ntfslabel "$partition" "$new_label" 2>/dev/null || echo "Warning: Could not rename NTFS partition $partition" + # NTFS has 32 character limit for labels + if [[ -n "$new_label" ]]; then + new_label="${new_label:0:32}" + if command -v ntfslabel >/dev/null 2>&1; then + sudo ntfslabel "$partition" "$new_label" 2>/dev/null || echo "Warning: Could not rename NTFS partition $partition" + fi fi ;; "xfs") - # XFS has 12 character limit - new_label="${new_label:0:12}" + # XFS has 12 character limit for labels + if [[ -n "$new_label" ]]; then + new_label="${new_label:0:12}" + if command -v xfs_admin >/dev/null 2>&1; then + sudo xfs_admin -L "$new_label" "$partition" 2>/dev/null || echo "Warning: Could not rename XFS partition $partition" + fi + fi + # Generate new UUID for XFS if command -v xfs_admin >/dev/null 2>&1; then - sudo xfs_admin -L "$new_label" "$partition" 2>/dev/null || echo "Warning: Could not rename XFS partition $partition" + sudo xfs_admin -U generate "$partition" 2>/dev/null || echo "Warning: Could not change UUID on $partition" fi ;; *) echo "Info: Skipping unknown filesystem type '$fstype' on $partition" + continue ;; esac - echo "Renamed partition $partition: '$current_label' -> '$new_label'" + # Get the new UUID after regeneration + local new_uuid + new_uuid=$(lsblk -no UUID "$partition" 2>/dev/null) + [[ -n "$new_uuid" ]] && new_uuids["$partition"]="$new_uuid" + + if [[ -n "$current_label" && -n "$new_label" ]]; then + echo "Updated partition $partition: '$current_label' -> '$new_label'" + fi + if [[ -n "$current_uuid" && -n "$new_uuid" && "$current_uuid" != "$new_uuid" ]]; then + echo "Regenerated UUID for $partition: $current_uuid -> $new_uuid" + fi done + + # Return the UUID mappings for fstab update + for partition in "${!old_uuids[@]}"; do + if [[ -n "${new_uuids[$partition]}" ]]; then + echo "UUID_MAPPING:${old_uuids[$partition]}:${new_uuids[$partition]}" + fi + done +} + +# Function to update fstab with new UUIDs +update_fstab_uuids() { + local mount_point="$1" + shift + local uuid_mappings=("$@") + + local fstab_file="$mount_point/etc/fstab" + + if [[ ! -f "$fstab_file" ]]; then + echo "Warning: /etc/fstab not found in mounted system" + return 1 + fi + + echo "Updating /etc/fstab with new UUIDs..." + + # Create backup of original fstab + sudo cp "$fstab_file" "$fstab_file.backup" || { + echo "Warning: Could not create fstab backup" + return 1 + } + + # Apply UUID mappings to fstab + local temp_fstab + temp_fstab=$(mktemp) + + for mapping in "${uuid_mappings[@]}"; do + if [[ "$mapping" =~ ^UUID_MAPPING:([^:]+):([^:]+)$ ]]; then + local old_uuid="${BASH_REMATCH[1]}" + local new_uuid="${BASH_REMATCH[2]}" + + # Replace old UUID with new UUID in fstab + sudo sed "s/UUID=$old_uuid/UUID=$new_uuid/g" "$fstab_file" | sudo tee "$temp_fstab" > /dev/null + sudo cp "$temp_fstab" "$fstab_file" + + echo "Updated fstab: $old_uuid -> $new_uuid" + fi + done + + rm -f "$temp_fstab" + return 0 } # Welcome message @@ -248,6 +343,10 @@ for part in "${TARGET_DEVICE}"*; do fi done +# Regenerate partition UUIDs and labels to prevent boot conflicts with USB +echo "Regenerating partition identifiers..." +mapfile -t uuid_mappings < <(regenerate_partition_identifiers "$TARGET_DEVICE") + # Mount and make final adjustments TEMP_MOUNT="/mnt/stormux_target" sudo mkdir -p "$TEMP_MOUNT" @@ -256,15 +355,15 @@ if sudo mount "$TARGET_ROOT_PART" "$TEMP_MOUNT" 2>/dev/null; then # Remove any USB-specific markers sudo rm -f "$TEMP_MOUNT/home/stormux/.firstboot" 2>/dev/null || true - # Update any USB-specific configurations if needed + # Update /etc/fstab with new UUIDs + if [[ ${#uuid_mappings[@]} -gt 0 ]]; then + update_fstab_uuids "$TEMP_MOUNT" "${uuid_mappings[@]}" + fi sudo umount "$TEMP_MOUNT" fi sudo rmdir "$TEMP_MOUNT" -# Rename all partition labels to prevent boot conflicts with USB -rename_partition_labels "$TARGET_DEVICE" - # Re-enable speech before success message echo "command toggletempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock 2>/dev/null || true