services: Add snuik-service-type.

* gnu/services/messaging.scm (snuik-configuration): New type.
(snuik-services): New procedure.
(snuik-activation, %snuik-accounts, snuik-service-type): New variables.
* doc/guix.texi (Messaging Services): Document it.

Change-Id: I0c52b4804948876dc1b4d3b5ac660af848a13f25
This commit is contained in:
Janneke Nieuwenhuizen 2025-03-13 19:22:02 +01:00
parent 973e59e24e
commit 2f204a7303
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
2 changed files with 171 additions and 2 deletions

View file

@ -36,7 +36,7 @@ Copyright @copyright{} 2016, 2017, 2018, 2021 Chris Marusich@*
Copyright @copyright{} 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Efraim Flashner@*
Copyright @copyright{} 2016 John Darrington@*
Copyright @copyright{} 2016, 2017 Nikita Gillmann@*
Copyright @copyright{} 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Janneke Nieuwenhuizen@*
Copyright @copyright{} 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025 Janneke Nieuwenhuizen@*
Copyright @copyright{} 2016, 2017, 2018, 2019, 2020, 2021 Julien Lepiller@*
Copyright @copyright{} 2016 Alex ter Weele@*
Copyright @copyright{} 2016, 2017, 2018, 2019, 2020, 2021 Christopher Baines@*
@ -30218,6 +30218,63 @@ and Error.
@end table
@end deftp
@cindex irc-bot
@cindex snuik
The @uref{https://gitlab.com/janneke/snuik, Snuik IRC bot} can be run as
a daemon to aid talking to users that are currently offline. With the
@code{(gnu services messaging)} service, you can configure it by adding
a @code{snuik-service-type} service to the @code{services} field of your
operating system declaration.
@defvar snuik-service-type
This is the type of the Snuik service, whose value is a
@code{snuik-configuration} object.
@end defvar
Here is an example of a service and its configuration:
@lisp
(service snuik-service-type
(snuik-configuration
(password-file "/var/run/snuik/.password.snuik")
(channels '("#bootstrappable"
"#dezyne"
"#guix-risc-v"
"#lilypond"))))
@end lisp
@deftp {Data Type} snuik-configuration
Available @code{snuik-configuration} fields are:
@table @asis
@item @code{snuik} (default: @code{snuik}) (type: package)
The Snuik package to use.
@item @code{server} (default: @code{"irc.libera.chat"})
The IRC server to connect to.
@item @code{port} (default: @code{6665}) (type: integer)
Port number used by the IRC server.
@item @code{nick} (default: @code{"snuik"}) (type: string)
The nickname for snuik to use.
@item @code{password} (default: @code{#f}) (type: string)
The password to use when logging in.
@item @code{password-file} (default: @code{".password.<nick>})
The file to read the password from to use when logging in.
@item @code{channels} (default: @code{'("##botchat")})
The channels for snuik to join, a list of strings.
@item @code{extra-options} (default: @code{'()})
Extra options will be passed to @command{snuik}, please run
@command{snuik --help } for more information.
@end table
@end deftp
@node Telephony Services
@subsection Telephony Services

View file

@ -59,7 +59,10 @@
bitlbee-service-type
quassel-configuration
quassel-service-type))
quassel-service-type
snuik-configuration
snuik-service-type))
;;; Commentary:
;;;
@ -1002,3 +1005,112 @@ a gateway between IRC and chat networks.")))
"Run @url{https://quassel-irc.org/,quasselcore}, the backend
for the distributed IRC client quassel, which allows you to connect from
multiple machines simultaneously.")))
;;;
;;; Snuik.
;;;
(define-maybe integer (no-serialization))
(define-configuration/no-serialization snuik-configuration
(snuik (package snuik) "The snuik package to use.")
(server maybe-string "The IRC server to connect to.")
(port maybe-integer "The port used by the IRC server.")
(nick maybe-string "The nickname for snuik to use.")
(password maybe-string "The password to use when logging in.")
(password-file maybe-string "The file to read the password from.")
(channels (list-of-strings '()) "The channels for snuik to join.")
(extra-options (list-of-strings '()) "Extra options to be passed to snuik.")
(home-service? (boolean for-home?) "Running as home service?"))
(define (snuik-services config)
"Return a <shepherd-service> for snuik with CONFIG."
(match-record config
<snuik-configuration>
(snuik server port nick password password-file channels extra-options
home-service?)
(let* ((password-file (snuik-configuration-password-file config))
(mappings `(,@(if home-service?
'()
`(,(file-system-mapping
(source "/var/run/snuik")
(target source)
(writable? #t))
,@(if password-file
(list (file-system-mapping
(source password-file)
(target source)))
'())))))
(snuik (least-authority-wrapper
(file-append snuik "/bin/snuik")
#:name "snuik"
#:mappings mappings
#:namespaces (delq 'net %namespaces)))
(command
#~'(#$snuik
#$@(if (and server (not (eq? server %unset-value)))
(list (string-append "--server=" server))
#~())
#$@(if (and port (not (eq? port %unset-value)))
(list (string-append "--port=" (number->string port)))
#~())
#$@(if (and nick (not (eq? nick %unset-value)))
(list (string-append "--nick=" nick))
#~())
#$@(if (and password (not (eq? password %unset-value)))
(list (string-append "--password=" password))
#~())
#$@(if (and password-file (not (eq? password-file %unset-value)))
(list (string-append "--password-file=" password-file))
#~())
#$@(if (pair? channels)
(list (string-append "--channels=" (string-join channels ",")))
#~())
#$@extra-options))
(log-file #~(string-append
#$(if home-service? #~%user-log-dir "/var/log")
"/snuik.log")))
(list (shepherd-service
(documentation "Run the snuik IRC bot.")
(provision '(snuik))
(requirement (if home-service? '() '(user-processes networking)))
(modules (if home-service?
'((shepherd support)) ;for '%user-log-dir'
'()))
(start #~(make-forkexec-constructor
#$command
#:log-file #$log-file
#:user #$(and (not home-service?) "snuik")
#:group #$(and (not home-service?) "snuik")))
(stop #~(make-kill-destructor)))))))
(define snuik-activation
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
(let* ((user (getpw "snuik"))
(directory "/var/run/snuik"))
(mkdir-p directory)
(chown directory (passwd:uid user) (passwd:gid user))))))
(define %snuik-accounts
(list (user-group (name "snuik") (system? #t))
(user-account
(name "snuik")
(group "snuik")
(system? #t)
(comment "Snuik IRC bot user")
(home-directory "/var/run/snuik")
(shell (file-append shadow "/sbin/nologin")))))
(define snuik-service-type
(service-type
(name 'home-snuik)
(description "Run the Snuik IRC bot.")
(default-value (snuik-configuration))
(extensions
(list (service-extension activation-service-type
(const snuik-activation))
(service-extension account-service-type
(const %snuik-accounts))
(service-extension shepherd-root-service-type
snuik-services)))))