#+TITLE: Introducción a Gnu Guix
#+AUTHOR: Camilo Meza Gaete
#+EMAIL: camilo.meza.g@member.fsf.org
* Estructura de la presentación
** Declaración de intenciones
Este escrito tiene por finalidad mostrar las bondades del sistema GNU Guix mediante la
recapitulación histórica, demostración de funciones relevantes, y guiar en el
mantenimiento de la distro. Todo desde el punto de vista de un usuario no técnico de
esta distribución (y gestor de paquetes) avanzada del sistema GNU.
** Partes relevantes
- Historia :: Orígenes y motivaciones del proyecto GNU Guix.
- Funcionamiento :: Detalles de lo que convierte a Guix en un gestor de paquetes
avanzado.
- Mantención :: Peculiaridades a las que dedicar atención para el correcto
funcionamiento del SO.
- Palabras de cierre :: Compromiso y alineamiento con la filosofía de GNU guix.
* Historia
** Antecedentes
*** El origen de Nix
El 18 de Enero del 2006, se publica la tesis doctoral de Eelco Dolstra titulada
[[./IntroGuix/TesisNix.png]]
*** ¿Cómo logra esto Nix?
Todos los programas se dirigen al directorio =/nix/store/= y hay sólo un
directorio por paquete instalado en la tienda.
Por ejemplo:
- =/nix/store/=
+ =./$HASH....emacs-26.3/=
+ =./$OTRO_HASH......texlive-20190410/=
+ =./$TERCER_HASH......stumpwm-19.11/=
*** Esto permite
La *tienda* es un directorio inmutable, y sólo puede ser intervenido por el gestor de
paquetes /nix/. Así, tenemos un sistema con componentes declarados antes de su
instalación.
Además, el hecho de que tengan una serie numérica para diferenciar cada directorio,
permite que más de una versión para un mismo programa esté en el sistema.
*** Entonces
Todo el sistema son enlaces simbólicos a los programas que están en la *tienda*.
** ¿Funcional?
*** El gestor de paquetes Nix
=dpkg= funciona bien, pero cuando se habla de funcional en este contexto se está haciendo referencia tanto al paradigma de programación, como al concepto matemático del que proviene.
*** Un ejemplo
El conjunto de dependencias de las coreutils de GNU:
[[./IntroGuix/coreutils.png]]
*** Así
El lenguaje Nix para estas definiciones puede resultar hostil, por lo que un grupo de
hackers de GNU decide utilizar la implementación Guile de Scheme.
*** En resumen
El modelo de gestión de software que implementa Nix es /funcional/ porque:
+ Las instalaciones son *inmutables*.
+ Las compilaciones/instalaciones *no tienen efectos secundarios*.
+ Construcción y despliegue de software :: llamar a la función *build*.
+ La tienda :: almacenamiento de los resultados de llamar a las funciones.
+ Recolección de basura
** GNU Guix
*** Primeros objetivos
En 2012, Ludovic Cortés presenta GNU Guix, con la idea de conservar el modelo de construcción y despliegue que hizo, pero:
- Utilizando una implementación de scheme llamada Guile para los paquetes.
- Agregando hackers de GNU.
[[./IntroGuix/Guix.png]]
Logo de Guix por sirgazil (CC-BY-SA 4.0)
*** Propósitos de la distribución
En la presentación, titulada "Guix, functional package management for the people, and
for GNU?" se establecen 2 motivaciones:
+ Tener un gestor de paquetes funcional.
+ Utilizarlo para construir una distribución GNU/Linux (u otras variantes de GNU) que
sea 100% software libre, práctica, y que esté fuertemente integrada con el sistema
GNU.
*** Propósitos de la distribución
Eventualmente, se presentarían 2 nuevos objetivos centrales:
+ Que las usuarias de la distribución puedan tener una Libertad 1 facilitada por Guile.
+ Tener ambientes de desarrollo reproducibles (desde la declaración de la configuración, hasta el bootstrap de inicio).
*** ¿Cómo lograría esto?
Un sistema completamente declarativo, utilizando Guile scheme.
#+BEGIN_SRC scheme
(define-public hello
(package
(name "hello")
(version "2.10")
(source (origin
(method url-fetch)
(uri (string-append "mirror://gnu/hello/hello-" version
".tar.gz"))
(sha256
(base32
"0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
(build-system gnu-build-system)
(synopsis "Hello, GNU world: An example GNU package")
(description
"GNU Hello prints the message \"Hello, world!\" and then exits. It
serves as an example of standard GNU coding practices. As such, it supports
command-line arguments, multiple languages, and so on.")
(home-page "https://www.gnu.org/software/hello/")
(license gpl3+)))
#+END_SRC
* Funcionamiento
** Configuración declarativa
*** Todo en un archivo
Uno de los puntos fuertes de Nix y Guix es que se puede tener la /declaración/ del
Sistema Operativo completo en sólo un archivo que incluya los servicios, los paquetes, y las configuraciones de éstos a utilizar por la usuaria.
*** Veamos un ejemplo propio
#+BEGIN_SRC scheme
(use-modules (gnu))
(use-service-modules desktop networking ssh xorg)
(use-package-modules wm)
(define %paquetes-base-de-todo-el-sistema
(map specification->package
'("los"
"paquetes")))
(operating-system
(locale "en_US.utf8")
(timezone "America/Santiago")
(keyboard-layout (keyboard-layout "latam"))
(host-name "LibreBadger")
(users "declaración de usuario"
%base-user-accounts))
(packages %paquetes-base-de-todo-el-sistema)
(services
(append
(list (service gnome-desktop-service-type)
(service openssh-service-type)
(set-xorg-configuration
(xorg-configuration
(keyboard-layout keyboard-layout))))
%desktop-services))
(bootloader
(bootloader-configuration
(bootloader grub-efi-bootloader)
(target "/boot/efi")
(keyboard-layout keyboard-layout)))
(swap-devices (list "/dev/sda2"))
(file-systems
(cons* (file-system
(mount-point "/boot/efi")
(device (uuid "12-chachacha" 'fat32))
(type "vfat"))
(file-system
(mount-point "/")
(device
(uuid "34-ChaChaCha"
'ext4))
(type "ext4"))
%base-file-systems))
#+END_SRC
*** Desmenucemos esa configuración
Este archivo de configuración declara 4 partes importantes:
- Las usuarias
- Los paquetes
- El conjunto de servicios
- Cargador de arranque
*** Declaración de usuarias
Dentro de la definición de sistema operativo, podremos encontrar una declaración
de la función *users*, en la que debemos incluir toda la información de las usuarias
que deseemos agregar, como en el siguiente ejemplo:
*** Declaración de usuarias
#+BEGIN_SRC scheme
(users (cons (user-account
(name "4lib")
(comment "gupo en que no todos quieren reconocerser fan de Emacs")
(group "users")
(supplementary-groups '("todos" "los" "grupos" "necesarios")))
%base-user-accounts))
#+END_SRC
*** Declaración de paquetes base
La función *packages* invocará a /guix package install/ con permisos de root, y todos
los paquetes que se declaren como argumentos de esta función quedarán instalados y
disponibles para todas las usuarias.
*** Declaración de paquetes base
#+BEGIN_SRC scheme
(packages
(append
(specification->package "stumpwm-with-slynk")
%base-packages))
#+END_SRC
*** Declaración de paquetes base
Pero, para que nuestra configuración quede más legible podemos hacer uso de las siguientes funciones de guile:
#+BEGIN_SRC scheme
(define %paquetes-utilidades
(map specification->package
'("nss-certs"
"git")))
(define %paquetes-wm
(map specification->package
'("stumpwm-with-slynk"
"sbcl")))
;; En la declaración de SO
(packages
(append
%paquetes-utilidades
%paquetes-wm
%base-packages))
#+END_SRC
*** Declaración de los servicios
Si quisieramos tener ssh, xorg, o un gestor de sesiones configurados, debemos incluir
esas definiciones en la declaración del SO.
#+BEGIN_SRC scheme
(services
(append
(list (service gnome-desktop-service-type)
(service openssh-service-type)
(set-xorg-configuration
(xorg-configuration
(keyboard-layout keyboard-layout))))
%desktop-services))
#+END_SRC
*** Declaración de servicios
Pero también hay otros servicios, como uno para utilizar software de bloqueo de pantallas (como i3lock). O de BBDD, impresión, gestión de contraseñas con PAM, etc.
*** Declaración del cargador de arranque
Finalmente, también se puede gestionar el cargador de arranque desde la declaración
del SO:
#+BEGIN_SRC scheme
(bootloader
(bootloader-configuration
(bootloader grub-efi-bootloader)
(target "/boot/efi")
(keyboard-layout keyboard-layout)))
#+END_SRC
*** Actualización del sistema
Una vez se tiene la declaración deseada, se debe hacer /guix pull/ seguido de un
=sudo guix system reconfigure /ruta/archivo/config.scm=
** Definición de paquetes
Cuando queremos controlar más finamente el paquete a nuestro antojo, podemos ir a ver su
definición, en este caso trabajaremos con GNU-hello:
*** Definición de GNU-hello
Un paquete en guix estará definido también en guile scheme, donde se utilizan las funciones *name*, *version*, *source*, *build-system*, *synopsis*, *description*, *homepage*, y *license*:
#+BEGIN_SRC scheme
(define-public hello
(package
(name "hello")
(version "2.10")
(source (origin
(method url-fetch)
(uri (string-append "mirror://gnu/hello/hello-" version
".tar.gz"))
(sha256
(base32
"0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
(build-system gnu-build-system)
(synopsis "Hello, GNU world: An example GNU package")
(description
"GNU Hello prints the message \"Hello, world!\" and then exits. It
serves as an example of standard GNU coding practices. As such, it supports
command-line arguments, multiple languages, and so on.")
(home-page "https://www.gnu.org/software/hello/")
(license gpl3+)))
#+END_SRC
** Gestión de paquetes
Los paquetes no sólo pueden ser gestionados mediante la reconfiguración del sistema, sino también por cada usuaria del equipo sin necesidad de privilegios especiales.
Esta gestión se puede hacer mediante las herramientas
+ Guix package
+ Guix pull
+ Guix describe
+ Guix gc
*** Guix package
Guix package es la opción responsable de la instalación, actualización, remoción, y búsqueda de los paquetes.
#+BEGIN_SRC shell
guix package -i paquete
guix install paquete
#+END_SRC
*** Guix package
#+BEGIN_SRC shell
guix package -r paquete2
guix remove paquete2
#+END_SRC
*** Guix package
#+BEGIN_SRC shell
guix package -r paquete2 -i paquete
#+END_SRC
*** Guix package
#+BEGIN_SRC shell
guix package -u . --do-not-upgrade texlive
guix upgrade paquete3
#+END_SRC
*** Guix package
#+BEGIN_SRC shell
guix package -s expresion-regular
guix search expresion-regular
#+END_SRC
*** Guix package
Además, todos los cambios que se hagan mediante guix package quedarán registrados como
/generaciones/, por lo que la usuaria siempre puede volver a un estado anterior invocando =guix package --roll-back= o =guix package -S patrón-de-generaciones=
*** Guix pull
Guix obtiene sus paquetes desde un repositorio en git, por lo que para sincronizar los
cambios y nuevos paquetes de los commit, se debe hacer /guix pull/.
*** Guix pull
El que esté en git significará que puedo tener una máquina apuntando a un determinado commit de la línea de tiempo del desarrollo de Guix, esta capacidad se llama =guix time-machine=.
*** Guix describe
Cuando no recuerdes la versión de guix que estás corriendo, o los canales que estás
usando, puedes invocar =guix describe= para obtener esa información.
*** Guix gc
Un potencial problema de guix es que la tienda ocupa más espacio (ya que los elementos que están en la tienda no se borran hasta que se solicita explícitamente).
*** Guix gc
Este resguardo de las generaciones ayuda a que guix sea prácticamente muy estable (si algo deja de funcionar en una actualización, puedo volver a un estado anterior). La única forma de reclamar ese espacio es invocando =guix gc=
#+BEGIN_SRC shell
guix package --delete-generations=patrón
guix gc --collect-garbage
guix gc -d patrón
#+END_SRC
*** Guix channels
Se pueden utilizar repositorios de git que no sean el de GNU para la actualización del
sistema. Así como también repositorios git que tengan definidos paquetes para guix.
*** Guix channels
A esta función se le denomina /canales/, y le da flexibilidad y personalización a GNU
guix. Para utilizarla basta con editar el archivo =.config/guix/channels.scm= y luego correr =guix pull=.
*** Guix channels
#+BEGIN_SRC scheme
;; Cambiar el repo para todos los paquetes.
(list (channel
(name 'guix)
(url "https://example.org/my-guix.git")
(branch "super-hacks")))
;; Añadir un repo que define nuevos paquetes.
(cons (channel
(name 'my-personal-packages)
(url "https://example.org/personal-packages.git"))
%default-channels)
#+END_SRC
** Desarrollo
*** Guix environment
Para generar ambientes de desarrollo, guix incluye una herramienta llamada /environments/ que incluyen el conjunto de paquetes que la usuaria necesite para trabajar (siendo similar a los contenedores de docker).
=guix environment paquete=
* Mantención
Ya conocemos las herramientas, propongamos entonces una forma de mantener nuestro sistema
al día.
** Archivo de configuración
Es recomendable mantenerlo en control de versiones, para así poder recuperarlo en caso
de cambiar nuestro equipo, pero además:
+ Hacer =guix pull= con una regularidad semanal
+ hacer =sudo guix system reconfigure= al menos una vez cada semana (dependiendo de la versión del kernel que estén ratreando).
** Guix packages
Utilizarlo sólo cuando se quiera tener un paquete que no necesite permisos especiales, o
que no estemos seguros de su necesidad a largo plazo.
+ =guix search= y =guix upgrade= serán las herramientas con mayor utilización
+ =guix install= y =guix remove= verán un uso moderado para quienes acostumbren otra distribuciónGNU/Linux.
* Palabras de cierre
** Agradecimientos
A todo el equipo de hackers de GNU, y obviamente a Ludovic Cortés y Ricardo Wurmus, sin quienes esta maravillosa distro no existe.
A 4libertades Chile, por ser tan ñoños como para interesarse en este tema.