This commit is contained in:
Daniel Ziltener 2024-04-17 01:53:58 +02:00
parent 33506a3ec9
commit 3b24d44a5e
Signed by: zilti
GPG Key ID: B38976E82C9DAE42
2 changed files with 563 additions and 112 deletions

View File

@ -1,13 +1,70 @@
#+TITLE: GUIX System Configuration
#+AUTHOR: Daniel Ziltener
#+PROPERTY: scheme-implementation guile
#+PROPERTY: header-args:scheme :comments none :session *guile*
#+PROPERTY: header-args:scheme :comments none :session *guile* :prologue "(use-modules (ice-9 pretty-print))"
#+begin_src emacs-lisp :results none
(org-babel-lob-ingest "./library.org")
* 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:
#+NAME: list-sample
- Entry 1
- Entry 2
First, a function that converts org lists into guile ~use-~ calls.
#+NAME: org-list-to-use
#+begin_src scheme :var use-call="use-modules" :var entries='() :var all-parens=0 :results output
(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)))
#+end_src
* Makefile
Sometimes, I need lists of ~string->symbol~ calls.
#+NAME: org-to-scheme-sym-list
#+begin_src scheme :var input=list-sample :results output
(pretty-print
`(list ,@(map string->symbol input)))
#+end_src
*** Converting Tables
**** Services
This function converts a table of simple services into service definitions.
#+NAME: service-converter
#+begin_src scheme :var input='() :colnames yes :results output
(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)))
#+end_src
** Makefile
#+begin_src makefile :tangle Makefile
reconfigure:
@ -19,7 +76,7 @@ reconfigure:
flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
#+end_src
* System Installation Script
** System Installation Script
This is to be run after setting up the partitions.
@ -30,85 +87,380 @@ This is to be run after setting up the partitions.
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"
#+end_src
* Modules
** The Feature Record Type
There are many community modules at [[https://whereis.みんな/][Whereis]].
This record type exists to facilitate grouping together configuration related to a specific feature.
#+NAME: module-list
- gnu
- gnu image
- gnu system nss
- guix channels
- rosenthal packages wm
- zilti packages hyprland
- nongnu packages firmware
- nongnu packages linux
- nongnu system linux-initrd
#+begin_src scheme :noweb yes :exports none :results output :tangle config.scm
<<list-to-use(use-call="use-modules",entries=module-list,all-parens=1)>>
#+NAME: feature-record
#+begin_src scheme
(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 '())))
#+end_src
#+RESULTS:
Since the records get written into a separate file to be consumed later, this helper function is necessary to do exactly that:
** Service Modules
#+NAME: service-module-list
- admin
- authentication
- base
- configuration
- dbus
- desktop
- docker
- linux
- networking
- nix
- pm
- sddm
- sound
- virtualization
- xorg
#+begin_src scheme :noweb yes :exports none :results output :tangle config.scm
<<list-to-use(use-call="use-service-modules",entries=service-module-list)>>
#+NAME: record-load-helper
#+begin_src scheme :noweb strip-export
<<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>>
#+end_src
** Package Modules
And ultimately, this function turns a list of features into a list of whatever is needed at that place.
#+NAME: package-module-list
- bootloaders
- certs
- containers
- freedesktop
- fonts
- gl
- gnome
- kde-frameworks
- linux
- pciutils
- qt
- readline
- terminals
- version-control
- virtualization
- wm
- xdisorg
- xorg
#+begin_src scheme :noweb yes :exports none :results output :tangle config.scm
<<list-to-use(use-call="use-package-modules",entries=package-module-list)>>
#+NAME: features-to-list
#+begin_src scheme
(define (features->list features get-fn)
(filter
(negate unspecified?)
(fold append '()
(map get-fn
(filter
(negate unspecified?)
features)))))
#+end_src
* Configuration Definitions
** Features
** File System
*** Git
Git configuration file:
#+begin_src :tagle xdg-config/git/config :mkdir-p yes
[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
#+end_src
I am using [[https://github.com/languitar/pass-git-helper][pass-git-helper]] to use Pass for git credentials.
#+begin_src :tangle xdg-config/pass-git-helper/git-pass-mapping.ini :mkdir-p yes
[*dziltener@lyrion.ch*]
target=Privat/Mailaccount
#+end_src
Git service configuration:
#+begin_src scheme :tangle features.scm
(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")))))
#+end_src
*** Hyprland
An amazing [[https://hyprland.org/][tiling compositor for Wayland]].
#+begin_src :tangle xdg-config/hypr/hyprland.conf :mkdir-p yes
# 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)"
#+end_src
Wallpaper via Hyprpaper
#+begin_src :tangle xdg-config/hypr/hyprland.conf :mkdir-p yes
preload = /home/zilti/config/wallpapers/Next/contents/images/5120x2880.png
wallpaper = ,/home/zilti/config/wallpapers/Next/contents/images/5120x2880.png
splash = true
#+end_src
Main configuration
#+begin_src scheme :tangle features.scm
(feature
(name 'hyprland)
(root-packages 'hyprland-xwayland)
(packages '(hyprcursor
hyprpaper
hypridle
hyprlock
hyprland-xwayland-plugin-hyprsplit)))
#+end_src
** Operating System Definitions
*** File System
Update the file system labels:
#+begin_src shell
@ -138,9 +490,9 @@ Update the file system labels:
(list (swap-space (target (file-system-label "swap")))))
#+end_src
** Channels
*** Channels
This adds the Nonguix channel.
This adds useful package channels.
#+NAME: root-channels
#+begin_src scheme :tangle channels.scm
@ -176,11 +528,107 @@ This adds the Nonguix channel.
%default-channels)
#+end_src
#+RESULTS: root-channels :tangle channels.scm
Here are the corresponding pubkeys:
#+RESULTS: root-channels
#+NAME: nonguix-pubkey
#+begin_src scheme :tangle keys/non-guix.pub :mkdirp yes
(public-key
(ecc
(curve Ed25519)
(q #C1FD53E5D4CE971933EC50C9F307AE2171A2D3B52C804642A7A35F84F3A4EA98#)
)
)
#+end_src
** Packages
#+NAME: guix-ci-pubkey
#+begin_src scheme :tangle keys/guix-ci.pub :mkdirp yes
(public-key
(ecc
(curve Ed25519)
(q #8D156F295D24B0D9A86FA5741A840FF2D24F60F7B6C4134814AD55625971B394#)
)
)
#+end_src
#+NAME: guix-bordeaux-pubkey
#+begin_src scheme :tangle keys/guix-bordeaux.pub :mkdirp yes
(public-key
(ecc
(curve Ed25519)
(q #7D602902D3A2DBB83F8A0FB98602A754C5493B0B778C8D1DD4E0F41DE14DE34F#)
)
)
#+end_src
*** Modules
There are many community modules at [[https://whereis.みんな/][Whereis]].
#+NAME: module-list
- gnu
- gnu image
- gnu system nss
- guix channels
- rosenthal packages wm
- zilti packages hyprland
- nongnu packages firmware
- nongnu packages linux
- nongnu system linux-initrd
#+begin_src scheme :noweb yes :exports none :results output :tangle config.scm
<<list-to-use(use-call="use-modules",entries=module-list,all-parens=1)>>
#+end_src
**** Service Modules
#+NAME: service-module-list
- admin
- authentication
- base
- configuration
- dbus
- desktop
- docker
- linux
- networking
- nix
- pm
- sddm
- sound
- virtualization
- xorg
#+begin_src scheme :noweb yes :exports none :results output :tangle config.scm
<<list-to-use(use-call="use-service-modules",entries=service-module-list)>>
#+end_src
**** Package Modules
#+NAME: package-module-list
- bootloaders
- certs
- containers
- freedesktop
- fonts
- gl
- gnome
- kde-frameworks
- linux
- pciutils
- qt
- readline
- terminals
- version-control
- virtualization
- wm
- xdisorg
- xorg
#+begin_src scheme :noweb yes :exports none :results output :tangle config.scm
<<list-to-use(use-call="use-package-modules",entries=package-module-list)>>
#+end_src
*** Root Packages
#+NAME: root-packages
- bluez-firmware
@ -225,7 +673,7 @@ This adds the Nonguix channel.
#+RESULTS: root-package-block
** Services
*** Services
#+NAME: root-services-block
#+begin_src scheme :noweb yes :exports none :results code
@ -242,7 +690,7 @@ This adds the Nonguix channel.
<<unattended-upgrade>>)))
#+end_src
*** Simple Services
**** Simple Services
These services are unmodified, or have just few settings.
@ -265,7 +713,7 @@ These services are unmodified, or have just few settings.
<<service-converter(input=root-simple-services)>>
#+end_src
*** Unattended Upgrade Service
**** Unattended Upgrade Service
#+NAME: unattended-upgrade
#+begin_src scheme :noweb no-export
@ -276,7 +724,7 @@ These services are unmodified, or have just few settings.
<<root-channels>>)))
#+end_src
*** Hosts File
**** Hosts File
#+NAME: hosts-file-service
#+begin_src scheme :noweb no-export
@ -286,37 +734,7 @@ These services are unmodified, or have just few settings.
(host "::1" "l.redsky.io" '("ld.redsky.io"))))
#+end_src
*** Modified Desktop Services
#+NAME: nonguix-pubkey
#+begin_src scheme :tangle keys/non-guix.pub :mkdirp yes
(public-key
(ecc
(curve Ed25519)
(q #C1FD53E5D4CE971933EC50C9F307AE2171A2D3B52C804642A7A35F84F3A4EA98#)
)
)
#+end_src
#+NAME: guix-ci-pubkey
#+begin_src scheme :tangle keys/guix-ci.pub :mkdirp yes
(public-key
(ecc
(curve Ed25519)
(q #8D156F295D24B0D9A86FA5741A840FF2D24F60F7B6C4134814AD55625971B394#)
)
)
#+end_src
#+NAME: guix-bordeaux-pubkey
#+begin_src scheme :tangle keys/guix-bordeaux.pub :mkdirp yes
(public-key
(ecc
(curve Ed25519)
(q #7D602902D3A2DBB83F8A0FB98602A754C5493B0B778C8D1DD4E0F41DE14DE34F#)
)
)
#+end_src
**** Modified Desktop Services
#+NAME: root-modified-desktop-services
#+begin_src scheme :exports none :results code :noweb no-export
@ -336,7 +754,7 @@ These services are unmodified, or have just few settings.
%default-authorized-guix-keys)))))
#+end_src
*** Screen Locker Service
**** Screen Locker Service
For some reason, this service runs on root level for Guix.
@ -350,7 +768,7 @@ For some reason, this service runs on root level for Guix.
(using-setuid? #f)))
#+end_src
* Operating System
*** Operating System
This is the full operating system specification.
@ -386,3 +804,35 @@ This is the full operating system specification.
<<root-services-block>>
(name-service-switch %mdns-host-lookup-nss))
#+end_src
** Guix Home
This is the main home configuration. First, all the imports:
#+NAME: home-module-list
- 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
#+begin_src scheme :noweb yes :exports none :results output :mkdir-p yes :tangle home/home-configuration.scm
<<list-to-use(use-call="use-modules",entries=home-module-list,all-parens=1)>>
#+end_src

View File

@ -31,8 +31,7 @@
(home-environment
;; Below is the list of Home services. To search for available
;; services, run 'guix home search KEYWORD' in a terminal.
(
services
(services
(list
(service home-shepherd-service-type)
(service home-msmtp-service-type
@ -273,4 +272,6 @@ services
(service home-dbus-service-type)
(service home-pipewire-service-type
(home-pipewire-configuration
(wireplumber wireplumber-minimal))))))
(wireplumber wireplumber-minimal)))
)
))