(define-module (tw home) #:use-module (ice-9 string-fun) #:use-module (gnu) #:use-module (gnu home services) #:use-module (gnu home services desktop) #:use-module (gnu home services shells) #:use-module (gnu home services shepherd) #:use-module (gnu home services ssh) #:use-module ((gnu packages admin) #:select (fdupes smartmontools tree)) #:use-module ((gnu packages android) #:select (adb fastboot)) #:use-module ((gnu packages backup) #:select (restic)) #:use-module ((gnu packages compression) #:select (zip unzip)) #:use-module ((gnu packages curl) #:select (curl)) #:use-module ((gnu packages databases) #:select (recutils)) #:use-module ((gnu packages disk) #:select (ranger)) #:use-module ((gnu packages dns) #:select (isc-bind)) #:use-module ((gnu packages file) #:select (file)) #:use-module ((gnu packages finance) #:select (hledger)) #:use-module ((gnu packages gnupg) #:select (gnupg)) #:use-module ((gnu packages graphviz) #:select (graphviz)) #:use-module ((gnu packages imagemagick) #:select (imagemagick)) #:use-module ((gnu packages less) #:select (less lesspipe)) #:use-module ((gnu packages linux) #:select (net-tools)) #:use-module ((gnu packages lisp) #:select (sbcl)) #:use-module ((gnu packages maths) #:select (gnuplot)) #:use-module ((gnu packages music) #:select (beets cmus)) #:use-module ((gnu packages ncdu) #:select (ncdu ncdu)) #:use-module ((gnu packages password-utils) #:select (password-store pass-otp)) #:use-module ((gnu packages pretty-print) #:select (source-highlight)) #:use-module ((gnu packages pv) #:select (pv)) #:use-module ((gnu packages python) #:select (python)) #:use-module ((gnu packages python-xyz) #:select (python-ipython python-pygments python-pillow python-pdftotext)) #:use-module ((gnu packages rsync) #:select (rsync)) #:use-module ((gnu packages shells) #:select (zsh)) #:use-module ((gnu packages shellutils) #:select (zsh-autosuggestions zsh-history-substring-search zsh-syntax-highlighting zsh-completions)) #:use-module ((gnu packages ssh) #:select (openssh)) #:use-module ((gnu packages textutils) #:select (dos2unix)) #:use-module ((gnu packages tls) #:select (openssl)) #:use-module ((gnu packages tmux) #:select (tmux)) #:use-module ((gnu packages version-control) #:select (diffstat git)) #:use-module ((gnu packages video) #:select (get-iplayer ffmpeg atomicparsley yt-dlp mediainfo)) #:use-module ((gnu packages vim) #:select (xxd)) #:use-module ((gnu packages web) #:select (jq)) #:use-module (gnu services configuration) #:use-module (guix gexp) #:use-module (guix packages) #:use-module (guix records) #:use-module (tw services restic) #:use-module (tw system)) (define (basic-packages config) ;; Basic packages to install everywhere, including servers. (list curl diffstat dos2unix fdupes file git gnupg gnuplot graphviz hledger imagemagick jq less lesspipe ncdu net-tools openssh openssl password-store pass-otp pv python python-ipython recutils restic rsync sbcl smartmontools source-highlight tmux tree xxd zip unzip adb fastboot beets cmus get-iplayer ffmpeg atomicparsley yt-dlp ;; Install only bind-utils like dig, not the full suite. (list isc-bind "utils") ;; Ranger can do code highlighting using python-pygments and ;; image previews in kitty using python-pillow. ranger python-pygments python-pillow mediainfo python-pdftotext ;; Shell zsh zsh-autosuggestions zsh-history-substring-search zsh-syntax-highlighting zsh-completions)) (define (xdg-configs config) "Configuration files for terminal programs." `(("htop/htoprc" ,(local-file "home/files/htoprc")) ("lesskey" ,(local-file "home/files/lesskey")) ("ranger/rc.conf" ,(local-file "home/files/ranger.conf")) ("tmux/tmux.conf" ,(local-file "home/files/tmux.conf")) ("user-dirs.locale" ,(plain-file "user-dirs.locale" "C")) ; Not sure if this is needed. Arch has it. ("user-dirs.dirs" ,(local-file "home/files/user-dirs.dirs")))) (define (non-xdg-configs config) "Configuration files for terminal programs that do not follow the XDG base dir spec." `((".infokey" ,(local-file "home/files/infokey")) (".local/bin/python" ,(file-append python "/bin/python3")) ;; With #:recursive? #t, Guix keeps the files' permission bits, i.e. makes them executable. (".local/bin/ppscm" ,(local-file "home/files/ppscm" #:recursive? #t)))) ; pretty-print scheme files (define (zshrc config) "Extend the home ZSH service to install my custom zshrc." ;; `home-zsh-configuration's are merged, so we can extend `home-zsh-service-type'. (home-zsh-extension (zshrc (list (local-file "home/files/zshrc") (local-file "home/files/prompt.zsh"))))) (define (environment-variables config) "Configure my shell environment." `(;; Common environment everywhere. ;; Prepend my own binaries to $PATH. These should probably all ;; be managed through `home-files-service-type'. ("PATH" . "$HOME/.local/bin${PATH:+:}$PATH") ;; Default terminal-related applications (except Emacs, which is separate). ("PAGER" . "less") ;; Guix force-overrides $LESS by default, so force-force it to do what I ;; want instead. `less' reads the `lesskey' file configured above. ("GUIX_PAGER" . "env -u LESS less") ;; To make LESS_TERMCAP_* variables (set in lesskey) apply to man pages in kitty. ("GROFF_NO_SGR" . "1") ;; Shell history -- primarily for zsh, but Emacs' eshell uses this too. ("HISTSIZE" . "10000000") ("LEDGER_FILE" . "$HOME/sync/ledger/ledger.journal") ("GTAGSLABEL" . "pygments") ;; Disable at-spi-dbus-launcher accessibility service. ("NO_AT_BRIDGE" . "1") ;; Auto-compilation is annoying and creates a bunch of files that are never cleaned up. ("GUILE_AUTO_COMPILE" . "0") ;; XDG basedir spec compliance for various programs. ;; See: https://wiki.archlinux.org/index.php/XDG_Base_Directory for a list of programs. ;; The `home-xdg-base-directories' service (enabled by default) sets $XDG_* variables for us. ("ANDROID_EMULATOR_HOME" . "$XDG_DATA_HOME/android-emulator") ("ASPELL_CONF" . "per-conf $XDG_CONFIG_HOME/aspell/aspell.conf; home-dir $XDG_DATA_HOME/aspell") ("BUP_DIR" . "$XDG_DATA_HOME/bup") ("CARGO_HOME" . "$XDG_DATA_HOME/cargo") ("ELECTRUMDIR" . "$XDG_DATA_HOME/electrum") ("FG_HOME" . "$XDG_DATA_HOME/fgfs") ("GETIPLAYERUSERPREFS" . "$XDG_DATA_HOME/get_iplayer") ("GTK2_RC_FILES" . "$XDG_CONFIG_HOME/gtk-2.0/gtkrc") ("ICEAUTHORITY" . "$XDG_CACHE_HOME/ICEauthority") ("INPUTRC" . "$XDG_CONFIG_HOME/readline/inputrc") ("IPYTHONDIR" . "$XDG_CONFIG_HOME/ipython") ("JUPYTER_CONFIG_DIR" . "$XDG_CONFIG_HOME/jupyter") ;; KONAN_DATA_DIR=~/.konan by default; grows to multiple GiB. ;; https://discuss.kotlinlang.org/t/change-konan-folder-location/18309 ("KONAN_DATA_DIR" . "$XDG_CACHE_HOME/konan") ("NPM_CONFIG_USERCONFIG" . "$XDG_CONFIG_HOME/npm/npmrc") ("PASSWORD_STORE_DIR" . "$XDG_DATA_HOME/password-store") ("PYLINTHOME" . "$XDG_CACHE_HOME/pylint") ("PYLINTRC" . "$XDG_CONFIG_HOME/pylint/pylintrc") ("RECOLL_CONFDIR" . "$XDG_CONFIG_HOME/recoll") ("RLWRAP_HOME" . "$XDG_DATA_HOME/rlwrap") ("STACK_ROOT" . "$XDG_DATA_HOME/stack") ("TMUX_TMPDIR" . "$XDG_RUNTIME_DIR") ("WEECHAT_HOME" . "$XDG_CONFIG_HOME/weechat") ("XCOMPOSECACHE" . "$XDG_CACHE_HOME/X11/XCompose") ("XCOMPOSEFILE" . "$XDG_CONFIG_HOME/X11/XCompose") ("ZDOTDIR" . "$XDG_CONFIG_HOME/zsh") ("_JAVA_OPTIONS" . "$_JAVA_OPTIONS${_JAVA_OPTIONS:+ }-Djava.util.prefs.userRoot=$XDG_CONFIG_HOME/java"))) (define-public tw-home-service-type (service-type (name 'tw-home) (description "Set up a basic, uniform home environment for my machines.") (default-value #f) (extensions (list (service-extension home-profile-service-type basic-packages) (service-extension home-zsh-service-type zshrc) (service-extension home-xdg-configuration-files-service-type xdg-configs) (service-extension home-files-service-type non-xdg-configs) (service-extension home-environment-variables-service-type environment-variables))))) ;;; Restic backup helpers (define-public (restic-pass-key key) (restic-password-source (type 'pass) (name key))) (define-public (restic-vin.wg-repo path) (restic-rest-repository (username "timo") (password (restic-pass-key "computers/vin/restic-server/timo")) (hostname "vin.wg") (port 8181) (path path))) ;;; OpenSSH configuration ;; Since we specify the entire `home-openssh-configuration', we cannot make ;; this a service extension. (define (wireguardify host) (string-replace-substring host ".twilken.net" ".wg")) (define (make-own-ssh-host host port) (openssh-host (name host) (port port) (user "timo"))) (export tw-openssh-configuration) (define* (tw-openssh-configuration #:key (default-ssh-key "~/.local/share/ssh-keys/id_ed25519") (cern-ssh-key "~/.local/share/ssh-keys/cern_id_rsa")) (let ((no-proxy (list (proxy-jump (host-name "none"))))) (home-openssh-configuration (hosts ;; Earlier rules take precedence over later ones. `(,(openssh-host (name "*.srcf.net") (user "tw466")) ;; My own machines ,@(map make-own-ssh-host (map car %ssh-ports) (map cdr %ssh-ports)) ,@(map make-own-ssh-host (map (compose wireguardify car) %ssh-ports) (map cdr %ssh-ports)) ,(openssh-host (name "*.fritz.box") (proxy (list (proxy-jump (host-name "lud.twilken.net"))))) ;; Git hosts ,(openssh-host (name "git.twilken.net") (user "git") ;; git.twilken.net is a CNAME to lud.twilken.net. (port (assoc-ref %ssh-ports "lud.twilken.net"))) ,(openssh-host (name "github.com") (user "git")) ,(openssh-host (name "ssh.github.com") (user "git")) ,(openssh-host (name "gitlab.cern.ch") (user "git") (port 7999) (proxy no-proxy)) ;; CERN stuff ,(openssh-host (name "lxtunnel.cern.ch") (proxy no-proxy) ; avoid ProxyJump loops ;; Share a single connection to lxtunnel, to speed up subsequent ;; connections to the GPN. Keep it open for a few minutes after ;; the last user connection exits, in case we need it again. (extra-content "\ ControlMaster auto ControlPath ${XDG_RUNTIME_DIR}/ssh_mux_%h_%p_%r ControlPersist 5m ")) ;; No proxying needed. aiadm even refuses connections via lxtunnel. ,(openssh-host (name "lxplus*.cern.ch") (proxy no-proxy)) ,(openssh-host (name "aiadm.cern.ch") (proxy no-proxy)) ,(openssh-host (name "*.cern.ch") (user "twilken") (identity-file cern-ssh-key) (proxy (list (proxy-jump (host-name "lxtunnel.cern.ch")))) ;; Delegated credentials are needed for EOS home mount on some systems. (extra-content " GSSAPIAuthentication yes\n GSSAPIDelegateCredentials yes")) ;; Default SSH key. This isn't in ~/.ssh as `home-openssh-service-type' ;; manages that and might delete keys there. ,(openssh-host (name "*") (identity-file default-ssh-key) ;; Remote servers probably don't know about kitty or foot. (extra-content " SetEnv TERM=xterm-256color")))))))