diff options
-rw-r--r-- | tw/home/cern.scm | 308 | ||||
-rw-r--r-- | tw/system/cern.scm | 243 | ||||
-rw-r--r-- | tw/system/files/timo-cern.pub | 1 |
3 files changed, 552 insertions, 0 deletions
diff --git a/tw/home/cern.scm b/tw/home/cern.scm new file mode 100644 index 00000000..6a814bc6 --- /dev/null +++ b/tw/home/cern.scm @@ -0,0 +1,308 @@ +;; This "home-environment" file can be passed to 'guix home reconfigure' +;; to reproduce the content of your profile. This is "symbolic": it only +;; specifies package names. To reproduce the exact same profile, you also +;; need to capture the channels being used, as returned by "guix describe". +;; See the "Replicating Guix" section in the manual. + +;; See also, for some tips: +;; https://github.com/alezost/shepherd-config/blob/master/init.scm + +(define-module (tw home cern) + #:use-module ((gnu) + #:select (use-package-modules)) + #:use-module (gnu home) + #:use-module (gnu home services) + #:use-module (gnu home services desktop) + #:use-module (gnu home services guix) + #:use-module (gnu home services mcron) + #:use-module (gnu home services pm) + #:use-module (gnu home services shepherd) + #:use-module (gnu packages) + #:use-module (gnu services) + #:use-module (gnu services shepherd) + #:use-module (guix channels) + #:use-module (guix gexp) + ;; #:use-module ((nongnu packages messaging) + ;; #:select (zoom)) + #:use-module (tw home) + #:use-module (tw home emacs) + #:use-module (tw packages alice) + #:use-module (tw packages catppuccin) + #:use-module (tw packages xorg) + #:use-module (tw gexp) + #:use-module (tw theme)) + +(use-package-modules android calendar compton dav dunst fonts freedesktop games + gimp gnome gnome-xyz gnuzilla graphviz inkscape kde + libreoffice linux mail messaging networking pdf pulseaudio + python-xyz syndication tcl terminals version-control video + web-browsers wm xdisorg xorg) + +(define pim-packages + (list vdirsyncer khal khard aerc lynx)) ; lynx for HTML mail + +(define pim-services + (list + (simple-service 'pim-config home-xdg-configuration-files-service-type + `(("khal/config" ,(local-file "files/khal.conf")) + ("khard/khard.conf" ,(local-file "files/khard.conf")) + ("aerc" ,(local-file "files/aerc" #:recursive? #t)) + ("vdirsyncer/config" ,(local-file "files/vdirsyncer.conf")))) + + ;; These cron jobs are annoying because they pop up a password prompt every time they run. + ;; (simple-service 'pim-cronjobs home-mcron-service-type + ;; (list #~(job "15 */4 * * *" ; every four hours at HH:15 + ;; (string-append #$(file-append vdirsyncer "/bin/vdirsyncer") " metasync")) + ;; #~(job "0,30 * * * *" ; every half hour + ;; (string-append #$(file-append vdirsyncer "/bin/vdirsyncer") " sync")))) + + (simple-service 'mail-files home-files-service-type + `(;; The file from git main is newer than the one bundled with the + ;; packaged neomutt version and contains a few fixes. + (".local/bin/mutt_oauth2.py" + ,(local-file "files/neomutt/contrib/oauth2/mutt_oauth2.py" #:recursive? #t)))))) + +(define polybar-wrapper + (program-file + "polybar-wrapper" + #~(begin + ;; This wrapper program checks that the monitor we want to start + ;; polybar on is actually connected. + (use-modules (ice-9 popen) + (ice-9 rdelim)) + (let* ((connected-str (string-append (getenv "POLYBAR_MONITOR") " connected")) + (xrandr (open-pipe* OPEN_READ #$(file-append xrandr "/bin/xrandr") "-q")) + (monitor-connected? + (let loop ((line (read-line xrandr))) + (cond + ((eof-object? line) #f) ; we didn't find our monitor connected + ((string-prefix? connected-str line) #t) ; the monitor we want is connected + (else (loop (read-line xrandr))))))) ; keep looking + (close-pipe xrandr) + (when monitor-connected? + (execl #$(file-append polybar "/bin/polybar"))))))) + +(define (polybar-service monitor) + (shepherd-service + (documentation (string-append "Polybar desktop bar for monitor " monitor ".")) + (provision (list (symbol-append 'polybar- (string->symbol monitor)))) + (requirement '(xorg-setup)) + (start #~(make-forkexec-constructor + (list #$polybar-wrapper) + #:environment-variables + (cons #$(string-append "POLYBAR_MONITOR=" monitor) + (default-environment-variables)))) + (stop #~(make-kill-destructor)))) + +(define-public %cern-home + (home-environment + (packages + ;; These packages will show up in the home profile, under ~/.guix-home/profile. + (cons* + ;; CLI tools + bsd-games powertop (list git "send-email") + + ;; Work + s3cmd python-alibuild ; python-alidistlint + + ;; i3 and Xorg. i3 itself must be installed system-wide for gdm to pick it up. + ;; acpilight is a drop-in xbacklight replacement, as xbacklight doesn't work on my system. + acpilight arandr dunst gimp hsetroot inkscape icecat kitty libreoffice mpv + polybar pulsemixer rofi rofi-calc tk xdg-utils xdot xclip xcwd xdotool + xdpyinfo xev xfd xfontsel xinput xkill xprop xrandr xrdb xsel xset xwininfo + #;zoom zathura zathura-ps zathura-pdf-poppler + dconf dconf-editor ; required for config by blueman, cozy, ... + ;; gnome-keyring ; installed system-wide; see system-configuration.scm + ;; geoclue ; for redshift -- installed system-wide + ;; Fonts + font-hermit font-inconsolata font-fira-code font-fira-sans + font-libertinus font-openmoji + ;; Theming + papirus-icon-theme catppuccin-gtk-theme catppuccin-mocha-dark-cursors + + (append common-packages emacs-packages pim-packages))) + + ;; To search for available home services, run 'guix home search KEYWORD'. + (services + (cons* + ;; Configuration files for terminal-only programs in $XDG_CONFIG_HOME. + (simple-service 'laptop-config home-xdg-configuration-files-service-type + `(;; All alibuild needs is an empty file. + ("alibuild/disable-analytics" + ,(plain-file "alibuild-disable-analytics" "")) + ("X11/XCompose" ,(local-file "files/XCompose")) ; see also: $XCOMPOSEFILE variable + ("X11/Xresources" ,(local-file "files/Xresources")))) + + ;; This can't be a `service' as that would remove the 'guix channel. + (simple-service 'nonfree-channels home-channels-service-type + (list + ;; Nonguix is also needed system-wide for non-free drivers! + (channel + (name 'nonguix) + (url "https://gitlab.com/nonguix/nonguix") + ;; Enable signature verification: + (introduction + (make-channel-introduction + "897c1a470da759236cc11798f4e0a5f7d4d59fbc" + (openpgp-fingerprint + "2A39 3FFF 68F4 EF7A 3D29 12AF 6F51 20A0 22FB B2D5")))))) + + ;; Redshift: make the screen turn redder at night. + (service home-redshift-service-type + (home-redshift-configuration + ;; See info '(guix)Desktop Home Services'. + (location-provider 'manual) + ;; Approximate location + (latitude 46.0) + (longitude 6.0) + ;; (location-provider 'geoclue2) ; TODO: currently waits forever for a location -- not sure why geoclue doesn't work + ;; (daytime-temperature 6500) ; default 6500 + ;; (nighttime-temperature 4500) ; default 4500 + (daytime-brightness 1.0) + (nighttime-brightness 0.7) + (extra-content "fade=0"))) ; with fade=1, restarting redshift causes flickering for a few secs + + ;; The dbus service doesn't seem to be added automatically. + (service home-dbus-service-type + (home-dbus-configuration)) + + (simple-service 'gui-services home-shepherd-service-type + (list + (shepherd-service + (documentation "NetworkManager applet; provides a GUI for network connections.") + (provision '(nm-applet)) + (start #~(make-forkexec-constructor + (list #$(file-append network-manager-applet "/bin/nm-applet")))) + (stop #~(make-kill-destructor))) + + (polybar-service "DP2") + (polybar-service "DP1-8") + + (shepherd-service + (documentation "Dunst notification daemon; displays desktop notifications.") + (provision '(dunst)) + (start #~(make-forkexec-constructor + (list #$(file-append dunst "/bin/dunst")))) + (stop #~(make-kill-destructor))) + + (shepherd-service + (documentation "Picom compositor; enables transparent windows in X.") + (provision '(picom)) + (start #~(make-forkexec-constructor + (list #$(file-append picom "/bin/picom") + "--config" #$(local-file "files/picom.conf")))) + (stop #~(make-kill-destructor))) + + (shepherd-service + (documentation "Source Xresources on login.") + (provision '(xrdb)) + (one-shot? #t) + (start #~(lambda _ + (invoke #$(file-append xrdb "/bin/xrdb") "-merge" + (string-append (getenv "XDG_CONFIG_HOME") "/X11/Xresources"))))) + + ;; By default, xdotool gets most of "#@\|~()<>[]{} wrong. Make + ;; it use the correct keymap by re-setting the same one again. + (shepherd-service + (documentation "Fix X keyboard map on login; passmenu needs this.") + (provision '(fix-xdotool)) + (one-shot? #t) + (start #~(lambda _ + (use-modules (ice-9 rdelim) + (ice-9 regex) + (ice-9 popen)) + (let ((port (open-pipe* OPEN_READ #$(file-append setxkbmap "/bin/setxkbmap") + "-query"))) + (let loop ((line (read-line port))) + (unless (eof-object? line) + (let ((mtch (string-match "^layout:[[:space:]]*" line))) + (if mtch + (system* #$(file-append setxkbmap "/bin/setxkbmap") + (match:suffix mtch)) + (loop (read-line port)))))))))) + + (shepherd-service + (documentation "Set up X displays on login.") + (provision '(xorg-setup)) + (one-shot? #t) + (start #~(lambda _ + (system* #$(file-append numlockx "/bin/numlockx") "on") + ;; Turn off the monitors if there is no input for 10 minutes. + (system* #$(file-append xset "/bin/xset") "dpms" "600" "600" "600") + (system* #$(file-append xrandr "/bin/xrandr") + "--output" "DP2" "--primary" "--auto" + "--output" "DP1-8" "--auto" "--right-of" "DP2") + ;; Set the desktop background picture. Hopefully doing this just after + ;; xrandr works and sets it for both screens. + (system* #$(file-append hsetroot "/bin/hsetroot") "-cover" + (string-append (getenv "HOME") + ".config/X11/ridge-view.jpg"))))))) + + ;; Configuration files for GUI programs in $XDG_CONFIG_HOME. + (simple-service 'gui-config home-xdg-configuration-files-service-type + `(("dunst/dunstrc" ,(local-file "files/dunstrc")) + ("dunst/dunstrc.d/50-catppuccin.conf" ,catppuccin-dunstrc) + ("gtk-2.0/gtkrc" ,(local-file "files/gtk2.ini")) + ("gtk-3.0/settings.ini" ,(local-file "files/gtk3.ini")) + ("i3/config" ,(local-file "files/i3.conf")) + ;; TODO: "kdeglobals" works for some programs (e.g. kdeconnect-app), + ;; but not for others (e.g. nheko, kdeconnect-settings)... + ("kdeglobals" ,catppuccin-kdeglobals) + ("kitty/diff.conf" + ,(combined-text-file "kitty-diff.conf" + (plain-file "kitty-diff-custom.conf" + "pygments_style bw\n") + catppuccin-kitty-diff)) + ("kitty/kitty.conf" + ,(combined-text-file "kitty.conf" + (local-file "files/kitty.conf") + catppuccin-kitty)) + ("polybar/config.ini" ,(local-file "files/polybar.ini")) + ("polybar/catppuccin.ini" ,catppuccin-polybar) + ("rofi/config.rasi" ,(local-file "files/rofi.rasi")) + ("rofi/themes/catppuccin.rasi" ,catppuccin-rofi) + ("zathura/zathurarc" ,(local-file "files/zathurarc")) + ("zathura/catppuccin" ,catppuccin-zathura))) + + (simple-service 'cursor-theme home-files-service-type + `((".icons/default/index.theme" ,(local-file "files/cursors.ini")))) + + (simple-service 'gui-environment home-environment-variables-service-type + `(("TERMINAL" . "kitty") + ("_JAVA_OPTIONS" . + ,(string-append + "$_JAVA_OPTIONS${_JAVA_OPTIONS:+ }-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true " + "-Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel " + "-Dswing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel")) + ;; Smooth trackpad scrolling in Firefox/Icecat. + ;; https://wiki.archlinux.org/index.php/Firefox/Tweaks#Pixel-perfect_trackpad_scrolling + ("MOZ_USE_XINPUT2" . "1"))) + + (simple-service 'gui-scripts home-files-service-type + `(;; https://sw.kovidgoyal.net/kitty/kittens/diff/ + (".local/bin/kdiff" ; show a diff + ,(program-file "kdiff" #~(apply execl #$(file-append kitty "/bin/kitty") "kitty" + "+kitten" "diff" (cdr (command-line))))) + (".local/bin/icat" ; kitty's "catimg" equivalent + ,(program-file "icat" #~(apply execl #$(file-append kitty "/bin/kitty") "kitty" + "+kitten" "icat" (cdr (command-line))))) + (".local/bin/screenlock" + ,(program-file + "screenlock" + #~(begin ; Wrapper around i3lock to turn off the screen and pause notifications. + (system* #$(file-append dunst "/bin/dunstctl") "set-paused" "true") + (system* #$(file-append xset "/bin/xset") "dpms" "0" "0" "5") + ;; We mustn't use `file-append' here, as we have to pick up the + ;; setuid binary for i3lock installed by the system config. + (system* "i3lock" "-nc" #$catppuccin-background-color) + (system* #$(file-append xset "/bin/xset") "dpms" "600" "600" "600") + (system* #$(file-append dunst "/bin/dunstctl") "set-paused" "false")))) + ;; With #:recursive? #t, Guix keeps the files' permission bits, i.e. makes them executable. + (".local/bin/sessionmenu" ,(local-file "files/sessionmenu" #:recursive? #t)) + (".local/bin/passmenu" ,(local-file "files/passmenu" #:recursive? #t)) + (".local/bin/volume" ,(local-file "files/volume" #:recursive? #t)))) + + (append (gnupg-services #:gui-pinentry? #t) + common-services emacs-services pim-services))))) + +%cern-home diff --git a/tw/system/cern.scm b/tw/system/cern.scm new file mode 100644 index 00000000..76cae0bf --- /dev/null +++ b/tw/system/cern.scm @@ -0,0 +1,243 @@ +;; This is an operating system configuration file for a fairly minimal +;; "desktop" setup with i3 where the /home partition partition is +;; encrypted with LUKS. +;; +;; https://guix.gnu.org/manual/en/html_node/operating_002dsystem-Reference.html + +(define-module (tw system cern) + #:use-module (gnu) + #:use-module (gnu bootloader grub) + #:use-module (gnu system locale) + #:use-module (gnu system nss) + #:use-module (guix gexp) + #:use-module (guix packages) + #:use-module (tw system)) + +(use-package-modules certs cups disk docker file-systems gnome kerberos linux + mtools pulseaudio search shells wm xorg) + +(use-service-modules admin authentication avahi base cups dbus desktop docker + kerberos linux mcron networking pm ssh syncthing vpn xorg) + +(define efi-system-partition ; /dev/nvme0n1p1 + (uuid "806A-2762" 'fat)) +(define arch-root-partition ; /dev/nvme0n1p2 + (uuid "2c21b2c0-090e-4127-92fc-e83c589120f4" 'btrfs)) +(define guixsd-root-partition ; /dev/nvme0n1p4 -> 3 + (uuid "2c21b2c0-090e-4127-92fc-e83c589120f4" 'btrfs)) +(define swap-partition ; /dev/nvme0n1p3 -> 4 + (uuid "53559d6c-bf62-4cf6-991a-6dce6dd1dc64")) + +(define custom-xorg-config + (xorg-configuration + (keyboard-layout %british-keyboard))) + +(define-public %cern-system + (operating-system + (host-name "twilkendesktop.cern.ch") + (timezone "Europe/Zurich") + (locale "en_GB.utf8") + (locale-definitions + (list (locale-definition (name "en_GB.utf8") (source "en_GB")) + (locale-definition (name "en_US.utf8") (source "en_US")) + (locale-definition (name "fr_FR.utf8") (source "fr_FR")))) + + ;; Allow resolution of '.local' host names with mDNS. + (name-service-switch %mdns-host-lookup-nss) + + ;; Choose UK English X11 keyboard layout. + (keyboard-layout %british-keyboard) + + ;; Use the UEFI variant of GRUB with the EFI System + ;; Partition mounted on /boot/efi. + (bootloader + (bootloader-configuration + (bootloader grub-efi-bootloader) + (targets '("/boot/efi")) + ;; Note: keyboard-layout is ignored by non-grub bootloaders. + (keyboard-layout keyboard-layout) + (menu-entries + (list + (menu-entry + (label "systemd-boot") + (device efi-system-partition) + (chain-loader "/EFI/systemd/systemd-bootx64.efi")))))) + + (kernel linux-libre) + + (swap-devices + (list (swap-space + (target swap-partition) + (discard? #t)))) + + (file-systems + (cons* (file-system + (device guixsd-root-partition) + (mount-point "/") + (flags '(no-atime)) + (options (alist->file-system-options + '("ssd" ("compress" . "zstd")))) + (type "btrfs")) + (file-system + (device efi-system-partition) + (mount-point "/boot/efi") + (flags '(no-atime)) + (type "vfat")) + %base-file-systems)) + + ;; Members of the wheel group are allowed to use sudo. + (users (cons* (user-account + (name "twilken") + (comment "Timo Wilken") + (group "users") + (supplementary-groups + '("wheel" "audio" "video" "docker")) + (shell (file-append zsh "/bin/zsh"))) + %base-user-accounts)) + + (sudoers-file + (plain-file + "sudoers" + (string-append + ;; We need to preserve $TERMINFO so that programs under sudo can + ;; find kitty's terminfo files. This is possibly unsafe; sudo + ;; explicitly deletes this variable by default. + "Defaults env_keep += \"TERMINFO\"\n" + (plain-file-content %sudoers-specification) + ;; In addition to the default rules, allow admins to power off + ;; the computer. They'll have to use the system binaries, not + ;; those from their user profile, as /etc/sudoers requires + ;; absolute paths to commands. + "%wheel ALL=(ALL) NOPASSWD: " + "/run/current-system/profile/sbin/halt, " + "/run/current-system/profile/sbin/reboot, " + "/run/current-system/profile/sbin/shutdown\n"))) + + ;; This is where we specify system-wide packages. + (packages + (cons* + ;; System stuff + cups docker mit-krb5 + ;; 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 + ;; 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)) + + ;; Use the "desktop" services, which include the X11 + ;; log-in service, networking with NetworkManager, and more. + ;; See info '(guix)Services' for useful services. + (services + (cons* + (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)))) + + (bluetooth-service) + + (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 thermald-service-type + (thermald-configuration + (adaptive? #t))) + + (service earlyoom-service-type + (earlyoom-configuration)) ; TODO: configure at least `avoid-regexp' + + ;; Install i3lock as a setuid binary, so it can talk to PAM. + (screen-locker-service i3lock "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)) + + (set-xorg-configuration custom-xorg-config) + + (service unattended-upgrade-service-type + (unattended-upgrade-configuration + (schedule "0 21 * * *") ; every night at 22:00 + (maximum-duration (* 40 60)) ; 40 minutes + (operating-system-expression + #~(begin + (set! %load-path (cons "/home/timo/src/guix-decls" %load-path)) + (@ (tw system lap) %lap-system))) + (services-to-restart + ;; 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 22 * * *" "guix gc -d 2w -F 25G") ; after unattended-upgrade + #~(job "0 23 * * *" ; after guix gc + (string-append #$(file-append util-linux "/sbin/fstrim") + " --fstab --verbose")))) + + (service openssh-service-type + (openssh-configuration + (port-number 22022) + (x11-forwarding? #t) + (permit-root-login #f) + (password-authentication? #f) + (authorized-keys + `(("twilken" ,(local-file "files/timo-cern.pub")))))) + + (modify-services %desktop-services + (gdm-service-type + config => + (gdm-configuration + (inherit config) + (auto-login? #f) + (default-user "twilken") + (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)))))))) + +%cern-system diff --git a/tw/system/files/timo-cern.pub b/tw/system/files/timo-cern.pub new file mode 100644 index 00000000..58aca31b --- /dev/null +++ b/tw/system/files/timo-cern.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCoXEe40QydHD2afxYr/1urdzhTLTBUpnpjx6jHV82gT9vzXYfMLbtXHhJWcrs9F5Ms26CBuORltX3jMgmHLyawA5elWFznjRYnd0R+irIkSyycpe/RYIMAiQsCTN/TY4pB9YIn46qK1ZNKIeOXPXOh+mZmb8TssPfJpxP/i7yJAoy2DHS/TJaL7OwXIQ8iKOSm5zoxG5dfSWZZItiElZmjAhjW+Gz1H7J3p2wggJ7wNYQCDJr0a9IJzisx7kUArVq4VDqsPqIr6wDowlVo/d4x5IVleruXwEuqj/uMuVcsJmTolM+DXKgiPAWB/iVtKZkPFk49pR9/RMhga/8dV02RAde8T30iypENwan5noW6BFd0B+BuixmZ/U9QAWBUTMajo14Ji8h4GVWjV6OKN+MUTl9Vza3WL5e2ch3iUUuL64cCAgal1ANE7D/h/si4CIucPq2NriwWKAY5uo6w4yNi2TbfL5yBpoS1SMn8o8s8HpC6L5/+yB4imNvsr19Gda8= timo.wilken@cern.ch |