pacdef como gestor declarativo de paquetes en Arch (y Arch-like)

Mi problema con los gestores de paquetes es que a menudo instalo cosas para probarlas, esas cosas instalan dependencias, luego me olvido de borrar los paquetes una vez me dejan de hacer falta, o si lo hago, estas se olvidan de borrar sus dependencias y dejan un sistema con paquetes innecesarios y con suciedad acumulada.

Una de mis formas favoritas de resolver esto, es con herramientas que permitan declarar en un archivo la lista de paquetes que debe tener un ordenador. Como un package.json o un requirements.txt, pero a nivel sistema operativo. En cualquier caso, un mantenimiento periódico de la lista de paquetes es altamente recomendable para mantener limpio el ordenador, bajo mi punto de vista.

Mantenimiento de paquetes con Pacman

En Arch y otras distros donde se usa Pacman, existen formas de mantener la gestión de paquetes al punto. El artículo de consejos de Pacman en la wiki de Arch es un buen lugar para aprender más sobre esto.

A modo de resumen, un paquete en Arch se puede instalar en dos modos: modo explícito o modo dependencia. Un paquete se instala en modo explícito cuando se instala porque lo has pedido. Por ejemplo, hacer pacman -S firefox provoca que Firefox se instale en modo explícito, porque lo has puesto. Un paquete se instala en modo dependencia cuando se instala porque lo pide otro paquete. Por ejemplo, si Firefox depende de cuatro paquetes, esos paquetes (y todos los que dependan transitivamente) se instalan en modo dependencia1.

Puedes listar todos los paquetes de tu máquina con pacman -Q, pero puedes listar todos los paquetes de tu máquina instalados de forma explícita (es decir, porque has hecho pacman -S foo o similares) usando pacman -Qe2. Por lo tanto, una forma de tener bajo control tus paquetes es hacer pacman -Qe, encontrar lo que ya no te haga falta, y desinstalarlo con pacman -Rns. (Combinando los parámetros ns, Pacman borra dependencias y archivos de configuración que ya no hagan falta.)

Igualmente, a veces pueden quedar paquetes huérfanos. Son paquetes que no pediste, pero que se instalaron como dependencia. Si Pacman detecta que ningún paquete de los explícitos pide esa dependencia, se marca como paquete huérfano, porque realmente ni tú lo quieres, ni otro paquete lo quieres. Puedes listar este tipo de paquetes con pacman -Qdt, que es combinar pacman -Qd (para listar todas las dependencias), con la opción -t, que reporta sólo aquellos paquetes no dependientes de otro paquete. Nadie debería sentir que le falta nada por desinstalar los paquetes que reporte esa búsqueda.

Archivos declarativos con pacdef

Lo que nos lleva a pacdef. Es un gestor de paquetes declarativo multi-backend. Esto quiere decir que además de para Pacman, que es mi caso de uso, también puede hacer esto mismo con APT, Flatpak, Python y Rust. Gestor de paquetes declarativo quiere decir que sustituimos el estilo imperativo de «ordenar que se instalen y desinstalen cosas a golpe de pacman -S y pacman -R» por «indicar una lista de paquetes que deben estar instalados, y dejar que pacdef se busque la vida para poner lo que falte o quitar lo que sobre».

Se instala fácilmente desde AUR. Una vez instalado, su interfaz de control es el programa pacdef. La jerarquía de Pacdef es un poco confusa al principio así que voy a intentar explicarlo de forma simple, y empezando por abajo en vez de por arriba.

En Pacdef, tu objetivo es instalar paquetes. Creo que lo tenemos claro. Es una lista donde indicas que quieres tener un kernel Linux, ripgrep, zsh, neovim, Firefox, GIMP… Cuando ejecutas pacdef, procesa tu lista de paquetes, y quita de tu sistema lo que no esté en la lista, e instala lo que sí esté pero no tengas.

Sin embargo, para que no sea un cristo organizarlo, pacdef tiene secciones. En tu lista, la agrupas por gestor de paquetes. Por ejemplo, en la sección APT pondrías paquetes que quieres que pacdef instale a golpe de apt-get, como linux-image-6.1.0-17-amd64 o ripgrep. En la sección Flatpak indicas lo que quieres que instale mediante flatpak desde Flathub, como com.valvesoftware.Steam o com.visualstudio.code. Sin más, como digo Pacdef soporta varios backends así que los llama uno tras otro con lo que haya en cada sección. Yo aquí sólo tengo como grupo Arch porque lo apuesto todo a Pacman y AUR.

Pero además, para que no sea una lista muy larga, o para hacerlo más flexible, en Pacdef creas grupos. Un grupo es un archivo que contiene secciones. Esto te permite, si quieres, dividir tus listas de paquetes en varios archivos separados, para colocarlos por categoría. Podrías tener un único grupo con todo metido a presión, o podrías organizarlos. En mi caso, por ejemplo, sí uso varios grupos:

  • system: paquetes de sistema como base, linux-lts, man-db… en fin, cosas que se supone que hacen que el ordenador funcione.
  • terminal: paquetes de terminal como vim, tmux, ripgrep… si bien el ordenador no va a dejar de encender porque falten esos paquetes, sentiría que me faltan programas si no estuviesen ahí
  • deskapps: paquetes gráficos como firefox, bitwarden, zathura… lo mismo pero para interfaz gráfica.

En mis dotfiles está mi lista de grupos, donde hay más todavía, porque queda un paso esencial para entender por qué he empezado a usar Pacdef: qué hacer cuando hay varios ordenadores.

Pacdef en un entorno multiordenador

Una de las cosas importantes de Pacdef es que crear un grupo no lo activa automáticamente. Una vez que tengas creado tu grupo como un archivo de texto que se guarda en $XDG_CONFIG_HOME/pacdef, tienes que importarlo para marcarlo como activo.

Esta distinción es crucial: en mis dotfiles puedo tener grupos que estén activos y grupos que estén inactivos. Los grupos inactivos se ignoran, y sólo se tienen en cuenta los grupos activos. Y precisamente esa forma de activar o ignorar grupos es la que me permite mantener distintos perfiles, para cada ordenador.

Por ejemplo, en mis dotfiles hay un grupo llamado archstation, que representa mi torre. En este grupo tengo paquetes como nvidia-lts o amd-ucode, que tienen sentido de tener instalados en mi torre porque tiene hardware NVIDIA y AMD. Y a la vez, tengo otro grupo llamado frankenmac, que representa al Mac-Frankenstein. Aquí hay paquetes como broadcom-wl-dkms, intel-ucode o brightnessctl, que tienen sentido de usar para este ordenador concreto.

En cada ordenador, activo los grupos que sólo tienen sentido en ese instante. Por ejemplo, el grupo de la torre sólo está activo en la torre, porque no necesito instalar el driver de NVIDIA en un ordenador que no usa NVIDIA, ni el subsistema wifi en un ordenador de sobremesa. Similarmente, algunos paquetes que sólo tienen sentido en un ordenador concreto, como OBS Studio, viven en el grupo de ese ordenador.

En otros casos, puedo fabricar perfiles para representar un entorno de escritorio concreto. Ahora mismo hay un grupo llamado i3 que representa todo lo que uso con i3: i3-wm, polybar, xorg-server, dunst… Podría tener un grupo separado que represente a Hyprland y donde estén sus paquetes además de Wayland. Así, si quiero cambiar de entorno de escritorio y no quiero mezclar paquetes, puedo desactivar un grupo, activar el otro, y pacdef se ocupa de reordenar los paquetes.

Tengo un grupo llamado Pipewire y un grupo llamado PulseAudio. La razón por la que esto ocurre es porque casi todos mis ordenadores usan Pipewire, excepto el que uso para emitir, ya que de momento mi micrófono USB no se lleva bien con Pipewire; razón por la que solamente ese ordenador usa PulseAudio. Para no andar duplicando la lista de paquetes de Pipewire en todas mis máquinas, decidí separarlo a un grupo aparte, y en el perfil de cada ordenador activo el grupo con el sistema de audio correcto a mis necesidades.

Limitaciones de pacdef

De momento estoy contento con Pacdef, pero sí me he encontrado algunas limitaciones, aunque seguro que se pueden solucionar con más grupos.

Si bien es una pasada tener exactamente los mismos programas de escritorio en la torre y en el FrankenMac, de momento no he podido mover mi Pinebook Pro a Pacdef. La razón es que cuando se instala Arch Linux en un Pinebook Pro, se está usando un kernel diferente al estándar, que no es ni el mismo paquete. En el Pinebook Pro ahora mismo estoy usando el paquete linux-eos-arm, proporcionado por EndeavourOS, que realmente es un reensamblado del trabajo previamente hecho por ManjaroARM.

Probablemente esto se resuelva haciendo más grupos: system, system-amd64 y system-arm64, y reorganizando los paquetes para que linux-lts vaya a system-amd64 y linux-eos-arm a system-arm64. Seguiremos informando y si un día me atrevo a mirarlo, reportaré por aquí a ver qué tal.

  1. Pongamos que haces pacman -S firefox dbus. El paquete dbus es una dependencia de firefox. Sin embargo, como ahora lo estás pidiendo de forma directa, tienes que tener en cuenta que se va a instalar como explícito, no como dependencia. ↩︎
  2. Una cosa que puede ocurrir es que instales un paquete hecho en Python, pero no «instales» Python, en el sentido de que nunca has hecho pacman -S python pero sí has hecho pacman -S ansible y por eso ha instalado Python. Python aquí estará instalado como dependencia, y puede sorprender no encontrarlo en la lista. Por suerte, en casos puntuales como estos, podemos cambiar la razón entre explícito y dependencia, como explica la wiki. ↩︎

Un comentario en «pacdef como gestor declarativo de paquetes en Arch (y Arch-like)»

Los comentarios están cerrados.