~ruther/guix-local

8695dcf9d2fb967377969b109e7aaef9fb500c40 — 45mg 1 year, 10 months ago aefe57c
services: elogind: Support hook directories.

Allow the user to specify scripts to be added into Elogind's hook
directories. These scripts will be run before/after
suspend/hibernate/poweroff/reboot.

Also allow setting the associated config options.

* gnu/services/desktop.scm (elogind-configuration): add
`system-sleep-hook-files`, `system-shutdown-hook-files`,
and 4 new config options.
(elogind-configuration-file): Add entries for the new config options
under the `[Sleep]` section.
(elogind-etc-directory): New procedure.
(elogind-service-type): Extend `etc-service-type` using `/etc/elogind`.
* doc/guix.texi (Desktop Services): Document the new options.

Change-Id: I7e22cbaa9d031049b9d085ba0ce4cc8a8b4f16ff
Reviewed-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2 files changed, 79 insertions(+), 2 deletions(-)

M doc/guix.texi
M gnu/services/desktop.scm
M doc/guix.texi => doc/guix.texi +27 -0
@@ 134,6 134,7 @@ Copyright @copyright{} 2024 Arnaud Daby-Seesaram@*
Copyright @copyright{} 2024 Nigko Yerden@*
Copyright @copyright{} 2024 Troy Figiel@*
Copyright @copyright{} 2024 Sharlatan Hellseher@*
Copyright @copyright{} 2024 45mg@*

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or


@@ 25374,6 25375,32 @@ Data type representing the configuration of @command{elogind}.
@item @code{suspend-estimation-seconds} (default: @code{*unspecified*}) (type: integer)
...

@item @code{system-sleep-hook-files} (default: @code{'()}) (type: list)
A list of executables (file-like objects) that will be installed into
the @file{/etc/elogind/system-sleep/} hook directory. For example:

@lisp
(elogind-configuration
 (system-sleep-hook-files
  (list (local-file "sleep-script"))))
@end lisp

See `Hook directories' in the @code{loginctl(1)} man page for more information.

@item @code{system-shutdown-hook-files} (default: @code{'()}) (type: list)
A list of executables (file-like objects) that will be installed into
the @file{/etc/elogind/system-shutdown/} hook directory.

@item @code{allow-power-off-interrupts?} (default: @code{#f}) (type: boolean)
@itemx @code{allow-suspend-interrupts?} (default: @code{#f}) (type: boolean)
Whether the executables in elogind's hook directories (see above) can
cause a power-off or suspend action to be cancelled (interrupted) by
printing an appropriate error message to stdout.

@item @code{broadcast-power-off-interrupts?} (default: @code{#t}) (type: boolean)
@itemx @code{broadcast-suspend-interrupts?} (default: @code{#t}) (type: boolean)
Whether an interrupt of a power-off or suspend action is broadcasted.

@end table
@end deftp


M gnu/services/desktop.scm => gnu/services/desktop.scm +52 -2
@@ 17,6 17,7 @@
;;; Copyright © 2021, 2022 muradm <mail@muradm.net>
;;; Copyright © 2023 Bruno Victal <mirai@makinata.eu>
;;; Copyright © 2023 Zheng Junjie <873216071@qq.com>
;;; Copyright © 2024 45mg <45mg.writes@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;


@@ 1084,7 1085,19 @@ and many other) available for GIO applications.")
  (hibernate-delay-seconds          elogind-hibernate-delay-seconds
                                    (default *unspecified*))
  (suspend-estimation-seconds       elogind-suspend-estimation-seconds
                                    (default *unspecified*)))
                                    (default *unspecified*))
  (system-sleep-hook-files          elogind-system-sleep-hook-files
                                    (default '()))
  (system-shutdown-hook-files       elogind-system-shutdown-hook-files
                                    (default '()))
  (allow-power-off-interrupts?      elogind-allow-power-off-interrupts?
                                    (default #f))
  (allow-suspend-interrupts?        elogind-allow-suspend-interrupts?
                                    (default #f))
  (broadcast-power-off-interrupts?  elogind-broadcast-power-off-interrupts?
                                    (default #t))
  (broadcast-suspend-interrupts?    elogind-broadcast-suspend-interrupts?
                                    (default #t)))

(define (elogind-configuration-file config)
  (define (yesno x)


@@ 1172,7 1185,38 @@ and many other) available for GIO applications.")
   ("HybridSleepState" (sleep-list elogind-hybrid-sleep-state))
   ("HybridSleepMode" (sleep-list elogind-hybrid-sleep-mode))
   ("HibernateDelaySec" (maybe-non-negative-integer elogind-hibernate-delay-seconds))
   ("SuspendEstimationSec" (maybe-non-negative-integer elogind-suspend-estimation-seconds))))
   ("SuspendEstimationSec" (maybe-non-negative-integer elogind-suspend-estimation-seconds))
   ("AllowPowerOffInterrupts" (yesno elogind-allow-power-off-interrupts?))
   ("AllowSuspendInterrupts" (yesno elogind-allow-suspend-interrupts?))
   ("BroadcastPowerOffInterrupts" (yesno elogind-broadcast-power-off-interrupts?))
   ("BroadcastSuspendInterrupts" (yesno elogind-broadcast-suspend-interrupts?))))

(define (elogind-etc-directory config)
  "Return the /etc/elogind directory for CONFIG."
  (with-imported-modules (source-module-closure '((guix build utils)))
    (computed-file
     "etc-elogind"

     #~(begin
         (use-modules (guix build utils))

         (define sleep-directory (string-append #$output "/system-sleep/"))
         (define shutdown-directory (string-append #$output "/system-shutdown/"))

         (define (copy-script file directory)
           "Copy FILE into DIRECTORY, giving rx (500) permissions."
           (let ((dest (string-append directory "/" (basename file))))
             (mkdir-p directory)
             (copy-file file dest)
             (chmod dest #o500)))

         (mkdir-p #$output)            ;in case neither directory gets created
         (for-each (lambda (f)
                     (copy-script f sleep-directory))
                   '#$(elogind-system-sleep-hook-files config))
         (for-each (lambda (f)
                     (copy-script f shutdown-directory))
                   '#$(elogind-system-shutdown-hook-files config))))))

(define (elogind-dbus-service config)
  "Return a @file{org.freedesktop.login1.service} file that tells D-Bus how to


@@ 1294,6 1338,12 @@ seats.)"
                       (service-extension pam-root-service-type
                                          pam-extension-procedure)

                       ;; Install sleep/shutdown hook files.
                       (service-extension etc-service-type
                                          (lambda (config)
                                            `(("elogind"
                                               ,(elogind-etc-directory config)))))

                       ;; We need /run/user, /run/systemd, etc.
                       (service-extension file-system-service-type
                                          (const %elogind-file-systems))))