Files
arch-setup/shared/packages-common.sh

267 lines
11 KiB
Bash

#!/usr/bin/env bash
# Paquetes base, sourceados por kde/setup.sh (KDE Plasma es el único DE que
# instala este repo -- ver README "Decisiones").
# AUR-first: lo que está en repos oficiales va por pacman, el resto por paru.
# --- Repos oficiales (pacman) ---------------------------------------------
# Sincronizado con la instalación real de la máquina maestra. Si un paquete no
# está presente aquí, se elimina del instalador.
PACMAN_COMMON=(
# base / shell / CLI moderno
zsh starship fzf ripgrep bat eza btop zoxide fd tldr fastfetch 7zip vim usbutils
# dev toolchain (Podman en vez de Docker + capa de compat)
git base-devel podman podman-docker buildah
nodejs npm python python-pip rustup github-cli
# sync de dotfiles (repo arch-configs) -- en repos oficiales desde 2.x
chezmoi
# apps de escritorio que SÍ están en extra
bitwarden dbeaver gimp syncthing remmina freerdp apostrophe guvcview vlc vlc-plugin-ffmpeg
# diccionarios (corrector ortográfico en apps GTK/Qt)
hunspell-en_us hunspell-es_es
# fuentes / iconos compartidos
ttf-jetbrains-mono-nerd ttf-firacode-nerd noto-fonts noto-fonts-emoji
# red / utilidades base
networkmanager flatpak openssh networkmanager-openvpn openvpn tailscale wpa_supplicant
# audio (PipeWire reemplaza a PulseAudio)
pipewire pipewire-alsa pipewire-jack pipewire-pulse wireplumber libpulse
gst-plugin-pipewire gst-plugins-good gst-plugins-bad gst-libav
# bluetooth: stack + daemon comunes; la UI (bluedevil) se instala explícito
# en kde/setup.sh.
bluez bluez-utils
# hardware: mismo par de máquinas físicas (ver PROJECT_CONTEXT.md)
amd-ucode sof-firmware btrfs-progs zram-generator cpupower power-profiles-daemon
ibus wl-clipboard wmctrl smartmontools
# gvfs backend para montar móviles Android por MTP (Dolphin/Nautilus)
gvfs-mtp
# kernels: último + LTS como fallback ante actualizaciones rotas
linux linux-lts linux-lts-headers linux-firmware
# rollback de actualizaciones atómicas sobre btrfs. inotify-tools es
# dependencia OPCIONAL de grub-btrfs (pacman --needed no la instala sola)
# pero grub-btrfsd la necesita para arrancar -- sin ella el daemon muere
# con exit code 1 y el menú de GRUB nunca ve los snapshots (visto en real
# en Vampire-HM80: paquetes instalados pero grub-btrfsd en 'failed').
snapper snap-pac grub-btrfs inotify-tools
# bootloader (antes hardcodeado en kde/setup.sh, install_bootloader()
# también los instala explícito -- duplicado inofensivo con --needed, pero
# ahora viven aquí para que pkgsync pueda declararlos/protegerlos)
grub efibootmgr
# drivers gráficos open-source (antes hardcodeados en kde/setup.sh;
# mismo hardware físico en ambas máquinas, ver PROJECT_CONTEXT.md)
mesa vulkan-icd-loader vulkan-radeon vulkan-intel intel-media-driver
base
podman-compose
sudo
telegram-desktop
nano
android-tools
lzip
waydroid
glab
opencode
sshfs
isoimagewriter
)
# --- Flatpak ---------------------------------------------------------------
# Aplicaciones que en la máquina maestra están instaladas como Flatpak.
# Antes algunas de estas vivían en AUR (p.ej. heroic-games-launcher-bin,
# karere); ahora se gestionan desde Flathub.
FLATPAK_COMMON=(
com.heroicgameslauncher.hgl
io.github.tobagin.karere
org.gnome.gitlab.cheywood.Buffer
)
# --- AUR (paru) ------------------------------------------------------------
# helpwire: es un .deb; no hay paquete AUR estable -> se convierte con debtap
# (lo gestiona aparte la función install_helpwire de setup.sh).
# claude-code: NO va por AUR (se desincroniza del release real); se instala
# con el instalador nativo oficial, función install_claude_code() más abajo.
AUR_COMMON=(
zen-browser-bin
vscodium-bin
betterbird-bin
onlyoffice-bin
ungoogled-chromium-bin
ventoy-bin
woeusb-ng
bibata-cursor-theme-bin
pamac-all
yay
# herramientas adicionales presentes en la máquina maestra
autofirma debtap gotify-desktop stably-orca-bin
codexbar-cli
metapac
paru
spotifast-bin
)
# --- helpers usados por los setup.sh --------------------------------------
# Ejecuta un paso NO crítico: si falla, lo registra en FAILED_STEPS y
# CONTINÚA en vez de abortar todo el script (set -e no debe tirar una
# instalación de 1h por un mirror caído o un D-Bus que falta en el chroot).
FAILED_STEPS=()
run_optional() {
local desc="$1"; shift
echo ">> $desc"
if ! "$@"; then
FAILED_STEPS+=("$desc")
echo "!! Falló (no crítico, revisa a mano luego): $desc" >&2
fi
}
install_pacman() { pacman -S --needed --noconfirm "$@"; }
# paru se construye como usuario normal (makepkg no corre como root).
# RUSTUP_HOME/CARGO_HOME explícitos: bajo el fakeroot de makepkg, HOME pasa a
# /root y rustup intenta crear /root/.rustup (permission denied, uid real != root).
# rustup respeta RUSTUP_HOME antes que HOME, así que apuntarlo al home del usuario
# arregla los paquetes Rust (p.ej. karere).
as_user() {
sudo -u "$INSTALL_USER" bash -lc \
"export RUSTUP_HOME=\$HOME/.rustup CARGO_HOME=\$HOME/.cargo; $*"
}
bootstrap_paru() {
command -v paru &>/dev/null && return 0
install_pacman git base-devel
# rustup sin toolchain por defecto no expone cargo y rompe el build de paru
as_user 'rustup default stable'
# paru (fuente, no paru-bin): el binario de paru-bin enlaza contra una
# libalpm.so concreta y rompe si la del sistema nuevo difiere; compilar de
# fuente enlaza contra la libalpm instalada.
as_user 'cd /tmp && rm -rf paru && \
git clone https://aur.archlinux.org/paru.git && \
cd paru && makepkg -si --noconfirm'
}
install_aur() {
# Uno a uno: que un PKGBUILD roto (p.ej. karere) no se lleve por delante el
# resto del lote ni el chezmoi init posterior. Avisa de los que fallen.
local p failed=()
for p in "$@"; do
as_user "paru -S --needed --noconfirm $p" || failed+=("$p")
done
((${#failed[@]})) && echo "!! AUR falló (revisa a mano): ${failed[*]}" >&2
return 0
}
# archinstall 4.3 instala el paquete grub pero NO ejecuta grub-install con
# nuestro esquema (/boot ext4 separado + ESP): el sistema queda sin bootloader.
# Lo hacemos aquí (root, dentro del chroot). Idempotente.
install_bootloader() {
install_pacman grub efibootmgr
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB --recheck
grub-mkconfig -o /boot/grub/grub.cfg
}
# HelpWire no tiene AUR: descargar .deb, convertir con debtap, instalar.
install_helpwire() {
local url="https://www.helpwire.app/downloads/operator/linux/helpwire-operator.deb"
install_aur debtap
as_user "sudo debtap -u || true"
# debtap nombra el paquete por el campo Package del .deb ('helpwire', no
# 'helpwire-operator'): convertir en un dir limpio e instalar el único .zst,
# sin depender del nombre exacto.
as_user "d=\$(mktemp -d) && cd \"\$d\" && curl -fsSL -o hw.deb '$url' && \
yes '' | sudo debtap -Q hw.deb && \
sudo pacman -U --noconfirm \"\$d\"/*.pkg.tar.zst && rm -rf \"\$d\""
# debtap deja el .desktop y el icono dentro de /opt y su scriptlet (roto) no
# los registra, así que HelpWire no sale en el menú: lo hacemos a mano.
local hw=/opt/HelpWire/Operator/desktop
install -Dm644 "$hw/helpwire-operator.desktop" /usr/share/applications/helpwire-operator.desktop
install -Dm644 "$hw/helpwire-operator_128.png" /usr/share/icons/hicolor/128x128/apps/helpwire-operator.png
}
# Claude Code: instalador nativo oficial (no AUR, se autoactualiza). Instala
# en ~/.local/share/claude con symlink en ~/.local/bin/claude; no necesita
# root ni flags especiales para correr sin interacción.
install_claude_code() {
as_user "curl -fsSL https://claude.ai/install.sh | bash"
}
# Instala aplicaciones desde Flathub. Se usa para apps que en la máquina
# maestra están como Flatpak, aunque antes estuvieran en AUR.
install_flatpaks() {
echo ">> Instalando Flatpaks comunes..."
if ! command -v flatpak &>/dev/null; then
echo "!! flatpak no está disponible; omitiendo Flatpaks." >&2
return 0
fi
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
local app failed=()
for app in "$@"; do
flatpak install -y --noninteractive flathub "$app" || failed+=("$app")
done
((${#failed[@]})) && echo "!! Flatpak falló (revisa a mano): ${failed[*]}" >&2
return 0
}
# pkgsync: sincroniza qué paquetes hay instalados (pacman+AUR+flatpak) entre
# las dos máquinas, igual que chezmoi sincroniza los dotfiles. Instala metapac
# (motor de diff/aplicación), despliega pkgsync.sh y sus dos servicios de
# usuario, y deja el group file de metapac listo. Ver pkgsync/ en este repo.
install_pkgsync() {
echo ">> Instalando pkgsync (metapac + servicios de sincronización de paquetes)..."
install_aur metapac
as_user "mkdir -p ~/.local/bin ~/.config/systemd/user ~/.config/metapac/groups"
as_user "cp '$REPO_DIR/pkgsync/pkgsync.sh' ~/.local/bin/pkgsync.sh && chmod +x ~/.local/bin/pkgsync.sh"
as_user "cp '$REPO_DIR/pkgsync/systemd/'*.service ~/.config/systemd/user/"
as_user "~/.local/bin/pkgsync.sh bootstrap"
as_user "systemctl --user enable pkgsync-push.service pkgsync-pull.service"
# ya lo activa el run_once de chezmoi, pero por si este DE se instala algún
# día sin chezmoi: idempotente, no hace nada si ya está activo.
loginctl enable-linger "$INSTALL_USER" 2>/dev/null || true
}
# Configura snapper + snap-pac + grub-btrfs para rollback de actualizaciones.
# snap-pac crea snapshots automaticos antes/después de cada 'pacman -Syu'.
# grub-btrfs añade las entradas de snapshots al menú de GRUB.
configure_btrfs_rollback() {
echo ">> Configurando rollback btrfs (snapper + snap-pac + grub-btrfs)..."
# Asegurar que / es btrfs; si no, no hacemos nada.
if ! findmnt -nro FSTYPE / | grep -q btrfs; then
echo "!! Advertencia: / no es btrfs; omitiendo configuración de snapper." >&2
return 0
fi
# Crear configuración de snapper para / si no existe.
if [[ ! -f /etc/snapper/configs/root ]]; then
snapper --no-dbus -c root create-config /
fi
# Solo queremos snapshots automáticos de pacman (snap-pac), no por tiempo.
# Esto evita que se acumulen snapshots innecesarios y se coma espacio.
# ALLOW_GROUPS=wheel: snapper tiene su propia lista de permitidos aparte de
# los permisos de fichero de /.snapshots -- sin esto, "snapper -c root
# list" da "Sin permisos" para cualquiera que no sea root, aunque el chmod
# de abajo esté bien (visto en real en Vampire-HM80).
snapper --no-dbus -c root set-config \
TIMELINE_CREATE=no \
TIMELINE_LIMIT_HOURLY=0 \
TIMELINE_LIMIT_DAILY=0 \
TIMELINE_LIMIT_WEEKLY=0 \
TIMELINE_LIMIT_MONTHLY=0 \
TIMELINE_LIMIT_YEARLY=0 \
NUMBER_LIMIT=10 \
NUMBER_LIMIT_IMPORTANT=10 \
ALLOW_GROUPS=wheel
# Permisos del directorio de snapshots en sí (necesario además de
# ALLOW_GROUPS de arriba, snapper comprueba las dos cosas).
chmod 750 /.snapshots
chown :wheel /.snapshots 2>/dev/null || true
# Habilitar el daemon que regenera el menú de GRUB cuando cambian los snapshots.
systemctl enable grub-btrfsd
# Regenerar menú de GRUB con las entradas de snapshots.
grub-mkconfig -o /boot/grub/grub.cfg
}