gnu: base: Add greetd-service-type.

* gnu/services/base.scm (greetd-service-type): New variable
* gnu/services/base.scm (greetd-configuration): New data type
* gnu/services/base.scm (greetd-terminal-configuration): New data type
* gnu/services/base.scm (greetd-agreety-session): New data type
* gnu/services/base.scm (pam-limits-service-type): Should be aware of
greetd PAM service
* gnu/services/pam-mount.scm (pam-mount-pam-service): Should be aware
of greetd PAM service

Signed-off-by: Lars-Dominik Braun <ldb@leibniz-psychology.org>
This commit is contained in:
muradm 2022-06-15 12:17:39 +03:00 committed by Lars-Dominik Braun
parent 32ca068cb9
commit 530e0f0260
No known key found for this signature in database
GPG key ID: 421377011A378446
3 changed files with 360 additions and 2 deletions

View file

@ -97,6 +97,7 @@ Copyright @copyright{} 2021 Hui Lu@*
Copyright @copyright{} 2021 pukkamustard@* Copyright @copyright{} 2021 pukkamustard@*
Copyright @copyright{} 2021 Alice Brenon@* Copyright @copyright{} 2021 Alice Brenon@*
Copyright @copyright{} 2021, 2022 Josselin Poiret@* Copyright @copyright{} 2021, 2022 Josselin Poiret@*
Copyright @copyright{} 2021 muradm@*
Copyright @copyright{} 2021 Andrew Tropin@* Copyright @copyright{} 2021 Andrew Tropin@*
Copyright @copyright{} 2021 Sarah Morgensen@* Copyright @copyright{} 2021 Sarah Morgensen@*
Copyright @copyright{} 2022 Remco van 't Veer@* Copyright @copyright{} 2022 Remco van 't Veer@*
@ -18227,6 +18228,142 @@ about the Pluggable Authentication Module (PAM) limits, refer to the
@samp{pam_limits} man page from the @code{linux-pam} package. @samp{pam_limits} man page from the @code{linux-pam} package.
@end deffn @end deffn
@defvr {Scheme Variable} greetd-service-type
@uref{https://git.sr.ht/~kennylevinsen/greetd, @code{greetd}} is a minimal and
flexible login manager daemon, that makes no assumptions about what you
want to launch.
If you can run it from your shell in a TTY, greetd can start it. If it
can be taught to speak a simple JSON-based IPC protocol, then it can be
a geeter.
@code{greetd-service-type} provides necessary infrastructure for logging
in users, including:
@itemize @bullet
@item
@code{greetd} PAM service
@item
Special variation of @code{pam-mount} to mount @code{XDG_RUNTIME_DIR}
@end itemize
Here is example of switching from @code{mingetty-service-type} to
@code{greetd-service-type}, and how different terminals could be:
@lisp
(append
(modify-services %base-services
;; greetd-service-type provides "greetd" PAM service
(delete login-service-type)
;; and can be used in place of mingetty-service-type
(delete mingetty-service-type))
(list
(service greetd-service-type
(greetd-configuration
(terminals
(list
;; we can make any terminal active by default
(greetd-terminal-configuration (terminal-vt "1") (terminal-switch #t))
;; we can make environment without XDG_RUNTIME_DIR set
;; even provide our own environment variables
(greetd-terminal-configuration
(terminal-vt "2")
(default-session-command
(greetd-agreety-session
(extra-env '(("MY_VAR" . "1")))
(xdg-env? #f))))
;; we can use different shell instead of default bash
(greetd-terminal-configuration
(terminal-vt "3")
(default-session-command
(greetd-agreety-session (command (file-append zsh "/bin/zsh")))))
;; we can use any other executable command as greeter
(greetd-terminal-configuration
(terminal-vt "4")
(default-session-command (program-file "my-noop-greeter" #~(exit))))
(greetd-terminal-configuration (terminal-vt "5"))
(greetd-terminal-configuration (terminal-vt "6"))))))
;; mingetty-service-type can be used in parallel
;; if needed to do so, do not (delete login-service-type)
;; as illustrated above
#| (service mingetty-service-type (mingetty-configuration (tty "tty8"))) |#))
@end lisp
@end defvr
@deftp {Data Type} greetd-configuration
Configuration record for the @code{greetd-service-type}.
@table @asis
@item @code{motd}
A file-like object containing the ``message of the day''.
@item @code{allow-empty-passwords?} (default: @code{#t})
Allow empty passwords by default so that first-time users can log in when
the 'root' account has just been created.
@item @code{terminals} (default: @code{'()})
List of @code{greetd-terminal-configuration} per terminal for which
@code{greetd} should be started.
@end table
@end deftp
@deftp {Data Type} greetd-terminal-configuration
Configuration record for per terminal greetd daemon service.
@table @asis
@item @code{greetd} (default: @code{greetd})
The greetd package to use.
@item @code{config-file-name}
Configuration file name to use for greetd daemon. Generally, autogenerated
derivation based on @code{terminal-vt} value.
@item @code{log-file-name}
Log file name to use for greetd daemon. Generally, autogenerated
name based on @code{terminal-vt} value.
@item @code{terminal-vt} (default: @samp{"7"})
The VT to run on. Use of a specific VT with appropriate conflict avoidance
is recommended.
@item @code{terminal-switch} (default: @code{#f})
Make this terminal active on start of @code{greetd}.
@item @code{default-session-user} (default: @samp{"greeter"})
The user to use for running the greeter.
@item @code{default-session-command} (default: @code{(greetd-agreety-session)})
Can be either instance of @code{greetd-agreety-session} configuration or
@code{gexp->script} like object to use as greeter.
@end table
@end deftp
@deftp {Data Type} greetd-agreety-session
Configuration record for the agreety greetd greeter.
@table @asis
@item @code{agreety} (default: @code{greetd})
The package with @command{/bin/agreety} command.
@item @code{command} (default: @code{(file-append bash "/bin/bash")})
Command to be started by @command{/bin/agreety} on successful login.
@item @code{command-args} (default: @code{'("-l")})
Command arguments to pass to command.
@item @code{extra-env} (default: @code{'()})
Extra environment variables to set on login.
@item @code{xdg-env?} (default: @code{#t})
If true @code{XDG_RUNTIME_DIR} and @code{XDG_SESSION_TYPE} will be set
before starting command. One should note that, @code{extra-env} variables
are set right after mentioned variables, so that they can be overriden.
@end table
@end deftp
@node Scheduled Job Execution @node Scheduled Job Execution
@subsection Scheduled Job Execution @subsection Scheduled Job Execution

View file

@ -16,6 +16,7 @@
;;; Copyright © 2021 qblade <qblade@protonmail.com> ;;; Copyright © 2021 qblade <qblade@protonmail.com>
;;; Copyright © 2021 Hui Lu <luhuins@163.com> ;;; Copyright © 2021 Hui Lu <luhuins@163.com>
;;; Copyright © 2021, 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; Copyright © 2021, 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2021 muradm <mail@muradm.net>
;;; Copyright © 2022 Guillaume Le Vaillant <glv@posteo.net> ;;; Copyright © 2022 Guillaume Le Vaillant <glv@posteo.net>
;;; Copyright © 2022 Justin Veilleux <terramorpha@cock.li> ;;; Copyright © 2022 Justin Veilleux <terramorpha@cock.li>
;;; ;;;
@ -226,6 +227,11 @@ (define-module (gnu services base)
pam-limits-service-type pam-limits-service-type
pam-limits-service pam-limits-service
greetd-service-type
greetd-configuration
greetd-terminal-configuration
greetd-agreety-session
%base-services)) %base-services))
;;; Commentary: ;;; Commentary:
@ -1446,7 +1452,7 @@ (define pam-limits-service-type
(module "pam_limits.so") (module "pam_limits.so")
(arguments '("conf=/etc/security/limits.conf"))))) (arguments '("conf=/etc/security/limits.conf")))))
(if (member (pam-service-name pam) (if (member (pam-service-name pam)
'("login" "su" "slim" "gdm-password" "sddm" '("login" "greetd" "su" "slim" "gdm-password" "sddm"
"sudo" "sshd")) "sudo" "sshd"))
(pam-service (pam-service
(inherit pam) (inherit pam)
@ -2806,6 +2812,221 @@ (define %qemu-static-networking
(provision '(networking)) (provision '(networking))
(name-servers '("10.0.2.3")))) (name-servers '("10.0.2.3"))))
;;;
;;; greetd-service-type -- minimal and flexible login manager daemon
;;;
(define-record-type* <greetd-agreety-session>
greetd-agreety-session make-greetd-agreety-session
greetd-agreety-session?
(agreety greetd-agreety (default greetd))
(command greetd-agreety-command (default (file-append bash "/bin/bash")))
(command-args greetd-agreety-command-args (default '("-l")))
(extra-env greetd-agreety-extra-env (default '()))
(xdg-env? greetd-agreety-xdg-env? (default #t)))
(define greetd-agreety-tty-session-command
(match-lambda
(($ <greetd-agreety-session> _ command args extra-env)
(program-file
"agreety-tty-session-command"
#~(begin
(use-modules (ice-9 match))
(for-each (match-lambda ((var . val) (setenv var val)))
(quote (#$@extra-env)))
(apply execl #$command #$command (list #$@args)))))))
(define greetd-agreety-tty-xdg-session-command
(match-lambda
(($ <greetd-agreety-session> _ command args extra-env)
(program-file
"agreety-tty-xdg-session-command"
#~(begin
(use-modules (ice-9 match))
(let*
((username (getenv "USER"))
(useruid (passwd:uid (getpwuid username)))
(useruid (number->string useruid)))
(setenv "XDG_SESSION_TYPE" "tty")
(setenv "XDG_RUNTIME_DIR" (string-append "/run/user/" useruid)))
(for-each (match-lambda ((var . val) (setenv var val)))
(quote (#$@extra-env)))
(apply execl #$command #$command (list #$@args)))))))
(define (make-greetd-agreety-session-command config command)
(let ((agreety (file-append (greetd-agreety config) "/bin/agreety")))
(program-file
"agreety-command"
#~(execl #$agreety #$agreety "-c" #$command))))
(define (make-greetd-default-session-command config-or-command)
(cond ((greetd-agreety-session? config-or-command)
(cond ((greetd-agreety-xdg-env? config-or-command)
(make-greetd-agreety-session-command
config-or-command
(greetd-agreety-tty-xdg-session-command config-or-command)))
(#t
(make-greetd-agreety-session-command
config-or-command
(greetd-agreety-tty-session-command config-or-command)))))
(#t config-or-command)))
(define-record-type* <greetd-terminal-configuration>
greetd-terminal-configuration make-greetd-terminal-configuration
greetd-terminal-configuration?
(greetd greetd-package (default greetd))
(config-file-name greetd-config-file-name (thunked)
(default (default-config-file-name this-record)))
(log-file-name greetd-log-file-name (thunked)
(default (default-log-file-name this-record)))
(terminal-vt greetd-terminal-vt (default "7"))
(terminal-switch greetd-terminal-switch (default #f))
(default-session-user greetd-default-session-user (default "greeter"))
(default-session-command greetd-default-session-command
(default (greetd-agreety-session))
(sanitize make-greetd-default-session-command)))
(define (default-config-file-name config)
(string-join (list "config-" (greetd-terminal-vt config) ".toml") ""))
(define (default-log-file-name config)
(string-join (list "/var/log/greetd-" (greetd-terminal-vt config) ".log") ""))
(define (make-greetd-terminal-configuration-file config)
(let*
((config-file-name (greetd-config-file-name config))
(terminal-vt (greetd-terminal-vt config))
(terminal-switch (greetd-terminal-switch config))
(default-session-user (greetd-default-session-user config))
(default-session-command (greetd-default-session-command config)))
(mixed-text-file
config-file-name
"[terminal]\n"
"vt = " terminal-vt "\n"
"switch = " (if terminal-switch "true" "false") "\n"
"[default_session]\n"
"user = " default-session-user "\n"
"command = " default-session-command "\n")))
(define %greetd-accounts
(list (user-account
(name "greeter")
(group "wheel")
(supplementary-groups '("users" "tty" "input" "video" "audio"))
(system? #t))))
(define %greetd-file-systems
(list (file-system
(device "none")
(mount-point "/run/greetd/pam_mount")
(type "tmpfs")
(check? #f)
(flags '(no-suid no-dev no-exec))
(options "mode=0755")
(create-mount-point? #t))))
(define %greetd-pam-mount-rules
`((debug (@ (enable "0")))
(volume (@ (sgrp "users")
(fstype "tmpfs")
(mountpoint "/run/user/%(USERUID)")
(options "noexec,nosuid,nodev,size=1g,mode=0700,uid=%(USERUID),gid=%(USERGID)")))
(logout (@ (wait "0")
(hup "0")
(term "yes")
(kill "no")))
(mkmountpoint (@ (enable "1") (remove "true")))))
(define-record-type* <greetd-configuration>
greetd-configuration make-greetd-configuration
greetd-configuration?
(motd greetd-motd (default %default-motd))
(allow-empty-passwords? greetd-allow-empty-passwords? (default #t))
(terminals greetd-terminals (default '())))
(define (make-greetd-pam-mount-conf-file config)
(computed-file
"greetd_pam_mount.conf.xml"
#~(begin
(use-modules (sxml simple))
(call-with-output-file #$output
(lambda (port)
(sxml->xml
'(*TOP*
(*PI* xml "version='1.0' encoding='utf-8'")
(pam_mount
#$@%greetd-pam-mount-rules
(pmvarrun
#$(file-append greetd-pam-mount
"/sbin/pmvarrun -u '%(USER)' -o '%(OPERATION)'"))))
port))))))
(define (greetd-etc-service config)
`(("security/greetd_pam_mount.conf.xml"
,(make-greetd-pam-mount-conf-file config))))
(define (greetd-pam-service config)
(define optional-pam-mount
(pam-entry
(control "optional")
(module #~(string-append #$greetd-pam-mount "/lib/security/pam_mount.so"))
(arguments '("disable_interactive"))))
(list
(unix-pam-service "greetd"
#:login-uid? #t
#:allow-empty-passwords?
(greetd-allow-empty-passwords? config)
#:motd
(greetd-motd config))
(lambda (pam)
(if (member (pam-service-name pam)
'("login" "greetd" "su" "slim" "gdm-password"))
(pam-service
(inherit pam)
(auth (append (pam-service-auth pam)
(list optional-pam-mount)))
(session (append (pam-service-session pam)
(list optional-pam-mount))))
pam))))
(define (greetd-shepherd-services config)
(map
(lambda (tc)
(let*
((greetd-bin (file-append (greetd-package tc) "/sbin/greetd"))
(greetd-conf (make-greetd-terminal-configuration-file tc))
(greetd-log (greetd-log-file-name tc))
(greetd-vt (greetd-terminal-vt tc)))
(shepherd-service
(documentation "Minimal and flexible login manager daemon")
(requirement '(user-processes host-name udev virtual-terminal))
(provision (list (symbol-append
'term-tty
(string->symbol (greetd-terminal-vt tc)))))
(start #~(make-forkexec-constructor
(list #$greetd-bin "-c" #$greetd-conf)
#:log-file #$greetd-log))
(stop #~(make-kill-destructor)))))
(greetd-terminals config)))
(define greetd-service-type
(service-type
(name 'greetd)
(description "Provides necessary infrastructure for logging into the
system including @code{greetd} PAM service, @code{pam-mount} module to
mount/unmount /run/user/<uid> directory for user and @code{greetd}
login manager daemon.")
(extensions
(list
(service-extension account-service-type (const %greetd-accounts))
(service-extension file-system-service-type (const %greetd-file-systems))
(service-extension etc-service-type greetd-etc-service)
(service-extension pam-root-service-type greetd-pam-service)
(service-extension shepherd-root-service-type greetd-shepherd-services)))
(default-value (greetd-configuration))))
(define %base-services (define %base-services
;; Convenience variable holding the basic services. ;; Convenience variable holding the basic services.

View file

@ -90,7 +90,7 @@ (define optional-pam-mount
(module #~(string-append #$pam-mount "/lib/security/pam_mount.so")))) (module #~(string-append #$pam-mount "/lib/security/pam_mount.so"))))
(list (lambda (pam) (list (lambda (pam)
(if (member (pam-service-name pam) (if (member (pam-service-name pam)
'("login" "su" "slim" "gdm-password" "sddm")) '("login" "greetd" "su" "slim" "gdm-password" "sddm"))
(pam-service (pam-service
(inherit pam) (inherit pam)
(auth (append (pam-service-auth pam) (auth (append (pam-service-auth pam)