From 5d7e2f3290df90d2a916b0f5e0d157114cd3d797 Mon Sep 17 00:00:00 2001 From: Timo Wilken Date: Wed, 22 Nov 2023 23:07:31 +0100 Subject: Unify system declarations for lap and frm --- tw/system.scm | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++---- tw/system/frm.scm | 205 +++------------------------------- tw/system/lap.scm | 321 ++++++----------------------------------------------- 3 files changed, 348 insertions(+), 501 deletions(-) diff --git a/tw/system.scm b/tw/system.scm index 51146eed..5f39f861 100644 --- a/tw/system.scm +++ b/tw/system.scm @@ -6,12 +6,17 @@ #:use-module (gnu system keyboard) #:use-module (guix gexp) #:use-module (tw channels) + #:use-module (tw packages scanner) #:use-module (tw services wireguard)) -(use-package-modules acl admin avahi backup certs curl disk file-systems - golang linux lsof man moreutils python rsync search - shells version-control vpn) -(use-service-modules mcron monitoring networking ssh vpn) +(use-package-modules acl admin android avahi backup certs cups curl disk + docker file-systems gnome golang guile kerberos linux + lsof man moreutils mtools pulseaudio python rsync search + shells tls version-control vpn wm xorg) +(use-service-modules authentication avahi base cups dbus desktop docker + kerberos linux mcron monitoring networking pm shepherd + ssh vpn xorg) + (define-public %base-system-packages (cons* acl acpi age btrfs-progs cpupower curl efibootmgr exfat-utils git @@ -44,7 +49,35 @@ (define-public %ssh-ports '(("lud.twilken.net" . 22022) ("vin.twilken.net" . 22022) - ("pi3.twilken.net" . 51022))) + ("pi3.twilken.net" . 51022) + ("lap.twilken.net" . 22) + ("frm.twilken.net" . 22))) + +(define (tw-openssh-service host-name) + "Configure the SSH server for remote login." + ;; SSH login, allowing access only for me. To give more public keys + ;; access, extend `openssh-service-type'. + (service openssh-service-type + (openssh-configuration + (port-number (assoc-ref %ssh-ports host-name)) + (x11-forwarding? #t) + (permit-root-login #f) + (password-authentication? #f) + (accepted-environment '("LANG" "LC_*")) + (authorized-keys + `(("timo" + ,(local-file "system/files/timo.pub") + ,(local-file "system/files/timo-phone-gpg.pub"))))))) + +(define (tw-login-configuration config) + "Patch the given `login-configuration' to my liking." + (login-configuration + (inherit config) + ;; Delete the annoying message on SSH login. + (motd (plain-file "no-motd" "")) + ;; A blank installation has an empty root password. Let me log in + ;; after `guix system init'! + (allow-empty-passwords? #t))) (export server-wireguard-address) (define* (server-wireguard-address host-name #:optional port #:key (ipv6? #f)) @@ -60,17 +93,7 @@ (define-public (server-base-services host-name) (cons* - ;; SSH login, allowing access only for me. To give more public keys - ;; access, extend `openssh-service-type'. - (service openssh-service-type - (openssh-configuration - (port-number (assoc-ref %ssh-ports host-name)) - (password-authentication? #f) - (accepted-environment '("LANG" "LC_*")) - (authorized-keys - `(("timo" - ,(local-file "system/files/timo.pub") - ,(local-file "system/files/timo-phone-gpg.pub")))))) + (tw-openssh-service host-name) ;; Prometheus node exporter (service prometheus-node-exporter-service-type @@ -89,12 +112,266 @@ (this-host host-name))) (modify-services (append %system-channel-services %base-services) - ;; Delete the annoying message on SSH login. Beware when setting up a new - ;; host, as `allow-empty-passwords' will block login and sudo execution for - ;; all Guix-declared users (as these have no initial password). - (login-service-type + (login-service-type config => (tw-login-configuration config))))) + +(define set-timezone-script + ;; Every time we connect to a network, get our timezone from network geolocation. + ;; https://wiki.archlinux.org/title/System_time + ;; https://wiki.archlinux.org/title/Network_configuration/Wireless#Respecting_the_regulatory_domain + (with-extensions (list guile-json-4 guile-gnutls) ; guile-gnutls needed by (web client) + #~(begin + (use-modules ((srfi srfi-11) #:select (let-values)) + (json) + (web client) + (web response)) + (define api-url "https://ipapi.co/json") + ;; According to the Arch Wiki, when checking for "up" as the second + ;; argument, VPN connections could cause undesired timezone changes. + (when (and (string=? "connectivity-change" (caddr (command-line))) + (string=? "FULL" (getenv "CONNECTIVITY_STATE"))) + (let-values (((response text) (http-get api-url))) + (unless (= 200 (response-code response)) + (error "Got error response to request:" response)) + (let* ((json (json-string->scm text)) + (timezone (assoc-ref json "timezone")) + (zonefile (string-append #$tzdata "/share/zoneinfo/" timezone)) + (regdb-country (assoc-ref json "country_code")) + (error-code + (status:exit-val + ;; Set WiFi regulatory domain to use the correct channels. + (system* #$(file-append iw "/bin/iw") "reg" "set" regdb-country)))) + (format (current-error-port) "Updated WiFi regdomain to ~a: ~a~%" + regdb-country (if (zero? error-code) "success" + (format #f "error ~d" error-code))) + ;; Set local timezone. + (delete-file "/etc/localtime") + (symlink zonefile "/etc/localtime") + (format (current-error-port) + "Updated timezone to ~a: success~%" timezone))))))) + +;; This text is added verbatim to the Xorg config file. +(define touchpad-xorg-config "\ +# see man 4 libinput +Section \"InputClass\" + Identifier \"touchpad\" + Driver \"libinput\" + MatchIsTouchpad \"true\" + + Option \"DisableWhileTyping\" \"true\" + Option \"MiddleEmulation\" \"true\" + Option \"NaturalScrolling\" \"true\" + Option \"HorizontalScrolling\" \"true\" + Option \"ScrollMethod\" \"twofinger\" + Option \"ClickMethod\" \"clickfinger\" + Option \"Tapping\" \"true\" + Option \"TappingDrag\" \"true\" + Option \"TappingDragLock\" \"false\" + Option \"TappingButtonMap\" \"lrm\" +EndSection +") + +(define backlight-udev-rules + ;; The naive approach of GROUP="video", MODE="0664" doesn't seem to work. + ;; https://github.com/haikarainen/light/blob/master/90-backlight.rules + ;; https://github.com/Hummer12007/brightnessctl/blob/master/90-brightnessctl.rules + (udev-rule "90-backlight.rules" "\ +ACTION!=\"remove\", SUBSYSTEM==\"backlight\", GROUP=\"video\", MODE=\"0664\" +ACTION!=\"remove\", SUBSYSTEM==\"leds\", GROUP=\"video\", MODE=\"0664\" +")) + +(define-public %enduser-system-packages + (cons* + cups docker mit-krb5 + pulseaudio + dosfstools mtools ntfs-3g + i3-gaps ; install i3 here so gdm can see its xsession file + ;; We need to install gnome-keyring here so its PAM module is + ;; enabled properly (by its service; see below). + ;; nheko needs gnome-keyring to store secrets (kwallet doesn't do dbus). + gnome-keyring + ;; It's probably easiest to install geoclue system-wide, so it + ;; gets added to `%desktop-services' and redshift can access the + ;; location. + geoclue + %base-system-packages)) + +(export enduser-system-services) +(define* (enduser-system-services + #:key + host-name cores wireless-interface backlight-device + (xorg-extra-modules '()) + (xorg-drivers '())) + + (unless (and (string? host-name) + (number? cores) + (string? wireless-interface) + (string? backlight-device) + (list? xorg-extra-modules) + (list? xorg-drivers)) + (error "Invalid argument type")) + + (define xorg-config + (xorg-configuration + (keyboard-layout %british-keyboard) + (extra-config (list touchpad-xorg-config)) + (modules (append xorg-extra-modules %default-xorg-modules)) + (drivers xorg-drivers))) + + (cons* + (service docker-service-type) + + (service krb5-service-type + (krb5-configuration + (default-realm "CERN.CH") + (rdns? #f) + (realms (list (krb5-realm + (name "CERN.CH") + (default-domain "cern.ch") + (kdc "cerndc.cern.ch")))))) + + (service thermald-service-type + (thermald-configuration + (adaptive? #t))) + + (service earlyoom-service-type + (earlyoom-configuration)) ; TODO: configure at least `avoid-regexp' + + (set-xorg-configuration xorg-config) + + ;; Install i3lock as a setuid binary, so it can talk to PAM. + (service screen-locker-service-type + (screen-locker-configuration + (name "i3lock") + (program (file-append i3lock "/bin/i3lock")))) + + ;; Allow anyone in the "video" group to set the display's brightness. + ;; Run `udevadm info -q all /sys/class/backlight/*' to see properties. + (udev-rules-service 'backlight backlight-udev-rules #:groups '("video")) + ;; According to "info '(guix) Base Services'", the above should + ;; have a `#:groups '("video")', but that group is already + ;; declared as a supplementary group for my user and guix warns + ;; that it's declared twice. + + (simple-service 'xbacklight-services shepherd-root-service-type + (list + (shepherd-service + (documentation "Set laptop screen backlight on boot.") + (provision '(backlight)) + (one-shot? #t) + (start #~(make-forkexec-constructor + (list #$(program-file "backlight-setter" + (let ((sys-directory (string-append "/sys/class/backlight/" backlight-device))) + #~(begin + (use-modules ((ice-9 textual-ports) #:select (get-string-all)) + ((srfi srfi-26) #:select (cut))) + (define brightness-file #$(string-append sys-directory "/brightness")) + (define max-brightness-file #$(string-append sys-directory "/max_brightness")) + ;; These files don't exist right after startup, so wait for them to appear. + (while (not (and (file-exists? max-brightness-file) + (file-exists? brightness-file))) + (format (current-error-port) "Waiting for /sys files to appear...~%") + (sleep 1)) + (define max-brightness + (call-with-input-file max-brightness-file get-string-all)) + (call-with-output-file brightness-file + (cut display max-brightness <>))))))))))) + + ;; gnome-keyring is not in `%desktop-services' by default, + ;; but needs to be there to add itself to /etc/pam.d/. + ;; If using a DM other than GDM, add it to `pam-services' in + ;; `gnome-keyring-configuration' (see its docs). + (service gnome-keyring-service-type) + + (udev-rules-service 'android android-udev-rules #:groups '("adbusers")) + + (service cups-service-type + (cups-configuration + (web-interface? #t) + (default-shared? #f) + ;; See info '(guix)Printing Services' for more extensions. + (extensions + (list cups-filters foomatic-filters brlaser)))) + + (simple-service 'scanning-services shepherd-root-service-type + (list + (shepherd-service + (documentation "Expose USB scanners over IPP.") + (provision '(ipp-usb)) + (requirement '(networking)) ; only on localhost, though + (start #~(make-forkexec-constructor + (list #$(file-append ipp-usb "/bin/ipp-usb") "standalone"))) + (stop #~(make-kill-destructor))))) + + (extra-special-file "/etc/NetworkManager/dispatcher.d/09-set-timezone" + (program-file "set-timezone" set-timezone-script)) + + (service tw-wireguard-service-type + (tw-wireguard-configuration + (this-host host-name))) + + (tw-openssh-service host-name) + + ;; Since Guix 953c65ffdd4, build-machines can be directly specified in + ;; `guix-configuration'. However, this doesn't allow the dynamic + ;; selection of build machines as is done here. + (extra-special-file "/etc/guix/machines.scm" + (scheme-file "machines.scm" + #~(let ((lud (build-machine + (name "lud.twilken.net") + (systems '("x86_64-linux")) + (port '#$(assoc-ref %ssh-ports "lud.twilken.net")) + (host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGqXbxv3a2bZyGjnEirVCMtRBeLKW/ha8ULSR9Xye4Z1") + (user "timo") + (private-key "/home/timo/.local/share/ssh-keys/id_ed25519") + (speed '#$(/ 4 cores)))) ; 4 cores, 16 GB RAM + (vin (build-machine + (name "vin.twilken.net") + (systems '("x86_64-linux")) + (port '#$(assoc-ref %ssh-ports "vin.twilken.net")) + (host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEEpdfKxzoCwg53TKPF5YxgUwhGF+bELAyBGdxagQroJ") + (user "timo") + (private-key "/home/timo/.local/share/ssh-keys/id_ed25519") + (speed '#$(/ 8 cores))))) ; 8 cores, 16 GB RAM + (use-modules (ice-9 popen) + (ice-9 textual-ports) + (ice-9 regex)) + (let* ((regexp (make-regexp "^GENERAL\\.CONNECTION:[[:space:]]+TLAN$" regexp/newline)) + (pipe (open-pipe* OPEN_READ #$(file-append network-manager "/bin/nmcli") + "device" "show" #$wireless-interface)) + (at-home? (regexp-exec regexp (get-string-all pipe)))) + (close-pipe pipe) + ;; Only offload to vin when at home, as the network connection is too bad otherwise. + (if at-home? + (list vin) + (list lud)))))) + + (simple-service 'disk-maintenance mcron-service-type + ;; I don't think jobs run on boot if they would have run when the + ;; computer was turned off, so choose a time when the computer is + ;; probably turned on. + (list #~(job "45 21 * * *" "guix gc -d 2w -F 25G") ; after unattended-upgrade + #~(job "0 22 * * *" ; after guix gc + (string-append #$(file-append util-linux "/sbin/fstrim") + " --fstab --verbose")))) + + (modify-services (append %system-channel-services %desktop-services) + ;; Let sane find the airscan backend. ipp-usb needs to be running separately. + (sane-service-type _ => sane-backends/airscan) + + (gdm-service-type config => - (login-configuration + (gdm-configuration (inherit config) - (motd (plain-file "no-motd" "")) - (allow-empty-passwords? #f)))))) + (auto-login? #f) + (default-user "timo") + (xorg-configuration xorg-config))) + + (geoclue-service-type + config => + (geoclue-configuration + (inherit config) + (applications + (cons* (geoclue-application "redshift" #:system? #f) + %standard-geoclue-applications)))) + + (login-service-type config => (tw-login-configuration config))))) diff --git a/tw/system/frm.scm b/tw/system/frm.scm index e52ff1a1..f60dcfe0 100644 --- a/tw/system/frm.scm +++ b/tw/system/frm.scm @@ -7,6 +7,12 @@ (define-module (tw system frm) #:use-module (gnu) #:use-module (gnu bootloader grub) + #:use-module (gnu packages linux) + #:use-module (gnu packages shells) + #:use-module (gnu services admin) + #:use-module (gnu services desktop) + #:use-module (gnu services pm) + #:use-module (gnu services syncthing) #:use-module (gnu system locale) #:use-module (gnu system nss) #:use-module (guix gexp) @@ -20,34 +26,14 @@ #:use-module ((nonguix licenses) #:prefix nongnu:) #:use-module (tw channels) - #:use-module (tw packages scanner) #:use-module (tw services secrets) - #:use-module (tw services wireguard) #:use-module (tw system)) -(use-package-modules android certs cups disk docker file-systems gnome guile - kerberos linux mtools pulseaudio search shells tls wm xorg) - -(use-service-modules admin authentication avahi base cups dbus desktop docker - kerberos linux mcron networking pm shepherd ssh syncthing - vpn xorg) - (define efi-system-partition ; /dev/nvme0n1p1 (uuid "D8C7-2624" 'fat)) (define root-partition ; /dev/nvme0n1p2 (uuid "62fb4710-33d1-4eaf-aaaa-43d16ab26a58" 'btrfs)) -(define touchpad-xorg-config - (@@ (tw system lap) touchpad-xorg-config)) - -(define set-timezone-script - (@@ (tw system lap) set-timezone-script)) - -(define custom-xorg-config - (xorg-configuration - (keyboard-layout %british-keyboard) - (extra-config (list touchpad-xorg-config)))) - (define select-firmware (@@ (nongnu packages linux) select-firmware)) @@ -102,6 +88,7 @@ These are actually Mediatek MT7922 chips.") ;; The MT7921E module is for the card connected via PCIe, which it is ;; (it's in an M.2 slot). Alternatives are S (SDIO) and U (USB). (kernel (nongnu:corrupt-linux linux-libre #:configs '("CONFIG_MT7921E=m"))) + (kernel-loadable-modules (list ddcci-driver-linux)) (initrd nongnu:microcode-initrd) ;; TODO: Enable wifi firmware, if necessary? (firmware (cons* nongnu:amdgpu-firmware mt7922-firmware %base-firmware)) @@ -158,33 +145,7 @@ These are actually Mediatek MT7922 chips.") "/run/current-system/profile/sbin/shutdown\n"))) ;; This is where we specify system-wide packages. - (packages - (cons* - ;; System stuff - cups docker mit-krb5 - ;; File systems - dosfstools mtools ntfs-3g - ;; Desktop and drivers - ;; FIXME: lightdm depends on python-2, but the build throws an - ;; error that python2 is not supported. - ;; TODO: Does lightdm have a service I need to enable? - ;;lightdm lightdm-gtk-greeter - pulseaudio xf86-video-amdgpu - ;; Adds /sys/class/backlight entries for external monitors. - ;; Not needed for laptop display. - ;; ddcci-driver-linux - i3-gaps ; install i3 here so gdm can see its xsession file - i3lock ; we need a system service to make i3lock setuid root - ;; We need to install gnome-keyring here so its PAM module is - ;; enabled properly (by its service; see below). - ;; nheko needs gnome-keyring to store secrets (kwallet doesn't do dbus). - gnome-keyring - ;; It's probably easiest to install geoclue system-wide, so it - ;; gets added to `%desktop-services' and redshift can access the - ;; location. - geoclue - ;; Base packages - %base-system-packages)) + (packages %enduser-system-packages) ;; Use the "desktop" services, which include the X11 ;; log-in service, networking with NetworkManager, and more. @@ -195,60 +156,12 @@ These are actually Mediatek MT7922 chips.") (syncthing-configuration (user "timo"))) - (service cups-service-type - (cups-configuration - (web-interface? #t) - (default-shared? #f) - ;; See info '(guix)Printing Services' for more extensions. - (extensions - (list cups-filters foomatic-filters brlaser)))) - (service bluetooth-service-type) - (service tw-wireguard-service-type - (tw-wireguard-configuration - (this-host host-name))) - - (service docker-service-type - (docker-configuration)) - - (service krb5-service-type - (krb5-configuration - (default-realm "CERN.CH") - (rdns? #f) - (realms (list (krb5-realm - (name "CERN.CH") - (default-domain "cern.ch") - (kdc "cerndc.cern.ch")))))) - - (service tlp-service-type - (tlp-configuration)) ; TODO: configure properly - - (service thermald-service-type - (thermald-configuration - (adaptive? #t))) - - (service earlyoom-service-type - (earlyoom-configuration)) ; TODO: configure at least `avoid-regexp' + (service tlp-service-type) ; TODO: configure properly - (service fprintd-service-type) - - ;; Install i3lock as a setuid binary, so it can talk to PAM. - (service screen-locker-service-type - (screen-locker-configuration - (name "i3lock") - (program (file-append i3lock "/bin/i3lock")))) - - ;; gnome-keyring is not in `%desktop-services' by default, - ;; but needs to be there to add itself to /etc/pam.d/. - ;; If using a DM other than GDM, add it to `pam-services' in - ;; `gnome-keyring-configuration' (see its docs). - (service gnome-keyring-service-type - (gnome-keyring-configuration)) - - (udev-rules-service 'android android-udev-rules #:groups '("adbusers")) - - (set-xorg-configuration custom-xorg-config) + ;; fprintd complains about missing firmware, but fwpud doesn't find any. + ;; (service fprintd-service-type) (service unattended-upgrade-service-type (unattended-upgrade-configuration @@ -261,100 +174,16 @@ These are actually Mediatek MT7922 chips.") ;; Anything that won't cause disruption when restarting. '(syncthing-timo earlyoom thermald tlp wireguard-wg0 mcron)))) - (simple-service 'disk-maintenance mcron-service-type - ;; I don't think jobs run on boot if they would have run when the - ;; computer was turned off, so choose a time when the computer is - ;; probably turned on. - (list #~(job "45 21 * * *" "guix gc -d 2w -F 25G") ; after unattended-upgrade - #~(job "0 22 * * *" ; after guix gc - (string-append #$(file-append util-linux "/sbin/fstrim") - " --fstab --verbose")))) - - (extra-special-file "/etc/NetworkManager/dispatcher.d/09-set-timezone" - (program-file "set-timezone" set-timezone-script)) - - (simple-service 'scanning-services shepherd-root-service-type - (list - (shepherd-service - (documentation "Expose USB scanners over IPP.") - (provision '(ipp-usb)) - (requirement '(networking)) ; only on localhost, though - (start #~(make-forkexec-constructor - (list #$(file-append ipp-usb "/bin/ipp-usb") "standalone"))) - (stop #~(make-kill-destructor))))) - - ;; Since Guix 953c65ffdd4, build-machines can be directly specified in - ;; `guix-configuration'. However, this doesn't allow the dynamic - ;; selection of build machines as is done here. - (extra-special-file "/etc/guix/machines.scm" - (scheme-file "machines.scm" - #~(let ((lud (build-machine - (name "lud.twilken.net") - (systems '("x86_64-linux")) - (port '#$(assoc-ref %ssh-ports "lud.twilken.net")) - (host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGqXbxv3a2bZyGjnEirVCMtRBeLKW/ha8ULSR9Xye4Z1") - (user "timo") - (private-key "/home/timo/.local/share/ssh-keys/id_rsa") - (speed 1/3))) ; 4 cores, 16 GB RAM - (vin (build-machine - (name "vin.twilken.net") - (systems '("x86_64-linux")) - (port '#$(assoc-ref %ssh-ports "vin.twilken.net")) - (host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEEpdfKxzoCwg53TKPF5YxgUwhGF+bELAyBGdxagQroJ") - (user "timo") - (private-key "/home/timo/.local/share/ssh-keys/id_rsa") - (speed 2/3)))) ; 8 cores, 16 GB RAM - (use-modules (ice-9 popen) - (ice-9 textual-ports) - (ice-9 regex)) - (let* ((regexp (make-regexp "^GENERAL\\.CONNECTION:[[:space:]]+TLAN$" regexp/newline)) - (pipe (open-pipe* OPEN_READ #$(file-append network-manager "/bin/nmcli") - "device" "show" "wlp3s0")) - (at-home? (regexp-exec regexp (get-string-all pipe)))) - (close-pipe pipe) - ;; Only offload to vin when at home, as the network connection is too bad otherwise. - (if at-home? - (list vin) - (list lud)))))) - ;; Set up a secrets config for WireGuard to extend. (service secrets-service-type (secrets-configuration + ;; TODO: reencrypt with SSH host key (host-key "/etc/secrets.key"))) ; we have no SSH host keys, so use a custom key - (service openssh-service-type - (openssh-configuration - (x11-forwarding? #t) - (permit-root-login #f) - (password-authentication? #f) - (authorized-keys - `(("timo" ,(local-file "files/timo.pub")))))) - - (modify-services (append %system-channel-services %desktop-services) - ;; Let sane find the airscan backend. ipp-usb needs to be running separately. - (sane-service-type _ => sane-backends/airscan) - - (gdm-service-type - config => - (gdm-configuration - (inherit config) - (auto-login? #f) - (default-user "timo") - (xorg-configuration custom-xorg-config))) - - (geoclue-service-type - config => - (geoclue-configuration - (inherit config) - (applications - (cons* (geoclue-application "redshift" #:system? #f) - %standard-geoclue-applications)))) - - (login-service-type - config => - (login-configuration - (inherit config) - (motd (plain-file "no-motd" "")) - (allow-empty-passwords? #f)))))))) + (enduser-system-services + #:host-name host-name + #:cores 12 + #:wireless-interface "wlp1s0" + #:backlight-device "amdgpu_bl0"))))) %frm-system diff --git a/tw/system/lap.scm b/tw/system/lap.scm index e3037d61..241dca96 100644 --- a/tw/system/lap.scm +++ b/tw/system/lap.scm @@ -7,31 +7,32 @@ (define-module (tw system lap) #:use-module (gnu) #:use-module (gnu bootloader grub) + #:use-module (gnu packages linux) + #:use-module (gnu packages shells) + #:use-module (gnu services admin) + #:use-module (gnu services desktop) + #:use-module (gnu services pm) + #:use-module (gnu services shepherd) + #:use-module (gnu services syncthing) #:use-module (gnu system locale) #:use-module (gnu system nss) #:use-module (guix gexp) #:use-module (guix packages) - #:use-module ((guix utils) #:select (substitute-keyword-arguments)) + #:use-module ((guix utils) + #:select (substitute-keyword-arguments)) #:use-module ((nongnu packages linux) #:prefix nongnu:) ; don't interfere with (gnu packages linux) - #:use-module (nongnu packages nvidia) - #:use-module (nongnu packages scanner) - #:use-module (nongnu services nvidia) - #:use-module (nongnu system linux-initrd) + #:use-module ((nongnu packages nvidia) + #:prefix nongnu:) + #:use-module ((nongnu services nvidia) + #:prefix nongnu:) + #:use-module ((nongnu system linux-initrd) + #:prefix nongnu:) #:use-module (nonguix licenses) #:use-module (tw channels) - #:use-module (tw packages scanner) #:use-module (tw services secrets) - #:use-module (tw services wireguard) #:use-module (tw system)) -(use-package-modules android certs cups disk docker file-systems gnome guile - kerberos linux mtools pulseaudio search shells tls wm xorg) - -(use-service-modules admin authentication avahi base cups dbus desktop docker - kerberos linux mcron networking pm shepherd ssh syncthing - vpn xorg) - (define efi-system-partition ; /dev/nvme0n1p1 (uuid "E04A-DF05" 'fat)) (define tilearch-root-partition ; /dev/nvme0n1p2 @@ -45,80 +46,6 @@ (define data-partition-inside-luks ; /dev/mapper/data (uuid "826bb1a7-1069-46a5-897a-afa19272fbb0" 'btrfs)) -(define backlight-udev-rules - ;; The naive approach of GROUP="video", MODE="0664" doesn't seem to work. - ;; https://github.com/haikarainen/light/blob/master/90-backlight.rules - ;; https://github.com/Hummer12007/brightnessctl/blob/master/90-brightnessctl.rules - (udev-rule "90-backlight.rules" "\ -ACTION!=\"remove\", SUBSYSTEM==\"backlight\", GROUP=\"video\", MODE=\"0664\" -ACTION!=\"remove\", SUBSYSTEM==\"leds\", GROUP=\"video\", MODE=\"0664\" -")) - -;; This text is added verbatim to the Xorg config file. -(define touchpad-xorg-config "\ -# see man 4 libinput -Section \"InputClass\" - Identifier \"touchpad\" - Driver \"libinput\" - MatchIsTouchpad \"true\" - - Option \"DisableWhileTyping\" \"true\" - Option \"MiddleEmulation\" \"true\" - Option \"NaturalScrolling\" \"true\" - Option \"HorizontalScrolling\" \"true\" - Option \"ScrollMethod\" \"twofinger\" - Option \"ClickMethod\" \"clickfinger\" - Option \"Tapping\" \"true\" - Option \"TappingDrag\" \"true\" - Option \"TappingDragLock\" \"false\" - Option \"TappingButtonMap\" \"lrm\" -EndSection -") - -(define custom-xorg-config - (xorg-configuration - (keyboard-layout %british-keyboard) - (extra-config (list touchpad-xorg-config)) - ;; TODO: run acpid so nvidia driver can connect? - ;; See `guix show nvidia-driver' - (modules (cons* nvidia-driver %default-xorg-modules)) - (drivers '("nvidia" "modesetting")))) - -(define set-timezone-script - ;; Every time we connect to a network, get our timezone from network geolocation. - ;; https://wiki.archlinux.org/title/System_time - ;; https://wiki.archlinux.org/title/Network_configuration/Wireless#Respecting_the_regulatory_domain - (with-extensions (list guile-json-4 guile-gnutls) ; guile-gnutls needed by (web client) - #~(begin - (use-modules ((srfi srfi-11) #:select (let-values)) - (json) - (web client) - (web response)) - (define api-url "https://ipapi.co/json") - ;; According to the Arch Wiki, when checking for "up" as the second - ;; argument, VPN connections could cause undesired timezone changes. - (when (and (string=? "connectivity-change" (caddr (command-line))) - (string=? "FULL" (getenv "CONNECTIVITY_STATE"))) - (let-values (((response text) (http-get api-url))) - (unless (= 200 (response-code response)) - (error "Got error response to request:" response)) - (let* ((json (json-string->scm text)) - (timezone (assoc-ref json "timezone")) - (zonefile (string-append #$tzdata "/share/zoneinfo/" timezone)) - (regdb-country (assoc-ref json "country_code")) - (error-code - (status:exit-val - ;; Set WiFi regulatory domain to use the correct channels. - (system* #$(file-append iw "/bin/iw") "reg" "set" regdb-country)))) - (format (current-error-port) "Updated WiFi regdomain to ~a: ~a~%" - regdb-country (if (zero? error-code) "success" - (format #f "error ~d" error-code))) - ;; Set local timezone. - (delete-file "/etc/localtime") - (symlink zonefile "/etc/localtime") - (format (current-error-port) - "Updated timezone to ~a: success~%" timezone))))))) - (define-public %lap-system (operating-system (host-name "lap.twilken.net") @@ -164,7 +91,8 @@ EndSection ;;"acpi_enforce_resources=lax" "modprobe.blacklist=nouveau" ; prevent interference with nvidia %default-kernel-arguments)) - (initrd microcode-initrd) + (kernel-loadable-modules (list ddcci-driver-linux)) + (initrd nongnu:microcode-initrd) (firmware (cons* nongnu:atheros-firmware ; for atk10k/QCA6174/hw3.0 (wifi card) nongnu:i915-firmware ; for Intel GPU runtime power management etc %base-firmware)) @@ -235,34 +163,8 @@ EndSection ;; This is where we specify system-wide packages. (packages - (cons* - ;; System stuff - cups docker mit-krb5 - ;; File systems - dosfstools mtools ntfs-3g - ;; Desktop and drivers - ;; FIXME: lightdm depends on python-2, but the build throws an - ;; error that python2 is not supported. - ;; TODO: Does lightdm have a service I need to enable? - ;;lightdm lightdm-gtk-greeter - pulseaudio xf86-video-intel xf86-video-nouveau - ;; Adds /sys/class/backlight entries for external monitors. - ;; Not needed for laptop display. - ;; ddcci-driver-linux - i3-gaps ; install i3 here so gdm can see its xsession file - i3lock ; we need a system service to make i3lock setuid root - ;; We need to install gnome-keyring here so its PAM module is - ;; enabled properly (by its service; see below). - ;; nheko needs gnome-keyring to store secrets (kwallet doesn't do dbus). - gnome-keyring - ;; It's probably easiest to install geoclue system-wide, so it - ;; gets added to `%desktop-services' and redshift can access the - ;; location. - geoclue - ;; Proprietary NVIDIA driver. See its description for more required setup steps. - nvidia-driver - ;; Base packages - %base-system-packages)) + ;; Proprietary NVIDIA driver. See its description for more required setup steps. + (cons* nongnu:nvidia-driver %enduser-system-packages)) ;; Use the "desktop" services, which include the X11 ;; log-in service, networking with NetworkManager, and more. @@ -273,73 +175,15 @@ EndSection (syncthing-configuration (user "timo"))) - (service cups-service-type - (cups-configuration - (web-interface? #t) - (default-shared? #f) - ;; See info '(guix)Printing Services' for more extensions. - (extensions - (list cups-filters foomatic-filters brlaser)))) - (service bluetooth-service-type) - (service tw-wireguard-service-type - (tw-wireguard-configuration - (this-host host-name))) - - (service docker-service-type - (docker-configuration)) - - (service krb5-service-type - (krb5-configuration - (default-realm "CERN.CH") - (rdns? #f) - (realms (list (krb5-realm - (name "CERN.CH") - (default-domain "cern.ch") - (kdc "cerndc.cern.ch")))))) - - (service tlp-service-type - (tlp-configuration)) ; TODO: configure properly - - (service thermald-service-type - (thermald-configuration - (adaptive? #t))) - - (service earlyoom-service-type - (earlyoom-configuration)) ; TODO: configure at least `avoid-regexp' + (service tlp-service-type) ; TODO: configure properly ;; Disabled as it doesn't work with my hardware. ;; It always says "logging in with fingerprint failed" and blocks password login in gdm. ;; (service fprintd-service-type) - ;; Install i3lock as a setuid binary, so it can talk to PAM. - (service screen-locker-service-type - (screen-locker-configuration - (name "i3lock") - (program (file-append i3lock "/bin/i3lock")))) - - ;; gnome-keyring is not in `%desktop-services' by default, - ;; but needs to be there to add itself to /etc/pam.d/. - ;; If using a DM other than GDM, add it to `pam-services' in - ;; `gnome-keyring-configuration' (see its docs). - (service gnome-keyring-service-type - (gnome-keyring-configuration)) - - ;; Allow anyone in the "video" group to set the display's brightness. - ;; Run `udevadm info -q all /sys/class/backlight/intel_backlight' - ;; to see properties. - (udev-rules-service 'backlight backlight-udev-rules #:groups '("video")) - ;; According to "info '(guix) Base Services'", the above should - ;; have a `#:groups '("video")', but that group is already - ;; declared as a supplementary group for my user and guix warns - ;; that it's declared twice. - - (udev-rules-service 'android android-udev-rules #:groups '("adbusers")) - - (set-xorg-configuration custom-xorg-config) - - (service nvidia-service-type) ; proprietary nvidia driver + (service nongnu:nvidia-service-type) ; proprietary nvidia driver ;; For some reason, none of the NVIDIA things create this device file ;; automatically, even though the NVIDIA Xorg driver requires it (Xorg @@ -369,123 +213,20 @@ EndSection ;; Anything that won't cause disruption when restarting. '(syncthing-timo earlyoom thermald tlp wireguard-wg0 mcron)))) - (simple-service 'disk-maintenance mcron-service-type - ;; I don't think jobs run on boot if they would have run when the - ;; computer was turned off, so choose a time when the computer is - ;; probably turned on. - (list #~(job "45 21 * * *" "guix gc -d 2w -F 25G") ; after unattended-upgrade - #~(job "0 22 * * *" ; after guix gc - (string-append #$(file-append util-linux "/sbin/fstrim") - " --fstab --verbose")))) - - (extra-special-file "/etc/NetworkManager/dispatcher.d/09-set-timezone" - (program-file "set-timezone" set-timezone-script)) - - (simple-service 'xbacklight-services shepherd-root-service-type - (list - (shepherd-service - (documentation "Set laptop screen backlight on boot.") - (provision '(backlight)) - (one-shot? #t) - (start #~(make-forkexec-constructor - (list #$(program-file "backlight-setter" - #~(begin - (use-modules ((ice-9 textual-ports) #:select (get-string-all)) - ((srfi srfi-26) #:select (cut))) - (define brightness-file "/sys/class/backlight/intel_backlight/brightness") - (define max-brightness-file "/sys/class/backlight/intel_backlight/max_brightness") - ;; These files don't exist right after startup, so wait for them to appear. - (while (not (and (file-exists? max-brightness-file) - (file-exists? brightness-file))) - (format (current-error-port) "Waiting for /sys files to appear...~%") - (sleep 1)) - (define max-brightness - (call-with-input-file max-brightness-file get-string-all)) - (call-with-output-file brightness-file - (cut display max-brightness <>)))))))))) - - (simple-service 'scanning-services shepherd-root-service-type - (list - (shepherd-service - (documentation "Expose USB scanners over IPP.") - (provision '(ipp-usb)) - (requirement '(networking)) ; only on localhost, though - (start #~(make-forkexec-constructor - (list #$(file-append ipp-usb "/bin/ipp-usb") "standalone"))) - (stop #~(make-kill-destructor))))) - - ;; Since Guix 953c65ffdd4, build-machines can be directly specified in - ;; `guix-configuration'. However, this doesn't allow the dynamic - ;; selection of build machines as is done here. - (extra-special-file "/etc/guix/machines.scm" - (scheme-file "machines.scm" - #~(let ((lud (build-machine - (name "lud.twilken.net") - (systems '("x86_64-linux")) - (port '#$(assoc-ref %ssh-ports "lud.twilken.net")) - (host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGqXbxv3a2bZyGjnEirVCMtRBeLKW/ha8ULSR9Xye4Z1") - (user "timo") - (private-key "/home/timo/.local/share/ssh-keys/id_rsa") - (speed .5))) ; 4 cores, 16 GB RAM - (vin (build-machine - (name "vin.twilken.net") - (systems '("x86_64-linux")) - (port '#$(assoc-ref %ssh-ports "vin.twilken.net")) - (host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEEpdfKxzoCwg53TKPF5YxgUwhGF+bELAyBGdxagQroJ") - (user "timo") - (private-key "/home/timo/.local/share/ssh-keys/id_rsa") - (speed 1.)))) ; 8 cores, 16 GB RAM - (use-modules (ice-9 popen) - (ice-9 textual-ports) - (ice-9 regex)) - (let* ((regexp (make-regexp "^GENERAL\\.CONNECTION:[[:space:]]+TLAN$" regexp/newline)) - (pipe (open-pipe* OPEN_READ #$(file-append network-manager "/bin/nmcli") - "device" "show" "wlp3s0")) - (at-home? (regexp-exec regexp (get-string-all pipe)))) - (close-pipe pipe) - ;; Only offload to vin when at home, as the network connection is too bad otherwise. - (if at-home? - (list vin) - (list lud)))))) - ;; Set up a secrets config for WireGuard to extend. (service secrets-service-type (secrets-configuration + ;; TODO: reencrypt for SSH key. (host-key "/etc/secrets.key"))) ; we have no SSH host keys, so use a custom key - (service openssh-service-type - (openssh-configuration - (x11-forwarding? #t) - (permit-root-login #f) - (password-authentication? #f) - (authorized-keys - `(("timo" ,(local-file "files/timo.pub")))))) - - (modify-services (append %system-channel-services %desktop-services) - ;; Let sane find the airscan backend. ipp-usb needs to be running separately. - (sane-service-type _ => sane-backends/airscan) - - (gdm-service-type - config => - (gdm-configuration - (inherit config) - (auto-login? #f) - (default-user "timo") - (xorg-configuration custom-xorg-config))) - - (geoclue-service-type - config => - (geoclue-configuration - (inherit config) - (applications - (cons* (geoclue-application "redshift" #:system? #f) - %standard-geoclue-applications)))) - - (login-service-type - config => - (login-configuration - (inherit config) - (motd (plain-file "no-motd" "")) - (allow-empty-passwords? #f)))))))) + (enduser-system-services + #:host-name host-name + #:cores 8 + #:wireless-interface "wlp3s0" + #:backlight-device "intel_backlight" + #:xorg-extra-modules (list nongnu:nvidia-driver) + ;; TODO: run acpid so nvidia driver can connect? + ;; See `guix show nvidia-driver' + #:xorg-drivers '("nvidia" "modesetting")))))) %lap-system -- cgit v1.2.3