guixconfig/config.org
2024-04-17 01:53:58 +02:00

23 KiB

GUIX System Configuration

Daniel Ziltener's System Configuration

This is an attempt to fit my entire system's configuration in a file. Let's see how that turns out.

Emacs Lisp Helpers

To be able to use Org-Mode lists and tables, I need a few helpers for the conversion.

Converting Lists

A sample list for testing purposes:

  • Entry 1
  • Entry 2

First, a function that converts org lists into guile use- calls.

  (pretty-print
   `(,(string->symbol use-call)
     ,@(map (lambda (x)
              (let ((splits (string-split x #\ )))
                (if (and (= (length splits) 1)
                         (= 0 all-parens))
                    (string->symbol (car splits))
                    (map (lambda (y) (string->symbol y))
                         splits))))
            entries)))

Sometimes, I need lists of string->symbol calls.

  (pretty-print 
   `(list ,@(map string->symbol input)))

Converting Tables

Services

This function converts a table of simple services into service definitions.

  (pretty-print
   `(list
     ,@(map
        (lambda (row)
          (let ((service-name (car row))
                (configuration (cadr row)))
            `(service ,(string->symbol (string-append service-name "-service-type"))
                      (,(string->symbol (string-append service-name "-configuration"))
                       ,@(call-with-input-string configuration
                           read)))))
        input)))

Makefile

reconfigure:
	guix pull
	sudo guix archive --authorize < keys/non-guix.pub; \
	guix system reconfigure ./config.scm --substitute-urls='https://ci.guix.gnu.org https://bordeaux.guix.gnu.org https://substitutes.nonguix.org'
	guix home reconfigure ./home/home-configuration.scm
	make -C /home/zilti/.guix-home/profile/lib/browserpass hosts-firefox-user
	flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo

System Installation Script

This is to be run after setting up the partitions.

  #!/bin/sh
  set euxo -pipefail
  mount /dev/disk/by-label/guix /mnt
  mkdir -p /mnt/boot/efi
  mount /dev/disk/by-label/EFI /mnt/boot/efi
  herd start cow-store /mnt
  guix pull -C channels.scm
  GUIX_PROFILE="/root/.config/guix/current"
  . "$GUIX_PROFILE/etc/profile"
  hash guix
  guix system -L. init config.scm /mnt --substitute-urls="https://ci.guix.gnu.org https://bordeaux.guix.gnu.org https://substitutes.nonguix.org"

The Feature Record Type

This record type exists to facilitate grouping together configuration related to a specific feature.

  (define-record-type* <feature>
    feature make-feature
    feature?
  (name             feature-name
                    (default #f))
  (root-packages    feature-root-packages
                    (default '()))
  (packages         feature-packages
                    (default '()))
  (files            feature-files
                    (default '()))
  (xdg-config-files feature-xdg-config-files
                    (default '()))
  (service          feature-service
                    (default '()))
  (home-service     feature-home-service
                    (default '()))
  (environment      feature-environment
                    (default '())))

Since the records get written into a separate file to be consumed later, this helper function is necessary to do exactly that:

  <<feature-record>>
    (define* (consume-file fobj #:optional (result '()))
      (let ((next-elem (read fobj)))
        (if (eof-object? next-elem)
            (reverse result)
            (consume-file fobj (cons next-elem result)))))
  <<features-to-list>>

And ultimately, this function turns a list of features into a list of whatever is needed at that place.

  (define (features->list features get-fn)
    (filter
     (negate unspecified?)
     (fold append '()
           (map get-fn
                (filter
                 (negate unspecified?)
                 features)))))

Features

Git

Git configuration file:

[commit]
	gpgSign = true
        user = dziltener@lyrion.ch
[core]
	pager = "diff-so-fancy | less '--tabs=4' '-RFX'"
[diff-so-fancy]
	changeHunkIndicators = true
	markEmptyLines = true
	stripLeadingSymbols = true
	useUnicodeRuler = true
[gpg]
	program = "gpg"
[interactive]
	diffFilter = "diff-so-fancy --patch"
[pull]
	rebase = true
[push]
	autoSetupRemote = true
[rebase]
	autoStash = true
[sendemail]
#        sendmailCmd = msmtp -t
        annotate = yes
        smtpServer = lyrion.ch
        smtpUser = dziltener
        smtpEncryption = ssl
        smtpServerPort = 465
[credential]
        helper = cache
	helper = !pass-git-helper $@
[tag]
	gpgSign = true
[user]
	email = "dziltener@lyrion.ch"
	name = "Daniel Ziltener"
	signingKey = "37F655BAF43BC0FF300A91A1B38976E82C9DAE42"
[init]
        defaultBranch = master
[github]
        user = dziltener@lyrion.ch
[gitlab]
	user = zilti

I am using pass-git-helper to use Pass for git credentials.

[*dziltener@lyrion.ch*]
target=Privat/Mailaccount

Git service configuration:

  (feature
   (name 'git)
   (root-packages '(git))
   (packages '(git git:send-email pass-git-helper))
   (xdg-config-files '(("git/config" ,(local-file "./xdg-config/git/config"))
                       ("pass-git-helper/git-pass-mapping.ini" ,(local-file "./xdg-config/pass-git-helper/git-pass-mapping.ini")))))

Hyprland

An amazing tiling compositor for Wayland.

# See https://wiki.hyprland.org/Configuring/Monitors/
monitor=eDP-1,2880x1800@90.0,0x1930,1.333333

# See https://wiki.hyprland.org/Configuring/Keywords/ for more

# Execute your favorite apps at launch
# exec-once = waybar & hyprpaper & firefox

# Source a file (multi-file configs)
# source = ~/.config/hypr/myColors.conf

# Set programs that you use
$terminal = kitty
$fileManager = dolphin
$menu = fuzzel

# Some default env vars.
env = XCURSOR_SIZE,24
env = HYPRCURSOR_SIZE,24
env = HYPRCURSOR_THEME,hyprcursor_Dracula
env = QT_QPA_PLATFORMTHEME,qt5ct # change to qt6ct if you have that
env = MOZ_ENABLE_WAYLAND,1
env = XDG_SESSION_TYPE,wayland
env = CLUTTER_BACKEND,wayland
env = SDL_VIDEODRIVER,wayland
env = LIBGL_DRI3_ENABLE,1
env = GDK_BACKEND,wayland
env = XKB_DEFAULT_RULES,evdev
env = QT_QPA_PLATFORM,wayland
env = WLR_DRM_NO_ATOMIC,1
env = SSH_AUTH_SOCK,/run/user/1000/gnupg/S.gpg-agent.ssh

# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
input {
    kb_layout = de
    kb_variant =
    kb_model =
    kb_options = caps:swapescape
    kb_rules =

    follow_mouse = 1

    touchpad {
        natural_scroll = no
    }

    sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
}

general {
    # See https://wiki.hyprland.org/Configuring/Variables/ for more

    gaps_in = 15
    gaps_out = 20
    border_size = 2
    col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
    col.inactive_border = rgba(595959aa)

    layout = master

    # Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
    allow_tearing = false
}

decoration {
    # See https://wiki.hyprland.org/Configuring/Variables/ for more

    rounding = 10
    
    blur {
        enabled = true
        size = 3
        passes = 1
    }

    drop_shadow = yes
    shadow_range = 4
    shadow_render_power = 3
    col.shadow = rgba(1a1a1aee)
}

animations {
    enabled = yes

    # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more

    bezier = myBezier, 0.05, 0.9, 0.1, 1.05

    animation = windows, 1, 7, myBezier
    animation = windowsOut, 1, 7, default, popin 80%
    animation = border, 1, 10, default
    animation = borderangle, 1, 8, default
    animation = fade, 1, 7, default
    animation = workspaces, 1, 6, default
}

dwindle {
    # See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
    pseudotile = no # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
    preserve_split = yes # you probably want this
    force_split = 0
    default_split_ratio = 1.5
}

master {
    # See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
    new_is_master = false
    orientation = center
    workspace = w[t2], layoutopt:orientation:left
    always_center_master = true
    mfact = 0.5
    special_scale_factor = 0.8
}

gestures {
    # See https://wiki.hyprland.org/Configuring/Variables/ for more
    workspace_swipe = off
}

misc {
    # See https://wiki.hyprland.org/Configuring/Variables/ for more
    force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
    vfr = true
    vrr = 1
    animate_manual_resizes = true
}

# Example windowrule v1
# windowrule = float, ^(kitty)$
# Example windowrule v2
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
#windowrulev2 = nomaximizerequest, class:.* # You'll probably like this.

# See https://wiki.hyprland.org/Configuring/Keywords/ for more
$mainMod = SUPER

# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bind = $mainMod, Q, exec, $terminal
bind = $mainMod, C, killactive, 
bind = $mainMod, M, exec, wlogout 
bind = $mainMod, E, exec, $fileManager
bind = $mainMod, V, togglefloating, 
bind = $mainMod, R, exec, $menu
bind = $mainMod SHIFT, L, exec, hyprlock
bind = $mainMod, PRINT, exec, grim -l 9 -g "`slurp`" - | swappy -f -
bind = $mainMod, P, pseudo, # dwindle
bind = $mainMod, J, togglesplit, # dwindle
bind = $mainMod, T, togglegroup,
bind = $mainMod, A, layoutmsg, swapwithmaster master
bind = $mainMod, I, layoutmsg, orientationcenter
bind = $mainMod, H, layoutmsg, orientationleft
bind = $mainMod, L, layoutmsg, orientationright

# Move focus with mainMod + arrow keys
bind = $mainMod, left, movefocus, l
bind = $mainMod, right, movefocus, r
bind = $mainMod, up, movefocus, u
bind = $mainMod, down, movefocus, d

# Move windows inside a workspace
bind = $mainMod SHIFT, a, movewindoworgroup, l
bind = $mainMod SHIFT, d, movewindoworgroup, r

# Handle tabbed windows
bind = $mainMod, tab, changegroupactive,
bind = $mainMod SHIFT, t, lockactivegroup, toggle

# Switch workspaces with mainMod + [0-9]
bind = $mainMod, 1, split:workspace, 1
bind = $mainMod, 2, split:workspace, 2
bind = $mainMod, 3, split:workspace, 3
bind = $mainMod, 4, split:workspace, 4
bind = $mainMod, 5, split:workspace, 5
bind = $mainMod, 6, split:workspace, 6
bind = $mainMod, 7, split:workspace, 7
bind = $mainMod, 8, split:workspace, 8
bind = $mainMod, 9, split:workspace, 9
bind = $mainMod, 0, split:workspace, 10

# Move active window to a workspace with mainMod + SHIFT + [0-9]
bind = $mainMod SHIFT, 1, split:movetoworkspace, 1
bind = $mainMod SHIFT, 2, split:movetoworkspace, 2
bind = $mainMod SHIFT, 3, split:movetoworkspace, 3
bind = $mainMod SHIFT, 4, split:movetoworkspace, 4
bind = $mainMod SHIFT, 5, split:movetoworkspace, 5
bind = $mainMod SHIFT, 6, split:movetoworkspace, 6
bind = $mainMod SHIFT, 7, split:movetoworkspace, 7
bind = $mainMod SHIFT, 8, split:movetoworkspace, 8
bind = $mainMod SHIFT, 9, split:movetoworkspace, 9
bind = $mainMod SHIFT, 0, split:movetoworkspace, 10

# Example special workspace (scratchpad)
bind = ALT SHIFT, RETURN, togglespecialworkspace, magic
bind = $mainMod SHIFT, S, movetoworkspace, special:magic

# Scroll through existing workspaces with mainMod + scroll
bind = $mainMod, mouse_down, workspace, e+1
bind = $mainMod, mouse_up, workspace, e-1

# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow

# Autostart
exec-once = hyprctl dispatch togglespecialworkspace; sleep 1; $terminal; hyprctl dispatch layoutmsg orientationleft; hyprctl dispatch togglespecialworkspace
exec-once = hyprpaper
exec-once = waybar
exec-once = daemon syncthing serve
exec-once = hypridle &
exec-once = swaync &
exec-once = emacs --daemon
exec-once = hyprctl plugin load "$(find /gnu/store/ -name 'libhyprsplit.so' | head -n1)"

Wallpaper via Hyprpaper

 preload = /home/zilti/config/wallpapers/Next/contents/images/5120x2880.png
 wallpaper = ,/home/zilti/config/wallpapers/Next/contents/images/5120x2880.png
 splash = true

Main configuration

  (feature
   (name 'hyprland)
   (root-packages 'hyprland-xwayland)
   (packages '(hyprcursor
               hyprpaper
               hypridle
               hyprlock
               hyprland-xwayland-plugin-hyprsplit)))

Operating System Definitions

File System

Update the file system labels:

  # XFS
  xfs_io -c "label -s NEWLABEL" /
  # FAT
  fatlabel /dev/device NEWLABEL
  (file-systems (append (list
                         (file-system
                          (device (file-system-label "EFI"))
                          (mount-point "/boot/efi")
                          (type "vfat"))
                         (file-system
                          (device (file-system-label "guix"))
                          (mount-point "/")
                          (type "xfs")))
                        %base-file-systems))
  (swap-devices
   (list (swap-space (target (file-system-label "swap")))))

Channels

This adds useful package channels.

  (cons* (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"))))
         (channel
           (name 'emacs)
           (url "https://github.com/babariviere/guix-emacs")
           (introduction
            (make-channel-introduction
             "72ca4ef5b572fea10a4589c37264fa35d4564783"
             (openpgp-fingerprint
              "261C A284 3452 FB01 F6DF  6CF4 F9B7 864F 2AB4 6F18"))))
         (channel
           (name 'rosenthal)
           (url "https://codeberg.org/hako/rosenthal.git")
           (branch "trunk")
           (introduction
            (make-channel-introduction
             "7677db76330121a901604dfbad19077893865f35"
             (openpgp-fingerprint
              "13E7 6CD6 E649 C28C 3385  4DF5 5E5A A665 6149 17F7"))))
         (channel
           (name 'ziltis-channel)
           (url "https://gitea.lyrion.ch/zilti/guixchannel"))
         %default-channels)

Here are the corresponding pubkeys:

  (public-key 
   (ecc 
    (curve Ed25519)
    (q #C1FD53E5D4CE971933EC50C9F307AE2171A2D3B52C804642A7A35F84F3A4EA98#)
    )
   )
  (public-key 
   (ecc 
    (curve Ed25519)
    (q #8D156F295D24B0D9A86FA5741A840FF2D24F60F7B6C4134814AD55625971B394#)
    )
   )
  (public-key 
   (ecc 
    (curve Ed25519)
    (q #7D602902D3A2DBB83F8A0FB98602A754C5493B0B778C8D1DD4E0F41DE14DE34F#)
    )
   )

Modules

There are many community modules at Whereis.

  • gnu
  • gnu image
  • gnu system nss
  • guix channels
  • rosenthal packages wm
  • zilti packages hyprland
  • nongnu packages firmware
  • nongnu packages linux
  • nongnu system linux-initrd
Service Modules
  • admin
  • authentication
  • base
  • configuration
  • dbus
  • desktop
  • docker
  • linux
  • networking
  • nix
  • pm
  • sddm
  • sound
  • virtualization
  • xorg
Package Modules
  • bootloaders
  • certs
  • containers
  • freedesktop
  • fonts
  • gl
  • gnome
  • kde-frameworks
  • linux
  • pciutils
  • qt
  • readline
  • terminals
  • version-control
  • virtualization
  • wm
  • xdisorg
  • xorg

Root Packages

  • bluez-firmware
  • egl-gbm
  • egl-wayland
  • eglexternalplatform
  • font-terminus
  • fwupd-nonfree
  • git
  • glu
  • hwdata
  • hyprland-xwayland
  • i915-firmware
  • libdrm
  • libglvnd
  • linux-pam
  • mesa
  • nss-certs
  • network-manager
  • kwayland
  • qtwayland
  • readline
  • tuxedo-keyboard
  • xdg-desktop-portal-hyprland
  • xdg-desktop-portal
  • xf86-video-amdgpu
  • xf86-video-intel
  • xorg-server-xwayland
  • xorg-server
  • wayland
  • amdgpu-firmware
  • amd-microcode
  • intel-microcode
  (packages
   (append
    <<org-to-scheme-sym-list(input=root-packages)>>
    %base-packages))

Services

Simple Services

These services are unmodified, or have just few settings.

Service Options
tlp ()
thermald ((adaptive? #t))
bluetooth ()
earlyoom ((minimum-available-memory 5) (minimum-free-swap 5))
inputattach ()
libvirt ((unix-sock-group "libvirt"))
nix ()
virtlog ()
fstrim ()
fprintd ()
Unattended Upgrade Service
  (service unattended-upgrade-service-type
   (unattended-upgrade-configuration
    (schedule "5 12 * * 1")
    (channels #~
     <<root-channels>>)))
Hosts File
  (simple-service  'add-extra-hosts
                   hosts-service-type
                   (list (host "127.0.0.1" "l.redsky.io" '("ld.redsky.io"))
                         (host "::1" "l.redsky.io" '("ld.redsky.io"))))
Modified Desktop Services
Screen Locker Service

For some reason, this service runs on root level for Guix.

  (service screen-locker-service-type
           (screen-locker-configuration
            (name "swaylock")
            (program
             (file-append swaylock-effects "/bin/swaylock"))
            (using-setuid? #f)))

Operating System

This is the full operating system specification.

  (operating-system
   (host-name "ziltis-machine")
   (timezone "Europe/Berlin")
   (locale "de_DE.utf8")
   (keyboard-layout
    (keyboard-layout "de" #:options '("caps:swapescape")))
   (kernel linux)
   (initrd microcode-initrd)
   (firmware (list linux-firmware))
   (bootloader
    (bootloader-configuration
     (bootloader grub-efi-bootloader)
     (targets
      '("/boot/efi"))
     (keyboard-layout keyboard-layout)))
   #;(file-systems %local-filesystem)
   #;(swap-devices %local-swap)
    <<config-filesystems>>
    <<config-swap>>
   (users
    (cons*
     (user-account
      (name "zilti")
      (group "users")
      (supplementary-groups
       '("avahi" "users" "input" "wheel" "netdev" "audio" "cdrom" "video" "libvirt" "lp")))
     %base-user-accounts))
    <<root-package-block>>
    <<root-services-block>>
   (name-service-switch %mdns-host-lookup-nss))

Guix Home

This is the main home configuration. First, all the imports:

  • gnu packages
  • gnu packages gnupg
  • gnu packages linux
  • gnu packages shellutils
  • nongnu packages game-client
  • gnu services
  • guix gexp
  • guix channels
  • gnu home
  • gnu home services
  • gnu home services desktop
  • gnu home services gnupg
  • gnu home services guix
  • gnu home services mail
  • gnu home services mcron
  • gnu home services pm
  • gnu home services shells
  • gnu home services shepherd
  • gnu home services sound
  • gnu home services ssh
  • gnu home services syncthing