From 617831c25aa7101187b085c7a83f354d21b7f3a6 Mon Sep 17 00:00:00 2001 From: Jacob Schantli Date: Tue, 6 Oct 2026 18:50:40 -0700 Subject: [PATCH] V1.2 - Improved script --- postinstall.sh | 239 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 165 insertions(+), 74 deletions(-) diff --git a/postinstall.sh b/postinstall.sh index 3fa79aa..d933afa 100644 --- a/postinstall.sh +++ b/postinstall.sh @@ -2,7 +2,14 @@ # Post install script for Fedora # Author: Jacob Schantli -# Version: 1.0 +# Version: 1.1 + +# Make a pipeline fail if any command in it fails. Without this, +# `curl ... | bash` reports success even when the download fails. +set -o pipefail + +# Steps that failed during this run (shown in the summary at the end) +FAILED_STEPS=() # ----------------------------------------------------------------------------- # Global Configuration @@ -14,8 +21,6 @@ DNF_PACKAGES=( "lutris" "btop" "fastfetch" - "jstest-gtk" - "yaru-icon-theme" "distrobox" "pipx" "bash-completion" @@ -25,7 +30,6 @@ DNF_PACKAGES=( "unzip" "git" "fzf" - "syncthing" "mpv" "fuse" "fuse-libs" @@ -43,20 +47,18 @@ FLATPAK_PACKAGES=( "com.vysp3r.ProtonPlus" "io.missioncenter.MissionCenter" "io.github.peazip.PeaZip" - "app.devsuite.Ptyxis" + #"app.devsuite.Ptyxis" "re.sonny.Junction" - "com.github.rafostar.Clapper" + #"com.github.rafostar.Clapper" "io.github.flattool.Ignition" "io.github.swordpuffin.rewaita" "page.tesk.Refine" - "io.gitlab.adhami3310.Converter" + #"io.gitlab.adhami3310.Converter" "com.usebottles.bottles" "com.bambulab.BambuStudio" "com.collaboraoffice.Office" - "io.github.martchus.syncthingtray" "io.github.kolunmi.Bazaar" "com.fastmail.Fastmail" - "org.waywallen.waywallen" ) GNOME_EXTENSIONS=( @@ -67,9 +69,9 @@ GNOME_EXTENSIONS=( "caffeine@patapon.info" "dynamic-music-pill@andbal" "gnome-fuzzy-app-search@gnome-shell-extensions.Czarlie.gitlab.com" - "IP-Finder@linxgem33.com" - "lan-ip-address@mrhuber.com" - "update-extension@purejava.org" + #"IP-Finder@linxgem33.com" + #"lan-ip-address@mrhuber.com" + #"update-extension@purejava.org" "user-theme@gnome-shell-extensions.gcampax.github.com" "gnome-wallpaper-engine@gjs.com.zip" ) @@ -102,10 +104,12 @@ command_exists() { # Check if the last command was successful check_status() { - if [ $? -eq 0 ]; then + local status=$? + if [ $status -eq 0 ]; then log_info "$1 successful." else log_error "$1 failed." + FAILED_STEPS+=("$1") # If the second argument is "critical", exit the script if [ "$2" == "critical" ]; then log_error "Critical error encountered. Exiting." @@ -162,7 +166,7 @@ install_fonts() { sudo dnf upgrade --refresh -y check_status "System upgrade" "critical" - sudo dnf install -y curl cabextract xorg-x11-font-utils fontconfig wget + sudo dnf install -y curl cabextract xorg-x11-font-utils fontconfig wget unzip check_status "Prerequisites installation" "critical" log_info "Installing Microsoft Core Fonts..." @@ -175,7 +179,8 @@ install_fonts() { log_info "Installing Meslo Nerd Font..." FONT_NAME="MesloLGS Nerd Font Mono" - if fc-list :family | grep -iq "$FONT_NAME"; then + # Redirect instead of `grep -q` so fc-list isn't killed by SIGPIPE (pipefail) + if fc-list :family | grep -i "$FONT_NAME" > /dev/null; then log_info "Font '$FONT_NAME' is already installed." else log_info "Installing font '$FONT_NAME'..." @@ -183,14 +188,13 @@ install_fonts() { FONT_DIR="$HOME/.local/share/fonts" TEMP_DIR=$(mktemp -d) - wget -O "$TEMP_DIR/$FONT_NAME.zip" "$FONT_URL" - unzip "$TEMP_DIR/$FONT_NAME.zip" -d "$TEMP_DIR" - mkdir -p "$FONT_DIR/$FONT_NAME" - mv "$TEMP_DIR"/*.ttf "$FONT_DIR/$FONT_NAME/" - - fc-cache -fv - rm -rf "$TEMP_DIR" + wget -q -O "$TEMP_DIR/Meslo.zip" "$FONT_URL" \ + && unzip -q "$TEMP_DIR/Meslo.zip" -d "$TEMP_DIR" \ + && mkdir -p "$FONT_DIR/$FONT_NAME" \ + && mv "$TEMP_DIR"/*.ttf "$FONT_DIR/$FONT_NAME/" \ + && fc-cache -f "$FONT_DIR" check_status "Meslo Nerd Font installation" "non-critical" + rm -rf "$TEMP_DIR" fi } @@ -214,11 +218,6 @@ install_software() { sudo dnf install -y "${DNF_PACKAGES[@]}" check_status "DNF packages installation" "non-critical" - # Install Gemini CLI - log_info "Installing gemini-cli via Homebrew..." - npm i @google/gemini-cli - check_status "gemini-cli installation" "non-critical" - # Ensure flatpak is set up if ! command -v flatpak &> /dev/null; then log_info "Flatpak not found. Installing..." @@ -230,23 +229,34 @@ install_software() { check_status "Flathub remote add" "non-critical" log_info "Installing Flatpak packages..." - for app in "${FLATPAK_PACKAGES[@]}"; do - log_info "Installing $app..." - flatpak install flathub -y "$app" - check_status "Flatpak $app" "non-critical" - done + # One transaction is much faster (single dependency resolution, shared + # runtimes downloaded once). If it fails, retry one-by-one so a single + # bad app ID doesn't block the rest. + if flatpak install flathub -y "${FLATPAK_PACKAGES[@]}"; then + log_info "Flatpak packages installation successful." + else + log_warn "Batch Flatpak install failed. Retrying apps individually..." + for app in "${FLATPAK_PACKAGES[@]}"; do + log_info "Installing $app..." + flatpak install flathub -y "$app" + check_status "Flatpak $app" "non-critical" + done + fi log_info "----------------------------------------------------" - log_info "Installing Homebrew and Gemini CLI" + log_info "Installing Homebrew" log_info "----------------------------------------------------" - # Install Homebrew - if command_exists brew; then + # Install Homebrew (also detect it when it isn't on PATH yet) + if command_exists brew || [ -x "/home/linuxbrew/.linuxbrew/bin/brew" ]; then log_info "Homebrew already installed." else log_info "Installing Homebrew..." - # Using NONINTERACTIVE=1 to avoid prompts during brew install - NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + # Download first so a failed download isn't reported as success. + # NONINTERACTIVE=1 avoids prompts during brew install. + BREW_INSTALLER=$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh) \ + && NONINTERACTIVE=1 /bin/bash -c "$BREW_INSTALLER" + check_status "Homebrew installation" "non-critical" # Add brew to path for the current session if [ -d "/home/linuxbrew/.linuxbrew/bin" ]; then @@ -254,8 +264,6 @@ install_software() { elif [ -d "$HOME/.linuxbrew/bin" ]; then eval "$($HOME/.linuxbrew/bin/brew shellenv)" fi - - check_status "Homebrew installation" "non-critical" fi } @@ -304,6 +312,17 @@ install_cachyos() { log_info "Installing CachyOS kernel" log_info "----------------------------------------------------" + # kernel-cachyos is built for x86-64-v3 CPUs. Ask before installing it on + # an older CPU, where the new (default) boot entry may not start. + if ! /lib64/ld-linux-x86-64.so.2 --help 2>/dev/null | grep 'x86-64-v3 (supported' > /dev/null; then + log_warn "Your CPU does not appear to support x86-64-v3, which kernel-cachyos targets." + read -p "Install the CachyOS kernel anyway? [y/N]: " reply + if [[ ! "$reply" =~ ^[Yy]$ ]]; then + log_info "Skipping CachyOS kernel." + return + fi + fi + sudo dnf copr enable -y bieszczaders/kernel-cachyos check_status "Enabling CachyOS Copr" "non-critical" @@ -320,6 +339,42 @@ install_cachyos() { check_status "CachyOS addons installation" "non-critical" } +install_p03() { + log_info "----------------------------------------------------" + log_info "Installing P03 kernel" + log_info "----------------------------------------------------" + + # The default kernel-p03 build needs x86-64-v3 and won't boot on older + # CPUs. Those get the x86-64-v2 build (kernel-p03-gcc) instead. + if /lib64/ld-linux-x86-64.so.2 --help 2>/dev/null | grep 'x86-64-v3 (supported' > /dev/null; then + P03_PACKAGE="kernel-p03" + else + log_warn "CPU lacks x86-64-v3 support. Installing the x86-64-v2 build (kernel-p03-gcc)." + P03_PACKAGE="kernel-p03-gcc" + fi + + sudo dnf copr enable -y catpieleaf/kernel-p03 + check_status "Enabling P03 Copr" "non-critical" + + sudo dnf install -y "$P03_PACKAGE" + check_status "P03 kernel installation" "non-critical" + + # P03 signs itself with a locally generated key. With Secure Boot on, that + # key must be enrolled or the kernel won't boot. + if mokutil --sb-state 2>/dev/null | grep -i 'SecureBoot enabled' > /dev/null; then + log_info "Secure Boot is enabled. Enrolling the P03 signing key..." + log_info "Pick a one-time password. On the next boot, choose 'Enroll MOK' and enter it." + sudo mokutil --import /etc/kernel/certs/p03-kernel/mok.der + check_status "P03 Secure Boot key enrollment" "non-critical" + fi + + if rpm -q kernel-cachyos > /dev/null 2>&1; then + log_warn "The CachyOS kernel is also installed. The newest kernel usually boots by default;" + log_warn "pick the other one from the boot menu if needed." + fi + log_warn "P03 uses the PRJC scheduler, so sched_ext schedulers (scx-scheds) likely won't work on it." +} + install_linuxtoys() { log_info "----------------------------------------------------" log_info "Installing LinuxToys" @@ -338,7 +393,8 @@ install_shell_env() { log_info "Starship already installed." else log_info "Installing Starship..." - curl -sSL https://starship.rs/install.sh | sudo sh + # -y skips the installer's confirmation prompt + curl -sSL https://starship.rs/install.sh | sudo sh -s -- -y check_status "Starship installation" "non-critical" fi @@ -421,7 +477,12 @@ install_topgrade() { log_info "Installing Topgrade" log_info "----------------------------------------------------" - sudo dnf copr enable lilay/topgrade + if command_exists topgrade; then + log_info "Topgrade already installed." + return + fi + + sudo dnf copr enable -y lilay/topgrade check_status "Enabling Topgrade" "non-critical" sudo dnf install -y topgrade @@ -457,6 +518,7 @@ install_gnome_extensions() { # Install (using the direct binary path) "$EXTENSION_TOOL" install "$extension" + check_status "GNOME Extension $extension" "non-critical" # Attempt to enable the extension (in case it's installed but disabled) log_info "Ensuring $extension is enabled..." @@ -464,11 +526,28 @@ install_gnome_extensions() { # Prompt user to press Enter to continue read -p "Press Enter to continue (if a popup appeared, confirm it first)..." - - check_status "GNOME Extension $extension" "non-critical" done } +install_antigravity() { + log_info "----------------------------------------------------" + log_info "Installing Antigravity App, IDE, and CLI" + log_info "----------------------------------------------------" + + log_info "Installing Antigravity CLI..." + curl -fsSL https://antigravity.google/cli/install.sh | bash + check_status "Antigravity CLI installation" "non-critical" + + log_info "Installing Antigravity App and IDE..." + # Community installer (opensnap). It downloads Google's official tarballs + # into /opt and adds launchers. It needs python3, and nautilus-python + # enables its "Open in Antigravity IDE" entry in Files. + sudo dnf install -y python3 nautilus-python + INSTALLER_URL="https://opensnap.github.io/antigravity/install.sh" + curl -fsSL "$INSTALLER_URL" | sudo -E env ANTIGRAVITY_LINUX_INSTALLER_URL="$INSTALLER_URL" bash -s -- --all + check_status "Antigravity App and IDE installation" "non-critical" +} + # ----------------------------------------------------------------------------- # Main Menu # ----------------------------------------------------------------------------- @@ -492,9 +571,45 @@ show_menu() { echo "12. Install 1Password" echo "13. Install Windscribe" echo "14. Install Topgrade" + echo "15. Install Antigravity App, IDE, and CLI" + echo "16. Install P03 Kernel (experimental, not in Install Everything)" echo "0. Exit" echo "====================================================" - read -p "Enter your choice [0-14]: " choice + read -p "Enter your choice [0-16]: " choice +} + +# Run every installation step. Pass "skip_kernel" to leave out CachyOS. +run_all() { + optimize_dnf + install_fonts + install_repos + install_software + install_discord + install_1password + install_Windscribe + install_topgrade + if [ "$1" != "skip_kernel" ]; then + install_cachyos + fi + install_linuxtoys + install_shell_env + install_gnome_extensions + install_antigravity +} + +# Show which steps failed during this run, if any +print_summary() { + log_info "----------------------------------------------------" + if [ ${#FAILED_STEPS[@]} -eq 0 ]; then + log_info "Post-install script completed successfully!" + else + log_warn "Post-install script finished with ${#FAILED_STEPS[@]} failed step(s):" + for step in "${FAILED_STEPS[@]}"; do + log_warn " - $step" + done + fi + log_info "Please restart your shell or run 'source ~/.bashrc' to see the changes." + log_info "----------------------------------------------------" } # ----------------------------------------------------------------------------- @@ -512,35 +627,11 @@ while true; do show_menu case $choice in 1) - optimize_dnf - install_fonts - install_repos - install_software - install_discord - install_1password - install_Windscribe - install_topgrade - install_cachyos - install_linuxtoys - install_shell_env - install_gnome_extensions - log_info "All tasks completed successfully!" + run_all break ;; 2) - optimize_dnf - install_fonts - install_repos - install_software - install_discord - install_1password - install_Windscribe - install_topgrade - # install_cachyos (Skipped) - install_linuxtoys - install_shell_env - install_gnome_extensions - log_info "All tasks (except kernel) completed successfully!" + run_all skip_kernel break ;; 3) optimize_dnf ;; @@ -555,8 +646,11 @@ while true; do 12) install_1password ;; 13) install_Windscribe ;; 14) install_topgrade ;; + 15) install_antigravity ;; + 16) install_p03 ;; 0) log_info "Exiting..." + print_summary exit 0 ;; *) @@ -570,7 +664,4 @@ while true; do fi done -log_info "----------------------------------------------------" -log_info "Post-install script completed successfully!" -log_info "Please restart your shell or run 'source ~/.bashrc' to see the changes." -log_info "----------------------------------------------------" \ No newline at end of file +print_summary \ No newline at end of file