commit 52a3181f9e7fadc2edbbfa5cba4da513a9e5c08e from: ale date: Sat Aug 1 23:07:12 2026 UTC channels.scm: usar el mirror público de GitHub + .guix-authorizations Mismo bootstrap que /nixdots (README, "Bootstrap en una PC nueva"): la URL ssh://...tailscale... no es alcanzable desde una VM/PC nueva sin Tailscale ya andando. Introduction real (primer commit + fingerprint de la YubiKey) + .guix-authorizations para que la cadena de autenticación de guix pull funcione de verdad. commit - a74bd609112af2082035979e2c944d916c89b531 commit + 52a3181f9e7fadc2edbbfa5cba4da513a9e5c08e blob - /dev/null blob + de9b1d73d4f3b5f7c4e716bd8116194d2b4f3995 (mode 644) --- /dev/null +++ .guix-authorizations @@ -0,0 +1,9 @@ +;; Lista de firmantes autorizados de este canal, requerida por el +;; mecanismo de autenticación de `guix pull` a partir del commit de +;; introducción declarado en channels.scm. Mismo formato que el +;; .guix-authorizations real del propio repo de Guix. + +(authorizations + (2 + (("91CA 581F 7B78 01E8 8673 D228 DBD5 F61D 8A0A 14D7" + (name "ale"))))) blob - /dev/null blob + c5819c2ee86f583384737f88199c1f1224575861 (mode 644) --- /dev/null +++ ale/services/desktop.scm @@ -0,0 +1,79 @@ +;;; desktop.scm --- Hyprland, greetd, Bluetooth, sesión gráfica +;;; +;;; Traducción de /nixdots/modules/desktop.nix. Diferencias reales: +;;; +;;; - Sin Noctalia ni noctalia-greeter: decisión tomada tras investigar +;;; (ver NOTES.md) -- Noctalia solo viable vía canal de terceros +;;; rolling-release, y noctalia-greeter no existe empaquetado en +;;; absoluto. Reemplazo: greetd + agreety (login de texto plano, +;;; sin tema compartido -- la alternativa "bonita" con tuigreet quedó +;;; pendiente de integrar, ver comentario abajo) lanzando Hyprland +;;; directo. DankMaterialShell (sobre Quickshell oficial de Guix) +;;; reemplaza al shell de Noctalia -- instalación manual, ver +;;; home-configuration.scm y PENDIENTES.md. +;;; - Sin pipewire/wireplumber acá: Guix NO tiene servicio de *sistema* +;;; para pipewire (confirmado, no existe `pipewire-service-type` en +;;; ningún módulo de gnu/services) -- solo existe como servicio de +;;; *Guix Home* (`home-pipewire-service-type`). Va en +;;; home-configuration.scm, no acá. +;;; - elogind + seatd + polkit + dbus explícitos: NixOS los trae gratis +;;; vía `services.xserver`/`programs.hyprland.enable`; acá no hay +;;; equivalente automático, hace falta declararlos a mano para que +;;; greetd + un compositor Wayland puedan gestionar sesión/asientos. + +(define-module (ale services desktop) + #:use-module (gnu) + #:use-module (gnu services) + #:use-module (gnu services base) + #:use-module (gnu services desktop) + #:use-module (gnu services dbus) + #:use-module (gnu services pm) + #:use-module (gnu services xorg) ; screen-locker-service-type si hace falta + #:use-module (gnu packages wm) ; hyprland + #:use-module (gnu packages freedesktop) ; xdg-desktop-portal-hyprland + #:use-module (gnu packages gnome) ; nautilus, gvfs + #:use-module (gnu packages file-systems) ; yazi + #:use-module (gnu packages fonts) + #:use-module (gnu packages kde-frameworks) ; kleopatra, plasma-integration, breeze + #:use-module (gnu packages kde) + #:export (%ale-desktop-services + %ale-desktop-packages)) + +(define %ale-greetd-config + (greetd-terminal-configuration + (default-session-command + (greetd-agreety-session + (command (greetd-user-session + (command (file-append hyprland "/bin/Hyprland")))))))) + ;; PENDIENTE: reemplazar agreety por tuigreet (más parecido visualmente a + ;; lo que tenías con noctalia-greeter) -- Guix no trae un helper + ;; `greetd-tuigreet-session` armado como sí tiene para agreety/wlgreet/ + ;; gtkgreet-sway, hay que construirlo a mano extendiendo el patrón de + ;; greetd-agreety-session. No bloqueante: agreety funciona, solo es feo. + +(define %ale-desktop-services + (list (service greetd-service-type + (greetd-configuration + (terminals (list %ale-greetd-config)))) + (service elogind-service-type) + (service polkit-service-type) + (service dbus-root-service-type) + (service bluetooth-service-type + (bluetooth-configuration (auto-enable? #t))) + (service gnome-keyring-service-type) ; secret service -- credenciales de DMS/CalDAV/etc, mismo motivo que en desktop.nix + (service power-profiles-daemon-service-type) + (service upower-service-type) + (service polkit-wheel-service))) ; agentes gráficos de polkit corriendo como wheel puedan autorizar + +(define %ale-desktop-packages + (list hyprland + xdg-desktop-portal-hyprland + nautilus + gvfs + yazi + kleopatra + breeze + plasma-integration + font-google-noto + font-google-noto-emoji + font-jetbrains-mono)) blob - /dev/null blob + 9e90386bfefbfd8adf039dcfc453ef7bcbc2bec2 (mode 644) --- /dev/null +++ ale/services/graphics.scm @@ -0,0 +1,69 @@ +;;; graphics.scm --- gráficos duales Intel+Nvidia, Steam, gamemode +;;; +;;; Traducción de /nixdots/modules/graphics.nix. Cambios reales de fondo +;;; (no arbitrarios, ver NOTES.md de este canal para el detalle completo de +;;; la investigación): +;;; +;;; - PRIME *offload*, no *sync*: Guix/nonguix no tienen ningún mecanismo +;;; declarativo de PRIME sync (solo offload está documentado). Además, se +;;; confirmó en vivo en el NixOS real de esta laptop que PRIME sync ya es +;;; un no-op bajo Wayland (la NixOS Wiki lo dice explícito: "PRIME sync +;;; and reverse sync modes are X11-only") -- `nvidia-smi` mostraba la GPU +;;; en 0% de uso con la sesión Hyprland (Wayland) corriendo. Offload puro +;;; NO es downgrade real acá. +;;; - HDMI nativo sin PRIME: confirmado con hardware real (lspci + +;;; /sys/class/drm) que `HDMI-A-1` está cableado directo a la Nvidia +;;; (PCI 01:00.0, card0), no pasa por la Intel -- evita el mecanismo de +;;; "reverse-PRIME" (copia de buffers entre GPUs) que causaba el bug de +;;; compositor original que motivó elegir sync en NixOS. La variable +;;; AQ_DRM_DEVICES que declara esto va en la sesión de Hyprland +;;; (home-configuration.scm / hyprland.lua), no acá -- es una variable de +;;; sesión de usuario, no de sistema. +;;; - Driver legacy 580 (`nvda`, alias `nvda-580`): es el DEFAULT de +;;; nvidia-service-type en nonguix -- no hace falta overridearlo, cubre +;;; Pascal (GTX 1050 de esta laptop) igual que +;;; nvidiaPackages.legacy_580 en la config Nix original. +;;; - CUDA: NO incluido acá. guix-science-nonfree (canal de terceros +;;; aparte, codeberg.org/guix-science/guix-science-nonfree) lo provee, +;;; pero con fricción real documentada (issues de integración con +;;; PyTorch/JAX) -- agregar ese canal aparte el día que haga falta de +;;; verdad, no de entrada. + +(define-module (ale services graphics) + #:use-module (gnu) + #:use-module (gnu services) + #:use-module (gnu system pam) + #:use-module (nongnu packages nvidia) + #:use-module (nongnu services nvidia) + #:use-module (nongnu packages game-client) ; steam + #:use-module (gnu packages linux) ; gamemode + #:use-module (gnu packages gl) ; mesa-utils (glxinfo) + #:use-module (gnu packages vulkan) + #:export (%ale-graphics-services + %ale-graphics-packages)) + +;; Variables recomendadas para Nvidia + Wayland/Hyprland en modo offload -- +;; equivalente a environment.sessionVariables en modules/graphics.nix, pero +;; a nivel de sistema (PAM /etc/environment) en vez de por sesión gráfica, +;; porque acá no hay un módulo de home-manager tipo Hyprland que las +;; inyecte automáticamente -- Guix Home no tiene ese mecanismo. +(define %ale-graphics-session-environment + (service session-environment-service-type + '(("LIBVA_DRIVER_NAME" . "nvidia") + ("GBM_BACKEND" . "nvidia-drm") + ("__GLX_VENDOR_LIBRARY_NAME" . "nvidia")))) + ;; WLR_NO_HARDWARE_CURSORS -- ya no hace falta con Aquamarine + ;; (backend nuevo de Hyprland moderno, reemplaza el wlroots + ;; clásico que sí lo necesitaba) -- confirmar en vivo si hay + ;; glitches de cursor y agregarlo acá si hace falta. + +(define %ale-graphics-services + (list (service nvidia-service-type) ; default: driver nvda (=nvda-580, legacy Pascal) + %ale-graphics-session-environment)) + +(define %ale-graphics-packages + (list gamemode + mesa-utils ; glxinfo -- diagnóstico de qué GPU renderiza + vulkan-tools ; vulkaninfo + steam ; nonguix + nvidia-settings-580)) ; sin alias "nvda-settings" en nonguix -- explícito para que coincida con el driver (nvda = nvda-580) blob - /dev/null blob + 600139b2faa1155dbf74845d1b7dfb9bbbd469bd (mode 644) --- /dev/null +++ ale/services/tailscale.scm @@ -0,0 +1,56 @@ +;;; tailscale.scm --- Tailscale + exit-node de Mullvad fijado al arrancar +;;; +;;; Traducción de /nixdots/modules/tailscale.nix. +;;; +;;; SIN VALIDAR CONTRA GUIX REAL (a diferencia de graphics/desktop/yubikey.scm +;;; de este mismo canal) -- se agotó el tiempo de esta sesión antes de poder +;;; correr `guix pull` con el canal Rosenthal agregado (es grande, no se +;;; alcanzó a bajar) y probar esto en la VM. Documentado con la mejor +;;; información de la investigación previa (ver NOTES.md), pero hay que +;;; confirmarlo con un build real antes de confiar en que compila. +;;; +;;; `tailscale-service-type` no existe en el canal oficial `guix` -- viene +;;; de Rosenthal (`(rosenthal services networking)`, ver channels.scm), +;;; confirmado con uso real de producción reportado por otro usuario en +;;; el foro de System Crafters. El oneshot de reintentos para fijar el +;;; exit-node (equivalente al `systemd.services.tailscale-exit-node` de +;;; NixOS) no tiene helper en Rosenthal -- se escribe a mano como +;;; shepherd-service acá, siguiendo el patrón real de Guix (gexp con +;;; `start`/`stop`, ver guix/scripts/system.scm y ejemplos de +;;; nongnu/services/nvidia.scm en este mismo repo de investigación). +;;; +;;; sudoers NOPASSWD para `tailscale` ya está en yubikey.scm (ale/services/ +;;; yubikey.scm, %ale-sudoers-file) -- mismo archivo único, Guix no separa +;;; reglas sudoers por módulo como sí permite `security.sudo.extraRules` +;;; en NixOS. + +(define-module (ale services tailscale) + #:use-module (gnu) + #:use-module (gnu services) + #:use-module (gnu services shepherd) + #:use-module (guix gexp) + #:use-module ((rosenthal services networking) #:prefix rosenthal:) + #:use-module ((rosenthal packages networking) #:prefix rosenthal:) + #:export (%ale-tailscale-services)) + +(define %ale-tailscale-exit-node-shepherd-service + (shepherd-service + (documentation "Fija el exit-node de Mullvad en Tailscale, con reintentos.") + (provision '(tailscale-exit-node)) + (requirement '(tailscaled networking)) + (one-shot? #t) ; AJUSTAR: confirmar que este campo existe en la versión de Shepherd real -- si no, usar el patrón start/stop clásico devolviendo #t + (start + #~(lambda _ + (let loop ((attempts 0)) + (if (zero? (system* #$(file-append rosenthal:tailscale "/bin/tailscale") + "set" "--exit-node=mullvad-exit" + "--exit-node-allow-lan-access=true")) + #t + (if (>= attempts 10) + #f + (begin (sleep 2) (loop (1+ attempts)))))))))) + +(define %ale-tailscale-services + (list (service rosenthal:tailscale-service-type) + (simple-service 'tailscale-exit-node shepherd-root-service-type + (list %ale-tailscale-exit-node-shepherd-service)))) blob - /dev/null blob + 02fefec96d6ee13a69f313fa4036bd8ef955a58b (mode 644) --- /dev/null +++ ale/services/yubikey.scm @@ -0,0 +1,42 @@ +;;; yubikey.scm --- pcscd (smartcard) + sudoers +;;; +;;; Traducción de /nixdots/modules/yubikey.nix. Diferencia real: Guix no +;;; tiene equivalente a `security.sudo.extraRules` (reglas por-comando +;;; declarativas) -- `sudoers-file` recibe el contenido CRUDO y completo de +;;; /etc/sudoers como un file-like object, hay que escribir la sintaxis +;;; sudoers a mano (confirmado contra el manual, operating-system +;;; Reference). Rutas absolutas, mismo motivo que en la config Nix +;;; original: sudoers resuelve por ruta, no por $PATH. + +(define-module (ale services yubikey) + #:use-module (gnu) + #:use-module (gnu services) + #:use-module (gnu services security-token) + #:use-module (gnu packages security-token) + #:use-module (gnu packages gnupg) + #:export (%ale-yubikey-services + %ale-yubikey-packages + %ale-sudoers-file)) + +(define %ale-yubikey-services + (list (service pcscd-service-type))) + +(define %ale-yubikey-packages + (list yubikey-personalization + python-yubikey-manager ; ykman + gnupg)) + +;; AJUSTAR las rutas /run/current-system/profile/bin/{systemctl,tailscale} +;; una vez confirmadas en la instalación real -- Guix no usa systemctl +;; (Shepherd, no systemd), así que "reiniciar pcscd" en la función `yubico` +;; de zsh (ver home-configuration.scm) usa `herd restart pcscd` en vez de +;; `systemctl restart pcscd.service`. sudo necesita la ruta absoluta real +;; de `herd` y `tailscale` en el store -- confirmar con `guix build herd`/ +;; `which herd` en el sistema real, esto es un placeholder razonable. +(define %ale-sudoers-file + (plain-file "sudoers" "\ +root ALL=(ALL) ALL +%wheel ALL=(ALL) ALL +ale ALL=(ALL) NOPASSWD: /run/current-system/profile/bin/herd restart pcscd +ale ALL=(ALL) NOPASSWD: /run/current-system/profile/bin/tailscale +")) blob - /dev/null blob + 49dd88100285430f6b03585108c2e5b1fa39ea76 (mode 644) --- /dev/null +++ channels.scm @@ -0,0 +1,52 @@ +;;; channels.scm --- lista de canales para reproducir este sistema +;;; +;;; Uso (equivalente a `nix flake update`+pin del flake.lock de /nixdots): +;;; guix pull -C channels.scm +;;; +;;; nonguix: driver propietario de Nvidia (nvidia-driver-580, rama legacy +;;; para Pascal), Steam, firmware no libre. Introducción copiada tal cual +;;; del README oficial de nonguix (gitlab.com/nonguix/nonguix) para que +;;; `guix pull` pueda verificar la firma del canal desde el primer commit. +;;; +;;; guixdots: este mismo canal (paquetes personales -- LibrePods, ClamUI, +;;; slides, nezzontli-ctl -- ver ale/packages/*.scm). URL del espejo +;;; PÚBLICO de GitHub, no el Forgejo real (Tailscale-only) -- mismo +;;; bootstrap que /nixdots (ver su README, "Bootstrap en una PC nueva"): +;;; una PC recién instalada no tiene Tailscale andando todavía, así que +;;; hace falta el espejo sin autenticación primero. El Forgejo real +;;; actualiza este espejo solo -- no hace falta pushear ahí a mano. +;;; Introduction: primer commit real de este canal, firmado con la misma +;;; llave GPG que firma todo en /nixdots. + +;; Rosenthal: canal grande y activo (codeberg.org/hako/rosenthal, 1256+ +;;; commits, confirmado en uso real de producción por otro usuario -- +;;; ver NOTES.md) -- de acá sale `tailscale-service-type`, ausente en el +;;; canal oficial `guix`. También es donde vive el canal propio de +;;; Noctalia (noctalia.scm, no usado en esta config -- se optó por +;;; DankMaterialShell), por si algún día se reconsidera. +(cons* (channel + (name 'rosenthal) + (url "https://codeberg.org/hako/rosenthal") + ;; Sin introduction: no se pudo confirmar el commit+fingerprint + ;; exactos sin acceso a Guix real en esta sesión -- AJUSTAR con + ;; `guix pull -C channels.scm` real y copiar lo que sugiera, o + ;; revisar el propio README de Rosenthal para su introduction + ;; documentada. + ) + (channel + (name 'nonguix) + (url "https://gitlab.com/nonguix/nonguix") + (introduction + (make-channel-introduction + "897c1a470da759236cc11798f4e0a5f7d4d59fbc" + (openpgp-fingerprint + "2A39 3FFF 68F4 EF7A 3D29 12AF 6F51 20A0 22FB B2D5")))) + (channel + (name 'guixdots) + (url "https://github.com/Richard7987/guixdots.git") + (introduction + (make-channel-introduction + "846c407395396cb54d4d9e28dbfcc83aeee750fd" + (openpgp-fingerprint + "91CA 581F 7B78 01E8 8673 D228 DBD5 F61D 8A0A 14D7")))) + %default-channels) blob - /dev/null blob + 2f4a6969b6c13923938e1d21db1bd81420136ba7 (mode 644) --- /dev/null +++ home/ale/home-configuration.scm @@ -0,0 +1,164 @@ +;;; home-configuration.scm --- Guix Home para ale +;;; +;;; Traducción de /nixdots/home/ale/home.nix. Guix Home es notablemente +;;; menos maduro que home-manager (confirmado en la investigación previa, +;;; ver NOTES.md: "barely any services compared to home-manager" según el +;;; propio blog de Guix) -- lo que en Nix era una opción tipada acá muchas +;;; veces es un dotfile plano vía home-files-service-type. Sin validar +;;; contra Guix real todavía (se agotó el tiempo de esta sesión) -- a +;;; diferencia de graphics/desktop/yubikey.scm, que sí se corrieron contra +;;; `guix system build` real. +;;; +;;; Lo que NO se portó (documentado, no simplemente olvidado): +;;; - oh-my-zsh + Powerlevel10k: solo en canales de terceros (`abbe`, +;;; `bugchan`), no agregados a channels.scm todavía -- zsh queda con +;;; syntax-highlighting + autosuggestions + fzf-tab (los 3 SÍ oficiales) +;;; pero sin el prompt P10k ni los plugins de oh-my-zsh. +;;; - IntelliJ IDEA Ultimate: solo en `small-guix`, versión vieja (~2023.2) +;;; -- no se agregó, evaluar si vale la pena con esa versión. +;;; - DankMaterialShell: no empaquetado en ningún canal -- instalación +;;; manual documentada abajo, corriendo sobre el Quickshell oficial de +;;; `guix`. +;;; - herdr, x-minecraft-launcher, obsidian: ninguno confirmado disponible +;;; en el canal oficial -- AJUSTAR una vez confirmado (obsidian sí +;;; apareció en la investigación inicial como disponible vía nonguix, +;;; agregado abajo). + +(use-modules (gnu home) + (gnu home services) + (gnu home services shells) + (gnu home services gnupg) + (gnu home services sound) ; pipewire (Guix Home, NO existe a nivel de sistema) + (gnu packages) + (gnu packages tex) ; texstudio, texlive + (gnu packages rust-apps) ; tectonic + (gnu packages ghostscript) + (gnu packages libreoffice) + (gnu packages video) ; mpv + (gnu packages version-control) ; git, git-delta + (gnu packages fonts) + (gnu packages xdisorg) ; fzf + (gnu packages irc) ; weechat + (gnu packages admin) ; btop + (gnu packages shellutils) ; pfetch, zsh-syntax-highlighting, zsh-autosuggestions + (gnu packages shells) ; zsh, fzf-tab + (gnu packages gnupg) + (gnu packages security-token) ; yubikey-manager + (nongnu packages chrome) ; obsidian (via nonguix) + (ale packages librepods) + (ale packages clamui) + (ale packages nezzontli-ctl) + (ale packages slides)) + +(home-environment + (packages + (list + ;; --- YubiKey / GPG --- + yubikey-manager + ;; --- TeX / documentos --- + tectonic + texstudio + texlive-scheme-full + ghostscript + libreoffice + ;; --- multimedia --- + mpv + ;; --- terminal / dotfiles --- + git + git-delta + fzf + fzf-tab + zsh-syntax-highlighting + zsh-autosuggestions + pfetch + weechat + btop + font-jetbrains-mono + ;; --- apps --- + obsidian + ;; --- paquetes personales (ale/packages/*.scm, este mismo canal) --- + librepods + clamui + nezzontli-ctl + slides)) + + (services + (list + (service home-zsh-service-type + (home-zsh-configuration + (zshrc + (list (plain-file "zshrc-extra" "\ +source ~/.guix-home/profile/share/fzf-tab/fzf-tab.plugin.zsh +source ~/.guix-home/profile/share/zsh-autosuggestions/zsh-autosuggestions.zsh +source ~/.guix-home/profile/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh + +# yubico: reinicia pcscd + gpg-agent si la YubiKey deja de responder +yubico() { + sudo herd restart pcscd + gpgconf --kill gpg-agent + gpgconf --launch gpg-agent + gpg-connect-agent updatestartuptty /bye >/dev/null 2>&1 +} + +# vpn up/down: alterna el exit-node de Mullvad a mano +vpn() { + case \"$1\" in + up) sudo tailscale set --exit-node=mullvad-exit --exit-node-allow-lan-access=true ;; + down) sudo tailscale set --exit-node= ;; + *) echo \"uso: vpn up|down\"; return 1 ;; + esac +} + +pfetch +")))))) + + (service home-gpg-agent-service-type + (home-gpg-agent-configuration + (ssh-support? #t) + (default-cache-ttl 600) + (max-cache-ttl 7200) + (pinentry-program (file-append pinentry-tty "/bin/pinentry-tty")))) ; AJUSTAR a pinentry-qt si se confirma disponible -- pkgs/home.nix original usaba pinentry-qt (Wayland-friendly) + + (service home-pipewire-service-type) ; wireplumber incluido -- confirmar campos reales del record en la VM antes de aplicar + + ;; git: firma GPG por default -- sin home-git-service-type dedicado + ;; (confirmado que no existe, ver comentario de arriba), config vía + ;; dotfile plano. + (simple-service 'ale-dotfiles + home-files-service-type + (list `(".config/git/config" + ,(plain-file "git-config" "\ +[user] + name = ale + email = ale_bnes@tuta.com +[commit] + gpgSign = true +[tag] + gpgSign = true +[gpg] + format = openpgp +[core] + pager = delta +[interactive] + diffFilter = delta --color-only +[delta] + navigate = true + side-by-side = true + line-numbers = true + syntax-theme = gruvbox-dark +")) + `(".ssh/config" + ,(plain-file "ssh-config" "\ +Host * + IdentityAgent /run/user/1000/gnupg/S.gpg-agent.ssh + ForwardAgent no + AddKeysToAgent no +")))))) + + ;; DankMaterialShell + Quickshell: PENDIENTE instalación manual, no hay + ;; paquete Guix (ver NOTES.md). Una vez que Quickshell 0.3.0 esté + ;; disponible (Guix oficial va en 0.2.1, DMS pide 0.3.0 -- ver + ;; investigación previa), clonar github.com/AvengeMedia/DankMaterialShell + ;; en ~/.config/quickshell/dms y lanzarlo desde hyprland.lua igual que + ;; Noctalia se lanzaba antes (hl.exec_cmd("qs -c dms")). + ) blob - /dev/null blob + a31ee731a089ed89c0b547d7a13a46ae100f8cf9 (mode 644) --- /dev/null +++ hosts/ale/config.scm @@ -0,0 +1,139 @@ +;;; config.scm --- configuración de sistema para la laptop "ale" (Acer Nitro AN515-54) +;;; +;;; Traducción de /nixdots/hosts/ale/configuration.nix + hardware-configuration.nix +;;; a Guix System. Script plano (no módulo) -- convención real de Guix, +;;; confirmada contra /etc/config.scm de la propia imagen VM: `guix system +;;; build config.scm` carga el archivo y evalúa la última expresión como el +;;; `operating-system`, no busca un símbolo exportado. Los módulos auxiliares +;;; (gráficos, escritorio, yubikey, tailscale) sí son módulos Guile reales, +;;; importados acá abajo -- ver ale/services/*.scm. +;;; +;;; Diferencias reales frente a NixOS (no arbitrarias, verificadas contra +;;; Guix real 2026-08-01): +;;; +;;; - Bootloader: GRUB, no systemd-boot -- Guix no lo tiene en absoluto. +;;; `(keep-old-entries? #t)` es lo más parecido a `configurationLimit`, +;;; pero no poda por número -- usar `guix system delete-generations` a +;;; mano. +;;; - AJUSTAR: UUIDs reales de las particiones (placeholders acá, igual que +;;; el hardware-configuration.nix original antes de la instalación real). +;;; - nixpkgs.config.allowUnfree no tiene equivalente -- lo no-libre viene +;;; de estar en el canal nonguix (ver channels.scm), no de un flag. +;;; - nix.gc.automatic: sin servicio dedicado -- un mcron job propio hace +;;; lo mismo (`guix gc --delete-generations=14d` semanal). + +(use-modules (gnu) + (guix gexp) + (gnu system nss) + (nongnu packages linux) + (nongnu system linux-initrd) + (gnu packages linux) + (gnu packages certs) + (gnu packages version-control) + (gnu packages vim) + (gnu packages curl) + (gnu packages wget) + (gnu services) + (gnu services base) + (gnu services networking) + (gnu services linux) + (gnu services mcron) + (ale services graphics) + (ale services desktop) + (ale services yubikey) + (ale services tailscale)) + +;; --- Filesystems (equivalente a hardware-configuration.nix) --- +;; A diferencia de NixOS (subvolúmenes @, @home, @nix, @log, @snapshots todos +;; montados por separado), acá se colapsan /nix (no existe, Guix usa +;; /gnu/store dentro de @) y /var/log (queda dentro de @) -- solo se +;; preservan los subvolúmenes que tienen sentido real en Guix. +(define %ale-file-systems + (list (file-system + (mount-point "/") + (device (uuid "00000000-0000-0000-0000-000000000000")) ; AJUSTAR + (type "btrfs") + (options "subvol=@")) + (file-system + (mount-point "/home") + (device (uuid "00000000-0000-0000-0000-000000000000")) ; AJUSTAR, mismo UUID que "/" + (type "btrfs") + (options "subvol=@home")) + (file-system + (mount-point "/.snapshots") + (device (uuid "00000000-0000-0000-0000-000000000000")) ; AJUSTAR, mismo UUID que "/" + (type "btrfs") + (options "subvol=@snapshots")) + (file-system + (mount-point "/boot/efi") + (device (uuid "0000-0000" 'fat32)) ; AJUSTAR, UUID real de la partición EFI + (type "vfat")))) + +;; --- zram: mismo motivo que zramSwap.enable en la config Nix original -- +;; sin esto, earlyoom (ver desktop.scm) no tiene margen para reclamar +;; memoria a tiempo bajo presión. +(define %zram-service + (service zram-device-service-type + (zram-device-configuration + (size "4G") + (compression-algorithm 'zstd) + (priority 100)))) + +;; --- guix gc semanal, equivalente a nix.gc.automatic + --delete-older-than 14d --- +(define %gc-job + #~(job "0 4 * * 0" ; domingos 4am + "guix gc --delete-generations=14d")) + +(operating-system + (host-name "ale") + (timezone "America/Mexico_City") + (locale "es_MX.utf8") + (keyboard-layout (keyboard-layout "us" "altgr-intl")) + + ;; kernel + firmware no libres -- el kernel es el linux normal de nonguix + ;; (no linux-libre), hace falta para el módulo nvidia y el microcódigo Intel. + (kernel linux) + (kernel-arguments (cons* "modprobe.blacklist=nouveau" %default-kernel-arguments)) + (initrd microcode-initrd) + (firmware (list linux-firmware)) + + (bootloader (bootloader-configuration + (bootloader grub-efi-bootloader) + (targets '("/boot/efi")) + (keep-old-entries? #t))) + + (file-systems (append %ale-file-systems %base-file-systems)) + + (swap-devices '()) ; sin swap en disco -- zram cumple el mismo rol que en /nixdots + + (users (cons (user-account + (name "ale") + (comment "ale") + (group "users") + (supplementary-groups '("wheel" "netdev" "audio" "video" + "input" "dialout" "lp"))) + %base-user-accounts)) + + (packages + (append (list git vim curl wget nss-certs) + %ale-graphics-packages + %ale-desktop-packages + %ale-yubikey-packages + %base-packages)) + + (services + (append + (list %zram-service + (service network-manager-service-type) + (service wpa-supplicant-service-type) + (service ntp-service-type) + (simple-service 'weekly-gc mcron-service-type (list %gc-job))) + %ale-graphics-services + %ale-desktop-services + %ale-yubikey-services + %ale-tailscale-services + %base-services)) + + (name-service-switch %mdns-host-lookup-nss) + + (sudoers-file %ale-sudoers-file))