(define-module (rodion services agate) #:use-module (guix records) #:use-module (guix gexp) #:use-module (ice-9 match) #:use-module (gnu services shepherd) #:use-module (gnu services admin) #:use-module (gnu system pam) #:use-module (gnu system shadow) #:use-module (gnu services) #:use-module (gnu packages admin) #:use-module (gnu packages rust-apps) #:export (agate-configuration agate-configuration? agate-configuration-package agate-configuration-content agate-configuration-cert agate-configuration-key agate-configuration-addr agate-configuration-hostname agate-configuration-lang agate-configuration-silent agate-configuration-serve-secret agate-configuration-log-ip agate-configuration-user agate-configuration-group agate-configuration-log-file agate-service-type)) (define-record-type* agate-configuration make-agate-configuration agate-configuration? (package agate-configuration-package (default agate)) (content agate-configuration-content (default "/srv/gemini")) (cert agate-configuration-cert (default #f)) (key agate-configuration-key (default #f)) (addr agate-configuration-addr (default '("0.0.0.0:1965" "[::]:1965"))) (hostname agate-configuration-hostname (default #f)) (lang agate-configuration-lang (default #f)) (silent? agate-configuration-silent (default #f)) (serve-secret? agate-configuration-serve-secret (default #f)) (log-ip? agate-configuration-log-ip (default #t)) (user agate-configuration-user (default "agate")) (group agate-configuration-group (default "agate")) (log-file agate-configuration-log (default "/var/log/agate.log"))) (define agate-shepherd-service (match-lambda (($ package content cert key addr hostname lang silent? serve-secret? log-ip? user group log-file) (list (shepherd-service (provision '(agate)) (requirement '(networking)) (documentation "Run the agate Gemini server.") (start (let ((agate (file-append package "/bin/agate"))) #~(make-forkexec-constructor (list #$agate "--content" #$content "--addr" #$@addr "--certs" #$cert #$@(if lang (list "--lang" lang) '()) #$@(if hostname (list "--hostname" hostname) '()) #$@(if silent? '("--silent") '()) #$@(if serve-secret? '("--serve-secret") '()) #$@(if log-ip? '("--log-ip") '())) #:user #$user #:group #$group #:log-file #$log-file))) (stop #~(make-kill-destructor))))))) (define agate-accounts (lambda (config) (let ((group (agate-configuration-group config)) (user (agate-configuration-user config))) `(,@(if (equal? group "agate") '() (list (user-group (name "agate") (system? #t)))) ,(user-group (name group) (system? #t)) ,(user-account (name user) (group group) (supplementary-groups '("agate")) (system? #t) (comment "agate server user") (home-directory "/var/empty") (shell (file-append shadow "/sbin/nologin"))))))) (define agate-service-type (service-type (name 'agate) (extensions (list (service-extension account-service-type agate-accounts) (service-extension shepherd-root-service-type agate-shepherd-service))) (default-value (agate-configuration)) (description "Run Agate, a simple Gemini protocol server written in Rust.")))