# 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](INSTALL.md). ## Uso (desde el USB live de Arch, como root) ```bash 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, DavMail, 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](https://github.com/ripytide/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 `/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 `/setup.sh` justo después de `chezmoi init --apply`. **Las dos máquinas ya instaladas** (retrofit, sin reinstalar): ```bash 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.