summaryrefslogtreecommitdiff
path: root/tw
diff options
context:
space:
mode:
authorTimo Wilken2023-09-12 19:42:21 +0200
committerTimo Wilken2023-09-12 21:18:32 +0200
commitd44b9efda2d387430e63c1d6cd426c88bcde2eda (patch)
treedb7973a37a88c439362e7311148e7275d27352fa /tw
parent340d839c2c4ff47ce047e63969c43393b7a335dc (diff)
Factor out proper Git and GnuPG service types
Diffstat (limited to 'tw')
-rw-r--r--tw/home.scm132
-rw-r--r--tw/home/cern.scm15
-rw-r--r--tw/home/lap.scm22
-rw-r--r--tw/services/git.scm108
-rw-r--r--tw/services/gnupg.scm94
5 files changed, 232 insertions, 139 deletions
diff --git a/tw/home.scm b/tw/home.scm
index 026c41d8..4065cf3b 100644
--- a/tw/home.scm
+++ b/tw/home.scm
@@ -48,60 +48,6 @@
zsh zsh-autosuggestions zsh-history-substring-search
zsh-syntax-highlighting zsh-completions))
-(export gnupg-services) ; there doesn't seem to be a `define*-public' macro
-(define* (gnupg-services default-key #:key gui-pinentry?)
- (list
- (simple-service 'gnupg-config home-files-service-type
- `(;; GnuPG config files must be in ~/.local/share/gnupg, not ~/.config,
- ;; so we can't use `home-xdg-configuration-files-service-type'.
- (".local/share/gnupg/dirmngr.conf"
- ,(plain-file "dirmngr.conf" "keyserver hkps://keys.openpgp.org"))
- (".local/share/gnupg/gpg.conf"
- ,(mixed-text-file "gpg.conf" "\
-# This options file can contain any long options to GnuPG.
-# See the gpg man page for a list of options.
-
-default-key " default-key "
-default-recipient-self
-use-agent
-no-greeting # get rid of the copyright notice
-# Always encrypt to my key as well, in addition to any recipient.
-encrypt-to " default-key "
-auto-key-import
-auto-key-retrieve
-photo-viewer \"" imv "/bin/imv %i\"
-
-# Because some mailers change lines starting with 'From ' to '>From '
-# it is good to handle such lines in a special way when creating
-# cleartext signatures; all other PGP versions do it this way too.
-# To enable full OpenPGP compliance you may want to use this option.
-#no-escape-from-lines
-"))
- (".local/share/gnupg/gpg-agent.conf"
- ,(mixed-text-file "gpg-agent.conf" "\
-pinentry-program " (if gui-pinentry?
- (file-append pinentry-rofi "/bin/pinentry-rofi")
- (file-append pinentry-tty "/bin/pinentry-tty")) "
-# Keep passphrase cached for longer, so that mcron jobs (e.g. restic,
-# vdirsyncer) can access the password store. Vdirsyncer should run every half
-# hour to extend the default-cache-ttl.
-default-cache-ttl 2100 # 35 min
-max-cache-ttl 43200 # 12 h
-# Needed if spawning lots of parallel gpg --decrypt processes. https://dev.gnupg.org/T3530
-auto-expand-secmem
-"))))
-
- (simple-service 'gnupg-agent home-shepherd-service-type
- (list
- (shepherd-service
- (documentation "GPG agent; caches key passwords.")
- (provision '(gpg-agent))
- (start #~(lambda _
- (invoke #$(file-append gnupg "/bin/gpg-agent")
- "--daemon" "--no-detach")))
- (stop #~(lambda _
- (invoke "gpg-connect-agent" "killagent" "/bye"))))))))
-
(define (wireguardify host)
(string-replace-substring host ".twilken.net" ".wg"))
@@ -277,7 +223,6 @@ auto-expand-secmem
("ELECTRUMDIR" . "$XDG_DATA_HOME/electrum")
("FG_HOME" . "$XDG_DATA_HOME/fgfs")
("GETIPLAYERUSERPREFS" . "$XDG_DATA_HOME/get_iplayer")
- ("GNUPGHOME" . "$XDG_DATA_HOME/gnupg")
("GTK2_RC_FILES" . "$XDG_CONFIG_HOME/gtk-2.0/gtkrc")
("ICEAUTHORITY" . "$XDG_CACHE_HOME/ICEauthority")
("INPUTRC" . "$XDG_CONFIG_HOME/readline/inputrc")
@@ -610,80 +555,3 @@ show_border=1
(".local/bin/volume" ,(local-file "home/files/volume" #:recursive? #t))
(".local/share/applications/emacsclient.desktop"
,(local-file "home/files/emacsclient.desktop"))))))
-
-(define gitconfig-includes
- (match-lambda
- (() '())
- (((name path _ _) rest ...)
- ;; The relative path is relative to the gitconfig file.
- (cons (format #f "[includeIf \"gitdir:~a/**\"]\n\tpath = ~aconfig"
- (string-trim-right path #\/) name)
- (gitconfig-includes rest)))
- ((id rest ...)
- (cons (format #f "# warning: ignored malformed identity: ~s" id)
- (gitconfig-includes rest)))))
-
-(define gitconfig-otherfiles
- (match-lambda
- (() '())
- (((name _ email signing-key) rest ...)
- `((,(string-append "git/" name "config")
- ,(plain-file (string-append "git" name "config")
- (string-append
- "[user]\n"
- (if email (string-append "\temail = " email "\n") "")
- (if signing-key (string-append "\tsigningkey = " signing-key "\n") ""))))
- ,@(gitconfig-otherfiles rest)))
- ((id rest ...)
- (format (current-error-port) "warning: ignored malformed gitconfig identity: ~s~%" id)
- (gitconfig-otherfiles rest))))
-
-(export gitconfig)
-(define* (gitconfig default-email default-signing-key #:rest identities)
- (simple-service 'gitconfig home-xdg-configuration-files-service-type
- `(,@(gitconfig-otherfiles identities)
- ("git/config" ,(mixed-text-file "gitconfig" "\
-# This is Git's per-user configuration file.
-[user]
- name = Timo Wilken
- email = " default-email "
- signingkey = " default-signing-key
- (string-join (gitconfig-includes identities) "\n" 'prefix) "
-[commit]
- gpgsign = true
-[url \"ssh://git@gitlab.cern.ch:7999/\"]
- insteadOf = https://gitlab.cern.ch/
-[url \"ssh://git@ssh.github.com/\"]
- insteadOf = gh:
-[gui]
- fontui = -family \\\"Fira Sans\\\" -size 10 -weight normal -slant roman -underline 0 -overstrike 0
- fontdiff = -family \\\"Hermit\\\" -size 10 -weight normal -slant roman -underline 0 -overstrike 0
- tabsize = 4
-[merge]
- summary = true
- conflictstyle = diff3
-[color]
- ui = auto
-[pull]
- rebase = false
- ff = only
-[alias]
- glog = log --decorate --graph --oneline
- plog = log --decorate --graph --oneline --pretty=tformat:\\\"%C(yellow)%h %Cgreen%as %Cblue%<(10,trunc)%an%Cred%d%Creset %s\\\"
-[init]
- defaultBranch = master
-[advice]
- detachedHead = false
- addEmptyPathspec = false
-# https://sw.kovidgoyal.net/kitty/kittens/diff/
-[diff]
- tool = kitty
- guitool = kitty.gui
-[difftool]
- prompt = false
- trustExitCode = true
-[difftool \"kitty\"]
- cmd = " kitty "/bin/kitty +kitten diff $LOCAL $REMOTE
-[difftool \"kitty.gui\"]
- cmd = " kitty "/bin/kitty " kitty "/bin/kitty +kitten diff $LOCAL $REMOTE
-")))))
diff --git a/tw/home/cern.scm b/tw/home/cern.scm
index f0dc7214..8c6ed7d5 100644
--- a/tw/home/cern.scm
+++ b/tw/home/cern.scm
@@ -30,6 +30,8 @@
#:use-module (tw packages catppuccin)
#:use-module (tw packages xorg)
#:use-module (tw gexp)
+ #:use-module (tw services git)
+ #:use-module (tw services gnupg)
#:use-module (tw theme))
(use-package-modules calendar dav mail web-browsers xdisorg xorg)
@@ -128,11 +130,18 @@
"/X11/ridge-view.jpg")))))))
;; On my work machine, Git must always use my work PGP key.
- (gitconfig "timo.wilken@cern.ch" "C2249BBE5E8761C943A0CFA1B7B3914BF63ACD7C")
+ (service home-git-service-type
+ (home-git-configuration
+ (default-email "timo.wilken@cern.ch")
+ (default-signing-key "C2249BBE5E8761C943A0CFA1B7B3914BF63ACD7C")))
(openssh-service #f)
- (append %common-services %interactive-services pim-services
- (gnupg-services "C2249BBE5E8761C943A0CFA1B7B3914BF63ACD7C" #:gui-pinentry? #t))))))
+ (service home-gnupg-service-type
+ (home-gnupg-configuration
+ (default-key "C2249BBE5E8761C943A0CFA1B7B3914BF63ACD7C")
+ (gui-pinentry? #t)))
+
+ (append %common-services %interactive-services pim-services)))))
%cern-home
diff --git a/tw/home/lap.scm b/tw/home/lap.scm
index c166c75e..ae5fb629 100644
--- a/tw/home/lap.scm
+++ b/tw/home/lap.scm
@@ -38,6 +38,8 @@
#:use-module ((nongnu packages steam-client)
#:select (steam))
#:use-module (tw home)
+ #:use-module (tw services git)
+ #:use-module (tw services gnupg)
#:use-module (tw packages scanner)
#:use-module (tw services restic)
#:use-module (tw theme))
@@ -202,12 +204,24 @@
;; On my private machine, I want to use my private PGP key normally, and
;; my work key only for work repositories.
- (gitconfig "git@twilken.net" "53EC3C06856883DD92355BC22FC78504681F69B0"
- '("cern" "~/src/alice" "timo.wilken@cern.ch" "C2249BBE5E8761C943A0CFA1B7B3914BF63ACD7C"))
+ (service home-git-service-type
+ (home-git-configuration
+ (default-email "git@twilken.net")
+ (default-signing-key "53EC3C06856883DD92355BC22FC78504681F69B0")
+ (identities
+ (list (home-git-identity
+ (name "cern")
+ (root-directory "~/src/alice")
+ (email "timo.wilken@cern.ch")
+ (signing-key "C2249BBE5E8761C943A0CFA1B7B3914BF63ACD7C"))))))
(openssh-service #t)
- (append pim-services %interactive-services %common-services
- (gnupg-services "53EC3C06856883DD92355BC22FC78504681F69B0" #:gui-pinentry? #t))))))
+ (service home-gnupg-service-type
+ (home-gnupg-configuration
+ (default-key "53EC3C06856883DD92355BC22FC78504681F69B0")
+ (gui-pinentry? #t)))
+
+ (append pim-services %interactive-services %common-services)))))
%lap-home
diff --git a/tw/services/git.scm b/tw/services/git.scm
new file mode 100644
index 00000000..69dae1e8
--- /dev/null
+++ b/tw/services/git.scm
@@ -0,0 +1,108 @@
+(define-module (tw services git)
+ #:use-module (gnu)
+ #:use-module (gnu home services)
+ #:use-module (gnu packages terminals)
+ #:use-module (gnu packages version-control)
+ #:use-module (gnu services configuration)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module ((guix records) #:select (match-record))
+ #:use-module (srfi srfi-1)
+ #:export (home-git-identity
+ home-git-configuration
+ home-git-service-type))
+
+(define-configuration/no-serialization home-git-identity
+ (name string "Short slug identifying this identity. Only used to name config files.")
+ (root-directory string "Directory under which this identity should apply.")
+ (email string "Author commits as this email for this identity.")
+ (signing-key string "Sign commits using this key for this identity."))
+
+(define (list-of-identities? thing)
+ (and (list? thing) (every home-git-identity? thing)))
+
+(define-configuration/no-serialization home-git-configuration
+ (default-email string "Author git commits as this email.")
+ (default-signing-key string "Sign git commits using this email.")
+ (identities (list-of-identities '()) "Override default configuration values
+under specific directories, e.g. to use a work identity in a directory
+containing work projects."))
+
+(define (gitconfig-includes identities)
+ (if (null? identities) '()
+ (cons (match-record (car identities) <home-git-identity>
+ (name root-directory)
+ ;; A relative path is relative to the gitconfig file.
+ (format #f "[includeIf \"gitdir:~a/**\"]\n\tpath = ~aconfig"
+ (string-trim-right root-directory #\/) name))
+ (gitconfig-includes (cdr identities)))))
+
+(define (gitconfig-otherfiles identities)
+ (if (null? identities) '()
+ (cons (match-record (car identities) <home-git-identity>
+ (name email signing-key)
+ (list
+ (string-append "git/" name "config")
+ (plain-file (string-append "git" name "config")
+ (string-append
+ "[user]\n"
+ (if email (string-append "\temail = " email "\n") "")
+ (if signing-key (string-append "\tsigningkey = " signing-key "\n") "")))))
+ (gitconfig-otherfiles (cdr identities)))))
+
+(define (gitconfig config)
+ (match-record config <home-git-configuration>
+ (default-email default-signing-key identities)
+ `(,@(gitconfig-otherfiles identities)
+ ("git/config" ,(mixed-text-file "gitconfig" "\
+# This is Git's per-user configuration file.
+[user]
+ name = Timo Wilken
+ email = " default-email "
+ signingkey = " default-signing-key
+ (string-join (gitconfig-includes identities) "\n" 'prefix) "
+[commit]
+ gpgsign = true
+[url \"ssh://git@gitlab.cern.ch:7999/\"]
+ insteadOf = https://gitlab.cern.ch/
+[url \"ssh://git@ssh.github.com/\"]
+ insteadOf = gh:
+[gui]
+ fontui = -family \\\"Fira Sans\\\" -size 10 -weight normal -slant roman -underline 0 -overstrike 0
+ fontdiff = -family \\\"Hermit\\\" -size 10 -weight normal -slant roman -underline 0 -overstrike 0
+ tabsize = 4
+[merge]
+ summary = true
+ conflictstyle = diff3
+[color]
+ ui = auto
+[pull]
+ rebase = false
+ ff = only
+[alias]
+ glog = log --decorate --graph --oneline
+ plog = log --decorate --graph --oneline --pretty=tformat:\\\"%C(yellow)%h %Cgreen%as %Cblue%<(10,trunc)%an%Cred%d%Creset %s\\\"
+[init]
+ defaultBranch = master
+[advice]
+ detachedHead = false
+ addEmptyPathspec = false
+# https://sw.kovidgoyal.net/kitty/kittens/diff/
+[diff]
+ tool = kitty
+ guitool = kitty.gui
+[difftool]
+ prompt = false
+ trustExitCode = true
+[difftool \"kitty\"]
+ cmd = " kitty "/bin/kitty +kitten diff $LOCAL $REMOTE
+[difftool \"kitty.gui\"]
+ cmd = " kitty "/bin/kitty " kitty "/bin/kitty +kitten diff $LOCAL $REMOTE
+")))))
+
+(define home-git-service-type
+ (service-type
+ (name 'git)
+ (extensions
+ (list (service-extension home-xdg-configuration-files-service-type gitconfig)))
+ (description "Configure Git.")))
diff --git a/tw/services/gnupg.scm b/tw/services/gnupg.scm
new file mode 100644
index 00000000..9b358ea4
--- /dev/null
+++ b/tw/services/gnupg.scm
@@ -0,0 +1,94 @@
+(define-module (tw services gnupg)
+ #:use-module (gnu)
+ #:use-module (gnu home services)
+ #:use-module (gnu home services shepherd)
+ #:use-module (gnu packages gnupg)
+ #:use-module ((gnu packages image-viewers)
+ #:select (imv))
+ #:use-module (gnu services configuration)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module ((guix records) #:select (match-record))
+ #:export (home-gnupg-configuration
+ home-gnupg-service-type))
+
+(define-configuration/no-serialization home-gnupg-configuration
+ (default-key string "The user's own key. Always encrypt to this key, and
+use it by default.")
+ (gui-pinentry? boolean "Use pinentry-rofi if true, else pinentry-tty.")
+ (keyserver (string "hkps://keys.openpgp.org") "The default keyserver to use.")
+ (gnupg (package gnupg) "The GnuPG package to use.")
+ (image-viewer (file-like (file-append imv "/bin/imv")) "A gexp returning a
+string, specifying the command to call in order to view images.")
+ (gnupghome (string "$XDG_DATA_HOME/gnupg") "The value of $GNUPGHOME in the
+environment."))
+
+(define (gnupg-xdg config)
+ `(("GNUPGHOME" . ,(home-gnupg-configuration-gnupghome config))))
+
+(define (gnupg-files config)
+ (match-record config <home-gnupg-configuration>
+ (default-key gui-pinentry? keyserver image-viewer)
+ `(;; GnuPG config files must be in ~/.local/share/gnupg, not ~/.config,
+ ;; so we can't use `home-xdg-configuration-files-service-type'.
+ (".local/share/gnupg/dirmngr.conf"
+ ,(mixed-text-file "dirmngr.conf"
+ "keyserver " keyserver "\n"))
+ (".local/share/gnupg/gpg.conf"
+ ,(mixed-text-file "gpg.conf" "\
+# This options file can contain any long options to GnuPG.
+# See the gpg man page for a list of options.
+# Comments can only be at the start of a line, not after options.
+
+default-key " default-key "
+default-recipient-self
+use-agent
+# Get rid of the copyright notice.
+no-greeting
+# Always encrypt to my key as well, in addition to any recipient.
+encrypt-to " default-key "
+auto-key-import
+auto-key-retrieve
+photo-viewer \"" image-viewer " %i\"
+
+# Because some mailers change lines starting with 'From ' to '>From '
+# it is good to handle such lines in a special way when creating
+# cleartext signatures; all other PGP versions do it this way too.
+# To enable full OpenPGP compliance you may want to use this option.
+#no-escape-from-lines
+"))
+ (".local/share/gnupg/gpg-agent.conf"
+ ,(mixed-text-file "gpg-agent.conf" "\
+pinentry-program " (if gui-pinentry?
+ (file-append pinentry-rofi "/bin/pinentry-rofi")
+ (file-append pinentry-tty "/bin/pinentry-tty")) "
+# Keep passphrase cached for longer, so that mcron jobs (e.g. restic,
+# vdirsyncer) can access the password store. Vdirsyncer should run every half
+# hour to extend the default-cache-ttl.
+default-cache-ttl 2100 # 35 min
+max-cache-ttl 43200 # 12 h
+# Needed if spawning lots of parallel gpg --decrypt processes. https://dev.gnupg.org/T3530
+auto-expand-secmem
+")))))
+
+(define (gnupg-shepherd config)
+ (match-record config <home-gnupg-configuration> (gnupg)
+ (list (shepherd-service
+ (documentation "GPG agent; caches key passwords.")
+ (provision '(gpg-agent))
+ (start #~(lambda _
+ (invoke #$(file-append gnupg "/bin/gpg-agent")
+ "--daemon" "--no-detach")))
+ (stop #~(lambda _
+ (invoke #$(file-append gnupg "/bin/gpg-connect-agent")
+ "killagent" "/bye")))))))
+
+(define home-gnupg-service-type
+ (service-type
+ (name 'gnupg)
+ (extensions
+ (list (service-extension home-shepherd-service-type gnupg-shepherd)
+ (service-extension home-files-service-type gnupg-files)
+ (service-extension home-environment-variables-service-type gnupg-xdg)))
+ (description
+ "Install GnuPG configuration files and run the agent.")))