El push de pkgsync del 2026-08-27 17:41 (8575c4f) commiteó el fichero ya vacío en disco (algo lo truncó a 0 bytes fuera de pkgsync entre las 16:10 y las 17:41 de ese día -- causa exacta desconocida), porque cmd_push() no validaba que el parcheo de arrays hubiera funcionado antes de commitear. Restaurado desdef3cdc35(último commit bueno, mismo día 07:37). El siguiente push recapturará los 3 semanas de drift real desde entonces. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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. Escritorio: KDE Plasma (único, sin GNOME — ver "Decisiones").
arch-setup/
├── kde/ archinstall-config.json + setup.sh (KDE Plasma, sddm)
├── shared/ packages-common.sh (paquetes base)
├── 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
./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:
archinstall --silentconkde/archinstall-config.json→ instala base + KDE Plasma en/mnt.- Se copia a sí mismo a
/mnty entra enarch-chroot. - Dentro del chroot: crea el usuario, instala paquetes (pacman + AUR vía
paru), aplica el aspecto y ejecutachezmoi init --applyapuntando agitea.josevi.ovh/josevi/arch-configs. - 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 porparu(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 + tema global Layan + iconos Tela + cursores
Layan-white (paquetes AUR, ver
kde/setup.sh) + splash Animated-Abstract-Cube; look capturado del portátil conshared/capture-kde.shy aplicado vía chezmoi. - Solo KDE Plasma, sin GNOME: hubo variante GNOME en su día; se retiró porque en el uso real KDE es lo único que se usa. Si algún día hiciera falta recuperarla, está en el historial de git (commit anterior a la retirada).
- Dotfiles en repo separado, paquetes en este mismo: no es arbitrario.
arch-configs(dotfiles, víachezmoi) es datos personales sin relación con "cómo se instala nada" — cambian solos a su ritmo, generan un historial de commits ruidoso ("Auto-backup HH:MM"), ysetup.shlos aplica como último paso, con el sistema ya funcionando; sichezmoi init --applyfallara entero, igualmente tendrías un Arch+KDE arrancable, solo que sin tu toque personal.shared/packages-common.shen cambio es el instalador, no datos sobre el instalador:kde/setup.shhacesourcede ese fichero y pasa sus arrays directamente ainstall_pacman/install_aur— el array es el input directo de la lógica de instalación, en el mismo repo que arranca todo el proceso. Meterlo en un repo aparte obligaría asetup.sha clonar un segundo repo a medias de la instalación (dentro del chroot, sin red garantizada) solo para saber qué paquetes meter. La línea divisoria es "cómo se construye el sistema" (este repo, código + su propia lista de paquetes) vs "qué aspecto tiene una vez construido" (arch-configs, datos personales) —pkgsync(sección más abajo) vive aquí porque edita exactamente el mismo array que el instalador consume.
⚠️ Antes de lanzar
-
Se borran los discos FIJOS detectados (
"wipe": true). Los discos se autodetectan filtrando por NO removible (RM=0enlsblk), así el USB instalador (sdb, removible) queda fuera y da igual que el SSD seanvme0n1o un SSD PCIe que enumera comosda. Esquema:- Disco de sistema (1º; nvme si existe) → ESP 512M (
/boot/efi) +/bootext4 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,/homevive dentro del/btrfs. - swap = zram (
"swap": true), sin partición de swap - bootloader GRUB (coherente con ESP en
/boot/efi+/bootseparado)
Verifica con
lsblkqué discos quedan como fijos. Para forzar nombres a mano:gen-disk-config.py BASE.json /dev/SISTEMA [/dev/HOME]. - Disco de sistema (1º; nvme si existe) → ESP 512M (
-
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, abrearchinstallinteractivo, define los discos a mano, usa Save configuration y pega ese bloquedisk_configen 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). KDE añade kcalc/ark/spectacle/kdeconnect/kinfocenter
(inline en kde/setup.sh, ver "Decisiones").
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(disparapkgsync-push.serviceal cerrar sesión, mismo trucoExecStopen unidad oneshotRemainAfterExitque usachezmoi-shutdown-sync.service): captura el inventario real (pacman -Qqen/pacman -Qqem/flatpak list), parchea los tres arrays depackages-common.shen un clon dedicado (~/.local/share/arch-setup) — añade lo nuevo, quita lo que ya no está instalado — y hacegit commit+pushbest-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(disparapkgsync-pull.serviceal iniciar sesión):git pullbest-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): corremetapac sync(instala lo que falte) ymetapac 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 depullpero solo imprime, sin tocar git ni notificar.pkgsync incoming: commits nuevos enorigin/mainaún no traídos (equivalente agit log HEAD..origin/main).pkgsync log [--patch]: historial legible de cambios de paquetes (git logsobreshared/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 hardcodeados enkde/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 kde/setup.sh justo después de
chezmoi init --apply.
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.