Files
arch-setup/README.md
T
Josevi d1077f0547 Arregla bug de trap RETURN en pkgsync.sh y quita mención stale a DavMail
trap RETURN persiste entre retornos de función en bash, no solo el de la
función que lo puso: al volver de compute_diff/cmd_push/cmd_audit hacia
arriba en la pila, volvía a dispararse sobre un $work ya fuera de scope
('work: variable sin asignar' bajo set -u). Cambiado a rm -rf explícito en
cada punto de salida.

DavMail se desinstaló del sistema; ya no debía aparecer en la lista de apps.
2026-08-18 11:08:54 +02:00

9.2 KiB

arch-setup

Instalación automatizada de Arch Linux para mis dos máquinas (hardware idéntico), en un único comando desde el USB live, sin reiniciar entre la base y la config. Dos variantes de escritorio: GNOME y KDE Plasma.

arch-setup/
├── gnome/    archinstall-config.json + setup.sh   (GNOME, gdm)
├── kde/      archinstall-config.json + setup.sh   (KDE Plasma, sddm)
├── shared/   packages-common.sh                   (paquetes comunes a ambos)
├── pkgsync/  pkgsync.sh + systemd/                (sync de paquetes entre máquinas)
└── README.md

Procedimiento paso a paso completo en INSTALL.md.

Uso (desde el USB live de Arch, como root)

pacman -Sy --noconfirm git
git clone https://gitea.josevi.ovh/josevi/arch-setup
cd arch-setup
./gnome/setup.sh      # o  ./kde/setup.sh

El script te pide: usuario a crear, token de Gitea (para el repo arch-configs privado), nombre y email de git. Después, sin más intervención:

  1. archinstall --silent con el JSON de la variante → instala base + escritorio en /mnt.
  2. Se copia a sí mismo a /mnt y entra en arch-chroot.
  3. Dentro del chroot: crea el usuario, instala paquetes (pacman + AUR vía paru), aplica el aspecto y ejecuta chezmoi init --apply apuntando a gitea.josevi.ovh/josevi/arch-configs.
  4. Quitas el USB y reboot. El tema se aplica en el primer login gráfico.

Decisiones

  • AUR-first: lo que está en repos oficiales va por pacman; el resto por paru (se bootstrapea solo). Sin Flatpak salvo que lo añadas.
  • Contenedores: Podman + podman-docker (capa de compat), no Docker.
  • Navegador: Zen Browser. También ungoogled-chromium.
  • Aspecto: JetBrains Mono Nerd en ambos escritorios; el resto diverge por DE. GNOME: Catppuccin Mocha + iconos Papirus-Dark + Dash-to-Dock y extensiones (AppIndicator, Blur my Shell, Caffeine, Clipboard Indicator, Vitals). KDE: tema global Layan + iconos Tela + cursores Layan-white (paquetes AUR, ver kde/setup.sh) + splash Animated-Abstract-Cube; look capturado del portátil con shared/capture-kde.sh y aplicado vía chezmoi.
  • Dotfiles: chezmoi apuntando a un repo separado (arch-configs).

⚠️ Antes de lanzar

  • Se borran los discos FIJOS detectados ("wipe": true). Los discos se autodetectan filtrando por NO removible (RM=0 en lsblk), así el USB instalador (sdb, removible) queda fuera y da igual que el SSD sea nvme0n1 o un SSD PCIe que enumera como sda. Esquema:

    • Disco de sistema (1º; nvme si existe) → ESP 512M (/boot/efi) + /boot ext4 1G + / btrfs (resto)
    • 2º disco fijo (si hay) → ext4 todo el disco en /home (ojo: destruye el disco de datos). Si solo hay 1 disco, /home vive dentro del / btrfs.
    • swap = zram ("swap": true), sin partición de swap
    • bootloader GRUB (coherente con ESP en /boot/efi + /boot separado)

    Verifica con lsblk qué discos quedan como fijos. Para forzar nombres a mano: gen-disk-config.py BASE.json /dev/SISTEMA [/dev/HOME].

  • Esquema de particiones de archinstall cambia entre versiones, y el particionado manual multi-disco es lo más sensible. Si archinstall se queja del disk_config, abre archinstall interactivo, define los discos a mano, usa Save configuration y pega ese bloque disk_config en el JSON.

  • Zona horaria/teclado fijados a Europe/Madrid / us-acentos. Ajusta si hace falta.

Apps que se instalan

Comunes (shared/packages-common.sh): zsh+starship+CLI moderno, git+base-devel, Podman, nodejs/python/rustup, Bitwarden, DBeaver, Obsidian, GIMP, Syncthing, Remmina+FreeRDP, Apostrophe, guvcview, KVIrc, Zen Browser, VSCode, Betterbird, OnlyOffice, Spotify, ungoogled-chromium, Karere, HelpWire (vía .deb→debtap). GNOME añade gnome-calculator/tweaks; KDE añade kcalc/ark/spectacle/kdeconnect/kinfocenter.

pkgsync — sincronización de paquetes entre las dos máquinas

Mismo patrón que chezmoi para los dotfiles (chezmoi-boot-sync.service / chezmoi-shutdown-sync.service en el repo arch-configs), pero para qué paquetes hay instalados de verdad (pacman + AUR + flatpak). Fuente de verdad: los arrays PACMAN_COMMON/AUR_COMMON/FLATPAK_COMMON de shared/packages-common.sh. Motor de diff/aplicación: metapac (AUR), con paru como backend para que cubra repos oficiales y AUR en una sola pasada.

pkgsync/
├── pkgsync.sh            CLI: bootstrap/push/pull/diff/apply/log/incoming/audit
└── systemd/
    ├── pkgsync-push.service   captura+sube al cerrar sesión/apagar
    └── pkgsync-pull.service   trae+compara al iniciar sesión (nunca instala/desinstala)

Cómo funciona

  • pkgsync push (dispara pkgsync-push.service al cerrar sesión, mismo truco ExecStop en unidad oneshot RemainAfterExit que usa chezmoi-shutdown-sync.service): captura el inventario real (pacman -Qqen/pacman -Qqem/flatpak list), parchea los tres arrays de packages-common.sh en un clon dedicado (~/.local/share/arch-setup) — añade lo nuevo, quita lo que ya no está instalado — y hace git commit + push best-effort con timeout, igual que chezmoi. El parcheo respeta los comentarios de agrupación existentes: lo nuevo se añade en un bloque marcador al final del array, listo para que lo reorganices a mano cuando quieras.
  • pkgsync pull (dispara pkgsync-pull.service al iniciar sesión): git pull best-effort con timeout (nunca bloquea el login), calcula el diff entre lo declarado y lo instalado, y solo notifica (notificación de escritorio + detalle en ~/.local/share/pkgsync.log). No instala ni desinstala nada por sí solo.
  • pkgsync apply (manual, cuando tú decidas revisar el diff): corre metapac sync (instala lo que falte) y metapac clean (desinstala lo sobrante), ambos con la confirmación interactiva nativa de metapac — nunca se pasa --no-confirm, así que siempre ves y confirmas cada borrado antes de que ocurra.
  • pkgsync diff: igual que el cálculo de pull pero solo imprime, sin tocar git ni notificar.
  • pkgsync incoming: commits nuevos en origin/main aún no traídos (equivalente a git log HEAD..origin/main).
  • pkgsync log [--patch]: historial legible de cambios de paquetes (git log sobre shared/packages-common.sh).
  • pkgsync audit: paquetes instalados localmente que no están declarados en ningún array ni en el override local — drift no capturado. Nota: los paquetes específicos de KDE/GNOME hardcodeados en <de>/setup.sh (plasma-desktop, sddm, temas AUR, etc.) siempre van a aparecer aquí — no viven en los arrays por diseño, no es drift real.

Paquetes críticos (nunca se borran automáticamente)

pkgsync.sh lleva una lista CRITICAL_PACKAGES hardcodeada (kernel, bootloader, drivers gráficos, red de rollback btrfs, y todo lo que sea soporte de hardware: CPU/energía, audio, bluetooth, red física, USB) que es independiente del array — sobrevive aunque el array se corrompa por error humano. Dos capas de protección: push nunca la quita del array aunque detecte que un paquete crítico no está instalado localmente (solo avisa en el log), y el group file que se genera para metapac siempre fuerza la unión con esta lista, así que metapac clean nunca puede verlos como "no declarados". La lista completa está al principio de pkgsync.sh.

Overrides locales (divergencias legítimas entre máquinas)

~/.config/metapac/groups/overrides.local.toml — mismo formato de group file que usa metapac. No vive en ningún repo git (fuera de arch-setup, en ~/.config/metapac/), así que ya queda fuera del control de versiones sin necesidad de nada más. pkgsync lo lee solo para no proponer esos paquetes como "nuevos" en push ni marcarlos como drift en audit; nunca lo escribe ni lo sobreescribe. bootstrap deja un scaffold comentado si no existe.

Instalación

Máquinas nuevas: automático, install_pkgsync() (en packages-common.sh) se llama desde <de>/setup.sh justo después de chezmoi init --apply.

Las dos máquinas ya instaladas (retrofit, sin reinstalar):

mkdir -p ~/.local/bin ~/.config/systemd/user
git clone https://gitea.josevi.ovh/josevi/arch-setup.git ~/.local/share/arch-setup
cp ~/.local/share/arch-setup/pkgsync/pkgsync.sh ~/.local/bin/ && chmod +x ~/.local/bin/pkgsync.sh
cp ~/.local/share/arch-setup/pkgsync/systemd/*.service ~/.config/systemd/user/
pkgsync.sh bootstrap
systemctl --user enable --now pkgsync-push.service pkgsync-pull.service

loginctl enable-linger ya está activo por el run_once de chezmoi, no hace falta repetirlo. Verifica una vez con flatpak list --columns=installation,application que tu instalación de Flatpak es system (si es user, cambia FLATPAK_INSTALLATION al principio de pkgsync.sh).

Auto-instalar sin supervisión (opt-in, apagado por defecto)

pkgsync pull respeta la variable de entorno PKGSYNC_AUTO_INSTALL=1: si está activada, corre metapac sync --no-confirm justo después de calcular el diff (solo instala lo que falte). Nunca toca metapac clean — los borrados siguen requiriendo pkgsync apply manual, pase lo que pase.