Package: guix;
Reported by: Ludovic Courtès <ludo <at> gnu.org>
Date: Mon, 14 Apr 2025 16:48:02 UTC
Severity: important
Done: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 77806 in the body.
You can then email your comments to 77806 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
maxim.cournoyer <at> gmail.com, bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Mon, 14 Apr 2025 16:48:02 GMT) Full text and rfc822 format available.Ludovic Courtès <ludo <at> gnu.org>
:maxim.cournoyer <at> gmail.com, bug-guix <at> gnu.org
.
(Mon, 14 Apr 2025 16:48:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: bug-guix <at> gnu.org Subject: elogind behavior changed: power key turns computer off Date: Mon, 14 Apr 2025 18:46:33 +0200
Hello, Probably related to the elogind upgrade in 098b5cdf9c6841df0b3c086974eef7e13fd23b36, I noticed today that pressing the power button on my laptop would turn it off instead of putting it into software suspend as it used to do: --8<---------------cut here---------------start------------->8--- 2025-04-14 17:59:53 localhost elogind[290]: Power key pressed short. 2025-04-14 17:59:53 localhost elogind[290]: Powering off... 2025-04-14 17:59:53 localhost elogind[290]: System is powering down. 2025-04-14 17:59:54 localhost shepherd[1]: Stopping service root... 2025-04-14 17:59:54 localhost shepherd[1]: Exiting shepherd... 2025-04-14 17:59:54 localhost shepherd[1]: Stopping service swap-/swap... 2025-04-14 17:59:54 localhost shepherd[1]: Service swap-/swap stopped. 2025-04-14 17:59:54 localhost shepherd[1]: Service swap-/swap is now stopped. --8<---------------cut here---------------end--------------->8--- Previously I had: --8<---------------cut here---------------start------------->8--- 2025-04-08 18:07:51 localhost elogind[282]: Power key pressed short. 2025-04-08 18:07:51 localhost elogind[282]: Suspending... 2025-04-08 18:07:51 localhost NetworkManager[311]: <info> [1744128471.3311] manager: sleep: sleep requested (sleeping: no enabled: yes) 2025-04-08 18:07:51 localhost NetworkManager[311]: <info> [1744128471.3332] manager: NetworkManager state is now ASLEEP 2025-04-08 18:07:51 localhost elogind[282]: Entering sleep state 'suspend'... 2025-04-08 18:07:51 localhost linux: [82930.856145] PM: suspend entry (deep) --8<---------------cut here---------------end--------------->8--- Yet the config reads this: --8<---------------cut here---------------start------------->8--- $ grep -i powerkey $(sudo herd configuration elogind) HandlePowerKey=suspend PowerKeyIgnoreInhibited=no --8<---------------cut here---------------end--------------->8--- Thoughts? Ludo’.
bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Wed, 16 Apr 2025 03:04:02 GMT) Full text and rfc822 format available.Message #8 received at 77806 <at> debbugs.gnu.org (full text, mbox):
From: Bas Alberts <bas <at> anti.computer> To: Ludovic Courtès <ludo <at> gnu.org> Cc: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, 77806 <at> debbugs.gnu.org Subject: Re: bug#77806: elogind behavior changed: power key turns computer off Date: Wed, 16 Apr 2025 03:03:28 +0000
On Mon, 14 Apr 2025 18:46:33 +0200, Ludovic Courtès <ludo <at> gnu.org> wrote: > > Yet the config reads this: > > $ grep -i powerkey $(sudo herd configuration elogind) > HandlePowerKey=suspend > PowerKeyIgnoreInhibited=no I'm having the same issue. My config is also unchanged but after this week's upgrades elogind no longer respects HandleLidSwitch=hibernate and my laptop defaults to s2idle which is prohibitively battery consuming on my hardware. λ ~ › grep -i HandleLidSwitch= $(sudo herd configuration elogind) HandleLidSwitch=hibernate ... on lid close: [ 3603.354720] PM: suspend entry (s2idle) [ 3603.359069] Filesystems sync: 0.004 seconds [ 3603.368060] Freezing user space processes ... Kind regards, Bas
Ludovic Courtès <ludo <at> gnu.org>
to control <at> debbugs.gnu.org
.
(Fri, 18 Apr 2025 20:51:07 GMT) Full text and rfc822 format available.bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Thu, 24 Apr 2025 05:30:02 GMT) Full text and rfc822 format available.Message #13 received at 77806 <at> debbugs.gnu.org (full text, mbox):
From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> To: Bas Alberts <bas <at> anti.computer> Cc: Ludovic Courtès <ludo <at> gnu.org>, 77806 <at> debbugs.gnu.org Subject: Re: bug#77806: elogind behavior changed: power key turns computer off Date: Thu, 24 Apr 2025 14:29:24 +0900
Hi, Thanks for the report. It looks like nowadays the sleep settings are expected to be in a distinct sleep.conf file [0]; I haven't verified yet but I suspect the [Sleep] section of our logind.conf is no longer honored. [0] https://github.com/elogind/elogind/issues/293 -- Thanks, Maxim
liliana.prikler <at> gmail.com, maxim.cournoyer <at> gmail.com, noelopez <at> free.fr, vivien <at> planete-kraus.eu, bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Thu, 24 Apr 2025 10:40:09 GMT) Full text and rfc822 format available.Message #16 received at 77806 <at> debbugs.gnu.org (full text, mbox):
From: Josselin Poiret <dev <at> jpoiret.xyz> To: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, Bas Alberts <bas <at> anti.computer> Cc: Ludovic Courtès <ludo <at> gnu.org>, Josselin Poiret <dev <at> jpoiret.xyz>, 77806 <at> debbugs.gnu.org Subject: [PATCH] gnu: elogind-service-type: Put user configuration in drop-in dirs. Date: Thu, 24 Apr 2025 12:38:41 +0200
From: Josselin Poiret <dev <at> jpoiret.xyz> * gnu/services/desktop.scm (elogind-configuration-files): Renamed from elogind-configuration-file. Split sections [Login] and [Sleep] in two files. (elogind-shepherd-service): Remove useless environment variable. Change-Id: Ibb4db04152c397c1ed4a35118129a2860ac9c2b5 --- Hello everyone, Here's a fix I just tested. I chose to use drop-in directories instead of the main conf file as it uses an hardcoded PKGCONFDIR. Best, Josselin gnu/services/desktop.scm | 110 ++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 53 deletions(-) diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm index fe034cfa8f4..628879c73dd 100644 --- a/gnu/services/desktop.scm +++ b/gnu/services/desktop.scm @@ -1101,7 +1101,7 @@ (define-record-type* <elogind-configuration> elogind-configuration (broadcast-suspend-interrupts? elogind-broadcast-suspend-interrupts? (default #t))) -(define (elogind-configuration-file config) +(define (elogind-configuration-files config) (define (yesno x) (match x (#t "yes") @@ -1152,55 +1152,59 @@ (define (elogind-configuration-file config) (string-append str "\n"))))) (define-syntax-rule (ini-file config file clause ...) (plain-file file (string-append (ini-file-clause config clause) ...))) - (ini-file - config "logind.conf" - "[Login]" - ("KillUserProcesses" (yesno elogind-kill-user-processes?)) - ("KillOnlyUsers" (user-name-list elogind-kill-only-users)) - ("KillExcludeUsers" (user-name-list elogind-kill-exclude-users)) - ("InhibitDelayMaxSec" (non-negative-integer elogind-inhibit-delay-max-seconds)) - ("HandlePowerKey" (handle-action elogind-handle-power-key)) - ("HandleSuspendKey" (handle-action elogind-handle-suspend-key)) - ("HandleHibernateKey" (handle-action elogind-handle-hibernate-key)) - ("HandleLidSwitch" (handle-action elogind-handle-lid-switch)) - ("HandleLidSwitchDocked" (handle-action elogind-handle-lid-switch-docked)) - ("HandleLidSwitchExternalPower" (handle-action elogind-handle-lid-switch-external-power)) - ("PowerKeyIgnoreInhibited" (yesno elogind-power-key-ignore-inhibited?)) - ("SuspendKeyIgnoreInhibited" (yesno elogind-suspend-key-ignore-inhibited?)) - ("HibernateKeyIgnoreInhibited" (yesno elogind-hibernate-key-ignore-inhibited?)) - ("LidSwitchIgnoreInhibited" (yesno elogind-lid-switch-ignore-inhibited?)) - ("HoldoffTimeoutSec" (non-negative-integer elogind-holdoff-timeout-seconds)) - ("IdleAction" (handle-action elogind-idle-action)) - ("IdleActionSec" (non-negative-integer elogind-idle-action-seconds)) - ("RuntimeDirectorySize" - (identity - (lambda (config) - (match (elogind-runtime-directory-size-percent config) - (#f (non-negative-integer (elogind-runtime-directory-size config))) - (percent (string-append (non-negative-integer percent) "%")))))) - ("RemoveIPC" (yesno elogind-remove-ipc?)) - "[Sleep]" - ("SuspendState" (sleep-list elogind-suspend-state)) - ("SuspendMode" (sleep-list elogind-suspend-mode)) - ("HibernateState" (sleep-list elogind-hibernate-state)) - ("HibernateMode" (sleep-list elogind-hibernate-mode)) - ("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)) - ("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?)))) + `(("logind.conf.d/logind.conf" . + ,(ini-file + config "logind.conf" + "[Login]" + ("KillUserProcesses" (yesno elogind-kill-user-processes?)) + ("KillOnlyUsers" (user-name-list elogind-kill-only-users)) + ("KillExcludeUsers" (user-name-list elogind-kill-exclude-users)) + ("InhibitDelayMaxSec" (non-negative-integer elogind-inhibit-delay-max-seconds)) + ("HandlePowerKey" (handle-action elogind-handle-power-key)) + ("HandleSuspendKey" (handle-action elogind-handle-suspend-key)) + ("HandleHibernateKey" (handle-action elogind-handle-hibernate-key)) + ("HandleLidSwitch" (handle-action elogind-handle-lid-switch)) + ("HandleLidSwitchDocked" (handle-action elogind-handle-lid-switch-docked)) + ("HandleLidSwitchExternalPower" (handle-action elogind-handle-lid-switch-external-power)) + ("PowerKeyIgnoreInhibited" (yesno elogind-power-key-ignore-inhibited?)) + ("SuspendKeyIgnoreInhibited" (yesno elogind-suspend-key-ignore-inhibited?)) + ("HibernateKeyIgnoreInhibited" (yesno elogind-hibernate-key-ignore-inhibited?)) + ("LidSwitchIgnoreInhibited" (yesno elogind-lid-switch-ignore-inhibited?)) + ("HoldoffTimeoutSec" (non-negative-integer elogind-holdoff-timeout-seconds)) + ("IdleAction" (handle-action elogind-idle-action)) + ("IdleActionSec" (non-negative-integer elogind-idle-action-seconds)) + ("RuntimeDirectorySize" + (identity + (lambda (config) + (match (elogind-runtime-directory-size-percent config) + (#f (non-negative-integer (elogind-runtime-directory-size config))) + (percent (string-append (non-negative-integer percent) "%")))))) + ("RemoveIPC" (yesno elogind-remove-ipc?)))) + ("sleep.conf.d/sleep.conf" . + ,(ini-file + config "sleep.conf" + "[Sleep]" + ("SuspendState" (sleep-list elogind-suspend-state)) + ("SuspendMode" (sleep-list elogind-suspend-mode)) + ("HibernateState" (sleep-list elogind-hibernate-state)) + ("HibernateMode" (sleep-list elogind-hibernate-mode)) + ("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)) + ("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))) + (with-imported-modules (source-module-closure '((guix build utils) (ice-9 match) (srfi srfi-1))) (computed-file "etc-elogind" #~(begin - (use-modules (guix build utils)) + (use-modules (guix build utils) (ice-9 match) (srfi srfi-1)) (define sleep-directory (string-append #$output "/system-sleep/")) (define shutdown-directory (string-append #$output "/system-shutdown/")) @@ -1218,7 +1222,14 @@ (define (elogind-etc-directory config) '#$(elogind-system-sleep-hook-files config)) (for-each (lambda (f) (copy-script f shutdown-directory)) - '#$(elogind-system-shutdown-hook-files config)))))) + '#$(elogind-system-shutdown-hook-files config)) + #$@(append-map + (match-lambda + ((name . file) + (list + #~(mkdir-p (dirname (string-append #$output "/" #$name))) + #~(copy-file #$file (string-append #$output "/" #$name))))) + (elogind-configuration-files config)))))) (define (elogind-dbus-service config) "Return a @file{org.freedesktop.login1.service} file that tells D-Bus how to @@ -1301,20 +1312,13 @@ (define (pam-extension-procedure config) (define (elogind-shepherd-service config) "Return a Shepherd service to start elogind according to @var{config}." - (define config-file - (elogind-configuration-file config)) - (list (shepherd-service (requirement '(user-processes dbus-system)) (provision '(elogind)) (start #~(make-forkexec-constructor (list #$(file-append (elogind-package config) - "/libexec/elogind/elogind")) - #:environment-variables - (list (string-append "ELOGIND_CONF_FILE=" - #$config-file)))) - (stop #~(make-kill-destructor)) - (actions (list (shepherd-configuration-action config-file)))))) + "/libexec/elogind/elogind")))) + (stop #~(make-kill-destructor))))) (define elogind-service-type (service-type (name 'elogind) base-commit: a6c96cdb7060ccfc2d0fe27a45b9bcc9590aedd6 prerequisite-patch-id: 1ee329e14fdb8d1e35141e9b5972c5e9b8a2b252 -- 2.49.0
bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Thu, 24 Apr 2025 21:40:04 GMT) Full text and rfc822 format available.Message #19 received at 77806 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Josselin Poiret <dev <at> jpoiret.xyz> Cc: Bas Alberts <bas <at> anti.computer>, Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, 77806 <at> debbugs.gnu.org Subject: Re: [PATCH] gnu: elogind-service-type: Put user configuration in drop-in dirs. Date: Thu, 24 Apr 2025 23:13:58 +0200
Hey, Josselin Poiret <dev <at> jpoiret.xyz> writes: > From: Josselin Poiret <dev <at> jpoiret.xyz> > > * gnu/services/desktop.scm (elogind-configuration-files): Renamed from > elogind-configuration-file. Split sections [Login] and [Sleep] in two files. > (elogind-shepherd-service): Remove useless environment variable. > > Change-Id: Ibb4db04152c397c1ed4a35118129a2860ac9c2b5 > + `(("logind.conf.d/logind.conf" . [...] > + ("sleep.conf.d/sleep.conf" . Should it be elogind/{logind.conf,sleep.conf}? > (define (elogind-etc-directory config) > "Return the /etc/elogind directory for CONFIG." > - (with-imported-modules (source-module-closure '((guix build utils))) > + (with-imported-modules (source-module-closure '((guix build utils) (ice-9 match) (srfi srfi-1))) This is incorrect: it would import these two modules from the host Guile into the build environment. > + #$@(append-map > + (match-lambda > + ((name . file) > + (list > + #~(mkdir-p (dirname (string-append #$output "/" #$name))) > + #~(copy-file #$file (string-append #$output "/" #$name))))) > + (elogind-configuration-files config)))))) I’d rather avoid the list of gexps and instead write: #$(map (match-lambda ((target . file) #~(begin (mkdir-p …) (copy-file …)))) …) > - (actions (list (shepherd-configuration-action config-file)))))) Too bad we’re losing this. Perhaps we could have a custom ‘configuration’ action returning the list of config files? Not a blocker anyway. Thanks for fixing it, I’ve inadvertently turned off my laptop too many times! Ludo’.
ludo <at> gnu.org, bas <at> anti.computer, maxim.cournoyer <at> gmail.com, dev <at> jpoiret.xyz, liliana.prikler <at> gmail.com, noelopez <at> free.fr, vivien <at> planete-kraus.eu, bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Fri, 25 Apr 2025 02:12:03 GMT) Full text and rfc822 format available.Message #22 received at 77806 <at> debbugs.gnu.org (full text, mbox):
From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> To: 77806 <at> debbugs.gnu.org Cc: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> Subject: [PATCH v2] services: elogind: Split sleep.conf and port to define-configuration. Date: Fri, 25 Apr 2025 11:10:16 +0900
* gnu/services/desktop.scm (pascal-case): New procedure. (<elogind-configuration>): Rewrite in terms of define-configuration. (elogind-configuration-file): Delete. (maybe-list-of-suspend-states?, maybe-list-of-suspend-modes?) maybe-list-of-user-names?, maybe-boolean?maybe-package?) (maybe-action?, maybe-percent?, maybe-list-of-strings?) (maybe-list-of-hibernation-modes?, maybe-non-negative-integer?) (non-negative-integer?, percent?, char-set:user-name, user-name?) (list-of-user-names?, %elogind-actions, action?, %linux-suspend-states) (string->symbol/maybe, suspend-state?, list-of-suspend-states?) (%linux-suspend-modes, suspend-mode?, list-of-suspend-modes?) (%linux-hibernation-modes, hibernation-mode?, list-of-hibernation-modes?) (elogind-deprecated-empty-serializer, list-of-file-likes?) (elogind-serialize-boolean, elogind-base-serializer, elogind-serialize-action) (elogind-serialize-non-negative-integer, elogind-serialize-percent) (elogind-list-serializer, elogind-serialize-list-of-strings) (elogind-serialize-list-of-user-names, elogind-serialize-list-of-suspend-states) (elogind-serialize-list-of-suspend-modes) (elogind-serialize-list-of-hibernation-modes) (%elogind-configuration-sleep-fields, logind.conf, sleep.conf): New procedures. (elogind-etc-directory): Create the main configuration files there too. (elogind-dbus-service): Adjust for package accessor name change. (pam-extension-procedure, elogind-shepherd-service) (elogind-service-type): Likewise. * doc/guix.texi (Desktop Services): Fully document configuration options. Fixes: bug#77806 Change-Id: I8767891871d83e58d64995ec986a7d01689fa6d8 --- doc/guix.texi | 191 +++++++----- gnu/services/desktop.scm | 628 ++++++++++++++++++++++++++------------- 2 files changed, 524 insertions(+), 295 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index be2fbbaf5bc..7b418a40892 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -26264,129 +26264,158 @@ Desktop Services @code{<elogind-configuration>} object. @end defvar -@c TODO: field descriptions. This is best done by refactoring -@c elogind-configuration to use define-configuration which embeds the -@c descriptions in the code and then use configuration->documentation. +@c Auto-generated via (configuration->documentation 'elogind-configuration). +@c %start of fragment + @deftp {Data Type} elogind-configuration -Data type representing the configuration of @command{elogind}. +Available @code{elogind-configuration} fields are: @table @asis @item @code{elogind} (default: @code{elogind}) (type: file-like) -... +The elogind package to use. -@item @code{kill-user-processes?} (default: @code{#f}) (type: boolean) -... +@item @code{system-sleep-hook-files} (default: @code{()}) (type: list-of-file-likes) +A list of executables (file-like objects) that will be installed into +the @file{/etc/elogind/system-sleep} hook directory. See `Hook +directories' in the @samp{loginctl(1)} man page for more information. -@item @code{kill-only-users} (default: @code{'()}) (type: list) -... +@item @code{system-shutdown-hook-files} (default: @code{()}) (type: list-of-file-likes) +A list of executables (file-like objects) that will be installed into +the @file{/etc/elogind/system-shutdown/} hook directory. -@item @code{kill-exclude-users} (default: @code{'("root")}) (type: list-of-string) -... +@item @code{allow-power-off-interrupts?} (default: @code{#f}) (type: maybe-boolean) +Whether the executables in elogind's hook directories (see above) can +cause a power-off action to be cancelled (interrupted) by printing an +appropriate error message to stdout. -@item @code{inhibit-delay-max-seconds} (default: @code{5}) (type: integer) -... +@item @code{allow-suspend-interrupts?} (default: @code{#f}) (type: maybe-boolean) +Likewise as the @code{allow-power-off-interrupts?} option, but for the +suspend action. -@item @code{handle-power-key} (default: @code{'poweroff}) (type: symbol) -... +@item @code{broadcast-power-off-interrupts?} (default: @code{#f}) (type: maybe-boolean) +Whether an interrupt of a power-off action is broadcasted. -@item @code{handle-suspend-key} (default: @code{'suspend}) (type: symbol) -... +@item @code{broadcast-suspend-interrupts?} (default: @code{#f}) (type: maybe-boolean) +Whether an interrupt of a suspend action is broadcasted. -@item @code{handle-hibernate-key} (default: @code{'hibernate}) (type: symbol) -... +@item @code{kill-user-processes?} (default: @code{#f}) (type: maybe-boolean) +Whether the processes of a user should be killed when the user logs out. -@item @code{handle-lid-switch} (default: @code{'suspend}) (type: symbol) -... +@item @code{kill-only-users} (type: maybe-list-of-user-names) +Usernames whose processes should be killed, regardless the value of +@code{kill-user-processes?}. -@item @code{handle-lid-switch-docked} (default: @code{'ignore}) (type: symbol) -... +@item @code{kill-exclude-users} (default: @code{("root")}) (type: maybe-list-of-user-names) +Usernames whose processes should @emph{not} be killed, regardless the +value of @code{kill-user-processes?}. -@item @code{handle-lid-switch-external-power} (default: @code{*unspecified*}) (type: symbol) -... +@item @code{inhibit-delay-max-seconds} (default: @code{5}) (type: maybe-non-negative-integer) +The maximum time a system shutdown or sleep request is delayed due to an +inhibitor lock of type delay being active before the inhibitor is +ignored and the operation executes anyway. -@item @code{power-key-ignore-inhibited?} (default: @code{#f}) (type: boolean) -... +@item @code{handle-power-key} (default: @code{poweroff}) (type: maybe-action) +The action done when the power key is pressed. The compiled default is +@code{'poweroff}. -@item @code{suspend-key-ignore-inhibited?} (default: @code{#f}) (type: boolean) -... +@item @code{handle-suspend-key} (default: @code{suspend}) (type: maybe-action) +The action done when the suspend key is pressed. The -@item @code{hibernate-key-ignore-inhibited?} (default: @code{#f}) (type: boolean) -... +@item @code{handle-hibernate-key} (default: @code{hibernate}) (type: maybe-action) +The action done when the hibernate key is pressed. -@item @code{lid-switch-ignore-inhibited?} (default: @code{#t}) (type: boolean) -... +@item @code{handle-lid-switch} (default: @code{suspend}) (type: maybe-action) +The action done when the lid is closed. -@item @code{holdoff-timeout-seconds} (default: @code{30}) (type: integer) -... +@item @code{handle-lid-switch-docked} (default: @code{ignore}) (type: maybe-action) +The action done when the lid is closed and the device docked. -@item @code{idle-action} (default: @code{'ignore}) (type: symbol) -... +@item @code{handle-lid-switch-external-power} (default: @code{suspend}) (type: maybe-action) +The action done when the lid is closed and the device is externally +powered. -@item @code{idle-action-seconds} (default: @code{(* 30 60)}) (type: integer) -... +@item @code{power-key-ignore-inhibited?} (default: @code{#f}) (type: maybe-boolean) +Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or +idle) when the power key is pressed. -@item @code{runtime-directory-size-percent} (default: @code{10}) (type: integer) -... +@item @code{suspend-key-ignore-inhibited?} (default: @code{#f}) (type: maybe-boolean) +Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or +idle) when the suspend key is pressed. -@item @code{runtime-directory-size} (default: @code{#f}) (type: integer) -... +@item @code{hibernate-key-ignore-inhibited?} (default: @code{#f}) (type: maybe-boolean) +Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or +idle) when the hibernate key is pressed. -@item @code{remove-ipc?} (default: @code{#t}) (type: boolean) -... +@item @code{lid-switch-ignore-inhibited?} (default: @code{#f}) (type: maybe-boolean) +Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or +idle) when the lid is closed. -@item @code{suspend-state} (default: @code{'("mem" "standby" "freeze")}) (type: list) -... +@item @code{holdoff-timeout-seconds} (default: @code{30}) (type: maybe-non-negative-integer) +Specifies the number of seconds after system startup or system resume +during which elogind will hold off on reacting to lid events. -@item @code{suspend-mode} (default: @code{'()}) (type: list) -... +@item @code{idle-action} (default: @code{ignore}) (type: maybe-action) +Action to take when the system is idle. -@item @code{hibernate-state} (default: @code{'("disk")}) (type: list) -... +@item @code{idle-action-seconds} (type: maybe-non-negative-integer) +The delay after which the action configured in @code{idle-action} is +taken after the system is idle. -@item @code{hibernate-mode} (default: @code{'("platform" "shutdown")}) (type: list) -... +@item @code{runtime-directory-size-percent} (type: maybe-percent) +Set the size limit, in percent, on the @env{XDG_RUNTIME_DIR} runtime +directory for each user who logs in. This specifies the per-user size +limit relative to the amount of physical @acronym{RAM,read access +memory}. This value takes precedence over that specified via +@code{runtime-directory-size}. -@item @code{hybrid-sleep-state} (default: @code{'("disk")}) (type: list) -... +@item @code{runtime-directory-size} (type: maybe-non-negative-integer) +Set the size limit, in bytes, on the @env{XDG_RUNTIME_DIR} runtime +directory for each user who logs in. -@item @code{hybrid-sleep-mode} (default: @code{'("suspend" "platform" "shutdown")}) (type: list) -... +@item @code{remove-ipc?} (default: @code{#t}) (type: maybe-boolean) +Whether @acronym{IPC,inter-process communication} objects belonging to +the user shall be removed when the user fully logs out. -@item @code{hibernate-delay-seconds} (default: @code{*unspecified*}) (type: integer) -... +@item @code{suspend-state} (default: @code{(mem standby freeze)}) (type: maybe-list-of-suspend-states) +The suspend state values to be write to @file{/sys/power/state} by +elogind when suspending the system. They will be tried in turn, until +one is written without error. -@item @code{suspend-estimation-seconds} (default: @code{*unspecified*}) (type: integer) -... +@item @code{suspend-mode} (type: maybe-list-of-suspend-modes) +The suspend mode values to write to @file{/sys/power/mem_sleep} by +elogind when suspending the system. -@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: +@item @code{suspend-estimation-seconds} (default: @code{3600}) (type: maybe-non-negative-integer) +Cause the RTC alarm to wake the system after the specified time span to +measure the system battery capacity level and estimate the battery +discharging rate, which is used for estimating the time span until the +system battery charge level goes down to 5%. This option is only used +by elogind when using the @code{'suspend-then-hibernate} action. -@lisp -(elogind-configuration - (system-sleep-hook-files - (list (local-file "sleep-script")))) -@end lisp +@item @code{hibernate-mode} (default: @code{(platform shutdown)}) (type: maybe-list-of-hibernation-modes) +The hibernation mode values to write to @file{/sys/power/disk} by +elogind when hibernating the system. -See `Hook directories' in the @code{loginctl(1)} man page for more information. +@item @code{hibernate-delay-seconds} (type: maybe-non-negative-integer) +The amount of time the system spends in suspend mode before the system +is automatically put into hibernate mode. -@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{hibernate-state} (type: maybe-list-of-strings) +Deprecated option. -@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{hybrid-sleep-state} (type: maybe-list-of-strings) +Deprecated option. -@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. +@item @code{hybrid-sleep-mode} (type: maybe-list-of-strings) +Deprecated option. @end table + @end deftp + +@c %end of fragment + @defvar accountsservice-service-type Type for the service that runs AccountsService, a system service that can list available accounts, change their passwords, and so on. diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm index fe034cfa8f4..e422fbc89df 100644 --- a/gnu/services/desktop.scm +++ b/gnu/services/desktop.scm @@ -37,6 +37,7 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu services desktop) + #:use-module ((gnu home services utils) #:select (object->camel-case-string)) #:use-module (gnu services) #:use-module (gnu services shepherd) #:use-module (gnu services base) @@ -228,6 +229,8 @@ (define (package-direct-input-selector tree) (loop (cdr tree) (car (assoc-ref (package-direct-inputs package) (car tree)))))))) +(define (pascal-case text) + (object->camel-case-string text 'upper)) ;;; @@ -1025,173 +1028,367 @@ (define gvfs-service-type ;;; Elogind login and seat management service. ;;; -(define-record-type* <elogind-configuration> elogind-configuration - make-elogind-configuration - elogind-configuration? - (elogind elogind-package - (default elogind)) - (kill-user-processes? elogind-kill-user-processes? - (default #f)) - (kill-only-users elogind-kill-only-users - (default '())) - (kill-exclude-users elogind-kill-exclude-users - (default '("root"))) - (inhibit-delay-max-seconds elogind-inhibit-delay-max-seconds - (default 5)) - (handle-power-key elogind-handle-power-key - (default 'poweroff)) - (handle-suspend-key elogind-handle-suspend-key - (default 'suspend)) - (handle-hibernate-key elogind-handle-hibernate-key - (default 'hibernate)) - (handle-lid-switch elogind-handle-lid-switch - (default 'suspend)) - (handle-lid-switch-docked elogind-handle-lid-switch-docked - (default 'ignore)) - (handle-lid-switch-external-power elogind-handle-lid-switch-external-power - (default *unspecified*)) - (power-key-ignore-inhibited? elogind-power-key-ignore-inhibited? - (default #f)) - (suspend-key-ignore-inhibited? elogind-suspend-key-ignore-inhibited? - (default #f)) - (hibernate-key-ignore-inhibited? elogind-hibernate-key-ignore-inhibited? - (default #f)) - (lid-switch-ignore-inhibited? elogind-lid-switch-ignore-inhibited? - (default #t)) - (holdoff-timeout-seconds elogind-holdoff-timeout-seconds - (default 30)) - (idle-action elogind-idle-action - (default 'ignore)) - (idle-action-seconds elogind-idle-action-seconds - (default (* 30 60))) - (runtime-directory-size-percent elogind-runtime-directory-size-percent - (default 10)) - (runtime-directory-size elogind-runtime-directory-size - (default #f)) - (remove-ipc? elogind-remove-ipc? - (default #t)) - - (suspend-state elogind-suspend-state - (default '("mem" "standby" "freeze"))) - (suspend-mode elogind-suspend-mode - (default '())) - (hibernate-state elogind-hibernate-state - (default '("disk"))) - (hibernate-mode elogind-hibernate-mode - (default '("platform" "shutdown"))) - (hybrid-sleep-state elogind-hybrid-sleep-state - (default '("disk"))) - (hybrid-sleep-mode elogind-hybrid-sleep-mode - (default - '("suspend" "platform" "shutdown"))) - (hibernate-delay-seconds elogind-hibernate-delay-seconds - (default *unspecified*)) - (suspend-estimation-seconds elogind-suspend-estimation-seconds - (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) - (match x - (#t "yes") - (#f "no") - (_ (error "expected #t or #f, instead got:" x)))) - (define char-set:user-name - (string->char-set "abcdefghijklmnopqrstuvwxyz0123456789_-")) - (define (valid-list? l pred) - (and-map (lambda (x) (string-every pred x)) l)) - (define (user-name-list users) - (unless (valid-list? users char-set:user-name) - (error "invalid user list" users)) - (string-join users " ")) - (define (enum val allowed) - (unless (memq val allowed) - (error "invalid value" val allowed)) - (symbol->string val)) - (define (non-negative-integer x) - (unless (exact-integer? x) (error "not an integer" x)) - (when (negative? x) (error "negative number not allowed" x)) - (number->string x)) - (define (maybe-non-negative-integer x) - (or (and (unspecified? x) x) - (non-negative-integer x))) - (define handle-actions - '(ignore poweroff reboot halt kexec suspend hibernate hybrid-sleep suspend-then-hibernate lock)) - (define (handle-action x) - (if (unspecified? x) - x ;let the unspecified value go through - (enum x handle-actions))) - (define (sleep-list tokens) - (unless (valid-list? tokens char-set:user-name) - (error "invalid sleep list" tokens)) - (string-join tokens " ")) - (define-syntax ini-file-clause - (syntax-rules () - ;; Produce an empty line when encountering an unspecified value. This - ;; is better than an empty string value, which can, in some cases, cause - ;; warnings such as "Failed to parse handle action setting". - ((_ config (prop (parser getter))) - (let ((value (parser (getter config)))) - (if (unspecified? value) - "" - (string-append prop "=" value "\n")))) - ((_ config str) - (if (unspecified? str) - "" - (string-append str "\n"))))) - (define-syntax-rule (ini-file config file clause ...) - (plain-file file (string-append (ini-file-clause config clause) ...))) - (ini-file - config "logind.conf" - "[Login]" - ("KillUserProcesses" (yesno elogind-kill-user-processes?)) - ("KillOnlyUsers" (user-name-list elogind-kill-only-users)) - ("KillExcludeUsers" (user-name-list elogind-kill-exclude-users)) - ("InhibitDelayMaxSec" (non-negative-integer elogind-inhibit-delay-max-seconds)) - ("HandlePowerKey" (handle-action elogind-handle-power-key)) - ("HandleSuspendKey" (handle-action elogind-handle-suspend-key)) - ("HandleHibernateKey" (handle-action elogind-handle-hibernate-key)) - ("HandleLidSwitch" (handle-action elogind-handle-lid-switch)) - ("HandleLidSwitchDocked" (handle-action elogind-handle-lid-switch-docked)) - ("HandleLidSwitchExternalPower" (handle-action elogind-handle-lid-switch-external-power)) - ("PowerKeyIgnoreInhibited" (yesno elogind-power-key-ignore-inhibited?)) - ("SuspendKeyIgnoreInhibited" (yesno elogind-suspend-key-ignore-inhibited?)) - ("HibernateKeyIgnoreInhibited" (yesno elogind-hibernate-key-ignore-inhibited?)) - ("LidSwitchIgnoreInhibited" (yesno elogind-lid-switch-ignore-inhibited?)) - ("HoldoffTimeoutSec" (non-negative-integer elogind-holdoff-timeout-seconds)) - ("IdleAction" (handle-action elogind-idle-action)) - ("IdleActionSec" (non-negative-integer elogind-idle-action-seconds)) - ("RuntimeDirectorySize" - (identity - (lambda (config) - (match (elogind-runtime-directory-size-percent config) - (#f (non-negative-integer (elogind-runtime-directory-size config))) - (percent (string-append (non-negative-integer percent) "%")))))) - ("RemoveIPC" (yesno elogind-remove-ipc?)) - "[Sleep]" - ("SuspendState" (sleep-list elogind-suspend-state)) - ("SuspendMode" (sleep-list elogind-suspend-mode)) - ("HibernateState" (sleep-list elogind-hibernate-state)) - ("HibernateMode" (sleep-list elogind-hibernate-mode)) - ("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)) - ("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?)))) +;;; Elogind configuration types. +(define-maybe boolean + (prefix elogind-)) + +(define (non-negative-integer? x) + (and (exact-integer? x) + (not (negative? x)))) + +(define-maybe non-negative-integer + (prefix elogind-)) + +(define (percent? x) + (and (non-negative-integer? x) + (>= x 0) + (<= x 100))) + +(define-maybe percent + (prefix elogind-)) + +(define char-set:user-name + (string->char-set "abcdefghijklmnopqrstuvwxyz0123456789_-")) + +(define (user-name? x) + (string-every char-set:user-name x)) + +(define list-of-user-names? + (list-of user-name?)) + +(define-maybe list-of-user-names + (prefix elogind-)) + +(define %elogind-actions + '( ignore poweroff reboot halt kexec suspend hibernate hybrid-sleep + suspend-then-hibernate lock factory-reset)) + +(define (action? x) + (member x %elogind-actions)) + +(define-maybe action + (prefix elogind-)) + +(define %linux-suspend-states + ;; The possible suspend states supported by the Linux kernel. + ;; See (info "(linux) Basic sysfs Interfaces for System Suspend and Hibernation"). + '(disk standby freeze mem)) + +(define (string->symbol/maybe x) + (if (string? x) + (string->symbol x) + x)) + +(define (suspend-state? x) + (member (string->symbol/maybe x) %linux-suspend-states)) + +(define list-of-suspend-states? + (list-of suspend-state?)) + +(define-maybe list-of-suspend-states + (prefix elogind-)) + +(define %linux-suspend-modes + ;; The possible suspend state variants supported by the Linux kernel. + ;; See (info "(linux) Basic sysfs Interfaces for System Suspend and Hibernation"). + '(s2idle shallow deep)) + +(define (suspend-mode? x) + (member (string->symbol/maybe x) %linux-suspend-modes)) + +(define list-of-suspend-modes? + (list-of suspend-mode?)) + +(define-maybe list-of-suspend-modes + (prefix elogind-)) + +(define %linux-hibernation-modes + ;; The possible hibernation operating modes supported by the Linux kernel. + ;; See (info "(linux) Basic sysfs Interfaces for System Suspend and Hibernation"). + '(platform shutdown reboot suspend test_resume)) + +(define (hibernation-mode? x) + (member (string->symbol/maybe x) %linux-hibernation-modes)) + +(define list-of-hibernation-modes? + (list-of hibernation-mode?)) + +(define-maybe list-of-hibernation-modes + (prefix elogind-)) + +(define (elogind-deprecated-empty-serializer name value) + (when (maybe-value-set? value) + (warn-about-deprecation name #f + #:replacement #f)) + "") + +(define list-of-file-likes? + (list-of file-like?)) + +(define-maybe list-of-strings + (prefix elogind-)) + +;;; Elogind serializers. +(define (elogind-serialize-boolean name value) + (let* ((name-str (symbol->string name)) + (name (if (string-suffix? "?" name-str) + (string-drop-right name-str 1) + name-str))) + (format #f "~a=~:[no~;yes~]~%" (pascal-case name) value))) + +(define (elogind-base-serializer name value) + (let* ((name-str (symbol->string name)) + (name (if (string-suffix? "seconds" name-str) + (string-drop-right name-str 4) ;seconds -> sec + name-str))) + (format #f "~a=~a~%" (pascal-case name) value))) + +(define elogind-serialize-action elogind-base-serializer) +(define elogind-serialize-non-negative-integer elogind-base-serializer) +(define elogind-serialize-percent elogind-base-serializer) + +(define (elogind-list-serializer name value) + (format #f "~a=~{~a~^ ~}~%" (pascal-case name) value)) + +(define elogind-serialize-list-of-strings elogind-list-serializer) +(define elogind-serialize-list-of-user-names elogind-list-serializer) +(define elogind-serialize-list-of-suspend-states elogind-list-serializer) +(define elogind-serialize-list-of-suspend-modes elogind-list-serializer) +(define elogind-serialize-list-of-hibernation-modes elogind-list-serializer) + +;;; XXX: For backward-compatible/historical reasons, the configuration object +;;; is flat, containing the fields of both the logind.conf and sleep.conf +;;; files. The list below contains the fields that should be serialized to +;;; sleep.conf. +(define %elogind-configuration-sleep-fields + '( suspend-state suspend-mode suspend-estimation-seconds + hibernate-mode hibernate-delay-seconds hibernate-state + hybrid-sleep-state hybrid-sleep-mode)) + +(define-configuration elogind-configuration + (elogind + (file-like elogind) + "The elogind package to use." + (serializer empty-serializer)) + + (system-sleep-hook-files + (list-of-file-likes '()) + "A list of executables (file-like objects) that will be installed into the +@file{/etc/elogind/system-sleep} hook directory. See `Hook directories' in +the @samp{loginctl(1)} man page for more information." + (serializer empty-serializer)) + + (system-shutdown-hook-files + (list-of-file-likes '()) + "A list of executables (file-like objects) that will be installed into the +@file{/etc/elogind/system-shutdown/} hook directory." + (serializer empty-serializer)) + + (allow-power-off-interrupts? + (maybe-boolean #f) + "Whether the executables in elogind's hook directories (see above) can + cause a power-off action to be cancelled (interrupted) by printing an + appropriate error message to stdout.") + + (allow-suspend-interrupts? + (maybe-boolean #f) + "Likewise as the @code{allow-power-off-interrupts?} option, but for the + suspend action.") + + (broadcast-power-off-interrupts? + (maybe-boolean #f) + "Whether an interrupt of a power-off action is broadcasted.") + + (broadcast-suspend-interrupts? + (maybe-boolean #f) + "Whether an interrupt of a suspend action is broadcasted.") + + ;; logind.conf options. + (kill-user-processes? + (maybe-boolean #f) + "Whether the processes of a user should be killed when the user logs + out.") + + (kill-only-users + maybe-list-of-user-names + "Usernames whose processes should be killed, regardless the value of + @code{kill-user-processes?}.") + + (kill-exclude-users + (maybe-list-of-user-names (list "root")) + "Usernames whose processes should @emph{not} be killed, regardless the + value of @code{kill-user-processes?}.") + + (inhibit-delay-max-seconds + (maybe-non-negative-integer 5) + "The maximum time a system shutdown or sleep request is delayed due to an + inhibitor lock of type delay being active before the inhibitor is ignored and + the operation executes anyway.") + + (handle-power-key + (maybe-action 'poweroff) + "The action done when the power key is pressed. The compiled default is + @code{'poweroff}.") + + (handle-suspend-key + (maybe-action 'suspend) + "The action done when the suspend key is pressed. The ") + + (handle-hibernate-key + (maybe-action 'hibernate) + "The action done when the hibernate key is pressed.") + + (handle-lid-switch + (maybe-action 'suspend) + "The action done when the lid is closed.") + + (handle-lid-switch-docked + (maybe-action 'ignore) + "The action done when the lid is closed and the device docked.") + + (handle-lid-switch-external-power + (maybe-action 'suspend) + "The action done when the lid is closed and the device is externally + powered.") + + (power-key-ignore-inhibited? + (maybe-boolean #f) + "Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or + idle) when the power key is pressed.") + + (suspend-key-ignore-inhibited? + (maybe-boolean #f) + "Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or + idle) when the suspend key is pressed.") + + (hibernate-key-ignore-inhibited? + (maybe-boolean #f) + "Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or + idle) when the hibernate key is pressed.") + + (lid-switch-ignore-inhibited? + (maybe-boolean #f) + "Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or + idle) when the lid is closed.") + + (holdoff-timeout-seconds + (maybe-non-negative-integer 30) + "Specifies the number of seconds after system startup or system resume +during which elogind will hold off on reacting to lid events.") + + (idle-action + (maybe-action 'ignore) + "Action to take when the system is idle.") + + (idle-action-seconds + maybe-non-negative-integer + "The delay after which the action configured in @code{idle-action} is +taken after the system is idle.") + + ;; XXX: Perhaps deprecate in the future and handle all the accepted forms + ;; directly in 'runtime-directory-size' instead. + (runtime-directory-size-percent + maybe-percent + "Set the size limit, in percent, on the @env{XDG_RUNTIME_DIR} runtime +directory for each user who logs in. This specifies the per-user size limit +relative to the amount of physical @acronym{RAM, read access memory}. This +value takes precedence over that specified via @code{runtime-directory-size}." + (serializer empty-serializer)) ;special cased at serialization time + + (runtime-directory-size + maybe-non-negative-integer + "Set the size limit, in bytes, on the @env{XDG_RUNTIME_DIR} runtime +directory for each user who logs in." + (serializer empty-serializer)) ;special cased at serialization time + + (remove-ipc? + (maybe-boolean #t) + "Whether @acronym{IPC, inter-process communication} objects belonging to +the user shall be removed when the user fully logs out.") + + ;; sleep.conf options. + ;; CAUTION: all sleep.conf option names must be registered in the above + ;; %ELOGIND-CONFIGURATION-SLEEP-FIELDS variable: otherwise they will be + ;; serialized to logind.conf instead of sleep.conf! + (suspend-state + (maybe-list-of-suspend-states '(mem standby freeze)) + "The suspend state values to be write to @file{/sys/power/state} by elogind + when suspending the system. They will be tried in turn, until one is written + without error.") + + (suspend-mode + (maybe-list-of-suspend-modes) + "The suspend mode values to write to @file{/sys/power/mem_sleep} by elogind + when suspending the system.") + + (suspend-estimation-seconds + (maybe-non-negative-integer (* 60 60)) ;1 hour + "Cause the RTC alarm to wake the system after the specified time span to + measure the system battery capacity level and estimate the battery discharging + rate, which is used for estimating the time span until the system battery + charge level goes down to 5%. This option is only used by elogind when using + the @code{'suspend-then-hibernate} action.") + + (hibernate-mode + (maybe-list-of-hibernation-modes '(platform shutdown)) + "The hibernation mode values to write to @file{/sys/power/disk} by elogind + when hibernating the system.") + + (hibernate-delay-seconds + maybe-non-negative-integer + "The amount of time the system spends in suspend mode before the system is + automatically put into hibernate mode.") + + ;; TODO: Remove in May 2026. + (hibernate-state + maybe-list-of-strings + "Deprecated option." + (serializer elogind-deprecated-empty-serializer)) + + ;; TODO: Remove in May 2026. + (hybrid-sleep-state + maybe-list-of-strings + "Deprecated option." + (serializer elogind-deprecated-empty-serializer)) + + ;; TODO: Remove in May 2026. + (hybrid-sleep-mode + maybe-list-of-strings + "Deprecated option." + (serializer elogind-deprecated-empty-serializer)) + + (prefix elogind-)) + +(define (logind.conf config) + (let ((logind-fields (remove (lambda (field) + (memq (configuration-field-name field) + %elogind-configuration-sleep-fields)) + elogind-configuration-fields))) + (match-record config <elogind-configuration> + (runtime-directory-size-percent runtime-directory-size) + ;; Handle the special-cased + ;; runtime-directory-size-percent/runtime-directory-size options pair. + (let ((runtime-directory-size + (if (maybe-value-set? runtime-directory-size-percent) + (format #f "~a%~%" runtime-directory-size-percent) ;10 -> 10% + runtime-directory-size))) + (mixed-text-file + "logind.conf" + "[Login]\n" + (if (maybe-value-set? runtime-directory-size) + (list "RuntimeDirectorySize=" runtime-directory-size) + "") + (serialize-configuration config logind-fields)))))) + +(define (sleep.conf config) + (let ((sleep-fields (filter (lambda (field) + (memq (configuration-field-name field) + %elogind-configuration-sleep-fields)) + elogind-configuration-fields))) + (mixed-text-file + "sleep.conf" + "[Sleep]\n" + (serialize-configuration config sleep-fields)))) (define (elogind-etc-directory config) "Return the /etc/elogind directory for CONFIG." @@ -1213,12 +1410,19 @@ (define (elogind-etc-directory config) (chmod dest #o500))) (mkdir-p #$output) ;in case neither directory gets created + + ;; Symlink the main configuration files. + (with-directory-excursion #$output + (symlink #$(logind.conf config) "logind.conf") + (symlink #$(sleep.conf config) "sleep.conf")) + (for-each (lambda (f) (copy-script f sleep-directory)) - '#$(elogind-system-sleep-hook-files config)) + '#$(elogind-configuration-system-sleep-hook-files config)) (for-each (lambda (f) (copy-script f shutdown-directory)) - '#$(elogind-system-shutdown-hook-files config)))))) + '#$(elogind-configuration-system-shutdown-hook-files + config)))))) (define (elogind-dbus-service config) "Return a @file{org.freedesktop.login1.service} file that tells D-Bus how to @@ -1231,7 +1435,7 @@ (define (elogind-dbus-service config) ;; <https://issues.guix.gnu.org/55444>. (define elogind - (elogind-package config)) + (elogind-configuration-elogind config)) (define wrapper (program-file "elogind-dbus-shepherd-sync" @@ -1288,7 +1492,7 @@ (define (pam-extension-procedure config) (define pam-elogind (pam-entry (control "required") - (module (file-append (elogind-package config) + (module (file-append (elogind-configuration-elogind config) "/lib/security/pam_elogind.so")))) (list (pam-extension @@ -1301,56 +1505,52 @@ (define (pam-extension-procedure config) (define (elogind-shepherd-service config) "Return a Shepherd service to start elogind according to @var{config}." - (define config-file - (elogind-configuration-file config)) - (list (shepherd-service (requirement '(user-processes dbus-system)) (provision '(elogind)) (start #~(make-forkexec-constructor - (list #$(file-append (elogind-package config) - "/libexec/elogind/elogind")) - #:environment-variables - (list (string-append "ELOGIND_CONF_FILE=" - #$config-file)))) + (list #$(file-append (elogind-configuration-elogind config) + "/libexec/elogind/elogind")))) (stop #~(make-kill-destructor)) - (actions (list (shepherd-configuration-action config-file)))))) + (actions (list (shepherd-configuration-action + "/etc/elogind/logind.conf")))))) (define elogind-service-type - (service-type (name 'elogind) - (extensions - (list (service-extension dbus-root-service-type - elogind-dbus-service) - (service-extension udev-service-type - (compose list elogind-package)) - (service-extension polkit-service-type - (compose list elogind-package)) - - ;; Start elogind from the Shepherd rather than waiting - ;; for bus activation. This ensures that it can handle - ;; events like lid close, etc. - (service-extension shepherd-root-service-type - elogind-shepherd-service) - - ;; Provide the 'loginctl' command. - (service-extension profile-service-type - (compose list elogind-package)) - - ;; Extend PAM with pam_elogind.so. - (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)))) - (default-value (elogind-configuration)) - (description "Run the @command{elogind} login and seat + (service-type + (name 'elogind) + (extensions + (list (service-extension dbus-root-service-type + elogind-dbus-service) + (service-extension udev-service-type + (compose list elogind-configuration-elogind)) + (service-extension polkit-service-type + (compose list elogind-configuration-elogind)) + + ;; Start elogind from the Shepherd rather than waiting + ;; for bus activation. This ensures that it can handle + ;; events like lid close, etc. + (service-extension shepherd-root-service-type + elogind-shepherd-service) + + ;; Provide the 'loginctl' command. + (service-extension profile-service-type + (compose list elogind-configuration-elogind)) + + ;; Extend PAM with pam_elogind.so. + (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)))) + (default-value (elogind-configuration)) + (description "Run the @command{elogind} login and seat management service. The @command{elogind} service integrates with PAM to allow other system components to know the set of logged-in users as well as their session types (graphical, console, remote, etc.). It can also clean up base-commit: 5b981a2b5c9c880634d883f3b7ae078b4fa75fdb -- 2.49.0
bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Fri, 25 Apr 2025 08:15:02 GMT) Full text and rfc822 format available.Message #25 received at 77806 <at> debbugs.gnu.org (full text, mbox):
From: Josselin Poiret <dev <at> jpoiret.xyz> To: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, 77806 <at> debbugs.gnu.org Cc: Vivien Kraus <vivien <at> planete-kraus.eu>, Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, Noé Lopez <noelopez <at> free.fr>, Liliana Marie Prikler <liliana.prikler <at> gmail.com>, Bas Alberts <bas <at> anti.computer>, Ludovic Courtès <ludo <at> gnu.org> Subject: Re: bug#77806: [PATCH v2] services: elogind: Split sleep.conf and port to define-configuration. Date: Fri, 25 Apr 2025 10:14:05 +0200
[Message part 1 (text/plain, inline)]
Hi Maxim, Maxim Cournoyer <maxim.cournoyer <at> gmail.com> writes: > + ;; Symlink the main configuration files. > + (with-directory-excursion #$output > + (symlink #$(logind.conf config) "logind.conf") > + (symlink #$(sleep.conf config) "sleep.conf")) I don't know about you, but this didn't work for me, as elogind looks for the config file in its own PKGCONFDIR (which is in the store), only looking for overrides in the /etc/elogind/*.d/ directories. Best, -- Josselin Poiret
[signature.asc (application/pgp-signature, inline)]
ludo <at> gnu.org, bas <at> anti.computer, maxim.cournoyer <at> gmail.com, dev <at> jpoiret.xyz, liliana.prikler <at> gmail.com, noelopez <at> free.fr, vivien <at> planete-kraus.eu, bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Fri, 25 Apr 2025 14:13:03 GMT) Full text and rfc822 format available.Message #28 received at 77806 <at> debbugs.gnu.org (full text, mbox):
From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> To: 77806 <at> debbugs.gnu.org Cc: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> Subject: [PATCH v3] services: elogind: Split sleep.conf and port to define-configuration. Date: Fri, 25 Apr 2025 23:11:33 +0900
* gnu/services/desktop.scm (pascal-case): New procedure. (<elogind-configuration>): Rewrite in terms of define-configuration. (elogind-configuration-file): Delete. (maybe-list-of-suspend-states?, maybe-list-of-suspend-modes?) maybe-list-of-user-names?, maybe-boolean?maybe-package?) (maybe-action?, maybe-percent?, maybe-list-of-strings?) (maybe-list-of-hibernation-modes?, maybe-non-negative-integer?) (non-negative-integer?, percent?, char-set:user-name, user-name?) (list-of-user-names?, %elogind-actions, action?, %linux-suspend-states) (string->symbol/maybe, suspend-state?, list-of-suspend-states?) (%linux-suspend-modes, suspend-mode?, list-of-suspend-modes?) (%linux-hibernation-modes, hibernation-mode?, list-of-hibernation-modes?) (elogind-deprecated-empty-serializer, list-of-file-likes?) (elogind-serialize-boolean, elogind-base-serializer, elogind-serialize-action) (elogind-serialize-non-negative-integer, elogind-serialize-percent) (elogind-list-serializer, elogind-serialize-list-of-strings) (elogind-serialize-list-of-user-names, elogind-serialize-list-of-suspend-states) (elogind-serialize-list-of-suspend-modes) (elogind-serialize-list-of-hibernation-modes) (%elogind-configuration-sleep-fields, logind.conf, sleep.conf): New procedures. (elogind-etc-directory): Create the main configuration files there too. (elogind-dbus-service): Adjust for package accessor name change. (pam-extension-procedure, elogind-shepherd-service) (elogind-service-type): Likewise. * doc/guix.texi (Desktop Services): Fully document configuration options. Fixes: bug#77806 Change-Id: I8767891871d83e58d64995ec986a7d01689fa6d8 --- doc/guix.texi | 191 +++++++----- gnu/services/desktop.scm | 630 ++++++++++++++++++++++++++------------- 2 files changed, 526 insertions(+), 295 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index be2fbbaf5bc..7b418a40892 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -26264,129 +26264,158 @@ Desktop Services @code{<elogind-configuration>} object. @end defvar -@c TODO: field descriptions. This is best done by refactoring -@c elogind-configuration to use define-configuration which embeds the -@c descriptions in the code and then use configuration->documentation. +@c Auto-generated via (configuration->documentation 'elogind-configuration). +@c %start of fragment + @deftp {Data Type} elogind-configuration -Data type representing the configuration of @command{elogind}. +Available @code{elogind-configuration} fields are: @table @asis @item @code{elogind} (default: @code{elogind}) (type: file-like) -... +The elogind package to use. -@item @code{kill-user-processes?} (default: @code{#f}) (type: boolean) -... +@item @code{system-sleep-hook-files} (default: @code{()}) (type: list-of-file-likes) +A list of executables (file-like objects) that will be installed into +the @file{/etc/elogind/system-sleep} hook directory. See `Hook +directories' in the @samp{loginctl(1)} man page for more information. -@item @code{kill-only-users} (default: @code{'()}) (type: list) -... +@item @code{system-shutdown-hook-files} (default: @code{()}) (type: list-of-file-likes) +A list of executables (file-like objects) that will be installed into +the @file{/etc/elogind/system-shutdown/} hook directory. -@item @code{kill-exclude-users} (default: @code{'("root")}) (type: list-of-string) -... +@item @code{allow-power-off-interrupts?} (default: @code{#f}) (type: maybe-boolean) +Whether the executables in elogind's hook directories (see above) can +cause a power-off action to be cancelled (interrupted) by printing an +appropriate error message to stdout. -@item @code{inhibit-delay-max-seconds} (default: @code{5}) (type: integer) -... +@item @code{allow-suspend-interrupts?} (default: @code{#f}) (type: maybe-boolean) +Likewise as the @code{allow-power-off-interrupts?} option, but for the +suspend action. -@item @code{handle-power-key} (default: @code{'poweroff}) (type: symbol) -... +@item @code{broadcast-power-off-interrupts?} (default: @code{#f}) (type: maybe-boolean) +Whether an interrupt of a power-off action is broadcasted. -@item @code{handle-suspend-key} (default: @code{'suspend}) (type: symbol) -... +@item @code{broadcast-suspend-interrupts?} (default: @code{#f}) (type: maybe-boolean) +Whether an interrupt of a suspend action is broadcasted. -@item @code{handle-hibernate-key} (default: @code{'hibernate}) (type: symbol) -... +@item @code{kill-user-processes?} (default: @code{#f}) (type: maybe-boolean) +Whether the processes of a user should be killed when the user logs out. -@item @code{handle-lid-switch} (default: @code{'suspend}) (type: symbol) -... +@item @code{kill-only-users} (type: maybe-list-of-user-names) +Usernames whose processes should be killed, regardless the value of +@code{kill-user-processes?}. -@item @code{handle-lid-switch-docked} (default: @code{'ignore}) (type: symbol) -... +@item @code{kill-exclude-users} (default: @code{("root")}) (type: maybe-list-of-user-names) +Usernames whose processes should @emph{not} be killed, regardless the +value of @code{kill-user-processes?}. -@item @code{handle-lid-switch-external-power} (default: @code{*unspecified*}) (type: symbol) -... +@item @code{inhibit-delay-max-seconds} (default: @code{5}) (type: maybe-non-negative-integer) +The maximum time a system shutdown or sleep request is delayed due to an +inhibitor lock of type delay being active before the inhibitor is +ignored and the operation executes anyway. -@item @code{power-key-ignore-inhibited?} (default: @code{#f}) (type: boolean) -... +@item @code{handle-power-key} (default: @code{poweroff}) (type: maybe-action) +The action done when the power key is pressed. The compiled default is +@code{'poweroff}. -@item @code{suspend-key-ignore-inhibited?} (default: @code{#f}) (type: boolean) -... +@item @code{handle-suspend-key} (default: @code{suspend}) (type: maybe-action) +The action done when the suspend key is pressed. The -@item @code{hibernate-key-ignore-inhibited?} (default: @code{#f}) (type: boolean) -... +@item @code{handle-hibernate-key} (default: @code{hibernate}) (type: maybe-action) +The action done when the hibernate key is pressed. -@item @code{lid-switch-ignore-inhibited?} (default: @code{#t}) (type: boolean) -... +@item @code{handle-lid-switch} (default: @code{suspend}) (type: maybe-action) +The action done when the lid is closed. -@item @code{holdoff-timeout-seconds} (default: @code{30}) (type: integer) -... +@item @code{handle-lid-switch-docked} (default: @code{ignore}) (type: maybe-action) +The action done when the lid is closed and the device docked. -@item @code{idle-action} (default: @code{'ignore}) (type: symbol) -... +@item @code{handle-lid-switch-external-power} (default: @code{suspend}) (type: maybe-action) +The action done when the lid is closed and the device is externally +powered. -@item @code{idle-action-seconds} (default: @code{(* 30 60)}) (type: integer) -... +@item @code{power-key-ignore-inhibited?} (default: @code{#f}) (type: maybe-boolean) +Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or +idle) when the power key is pressed. -@item @code{runtime-directory-size-percent} (default: @code{10}) (type: integer) -... +@item @code{suspend-key-ignore-inhibited?} (default: @code{#f}) (type: maybe-boolean) +Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or +idle) when the suspend key is pressed. -@item @code{runtime-directory-size} (default: @code{#f}) (type: integer) -... +@item @code{hibernate-key-ignore-inhibited?} (default: @code{#f}) (type: maybe-boolean) +Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or +idle) when the hibernate key is pressed. -@item @code{remove-ipc?} (default: @code{#t}) (type: boolean) -... +@item @code{lid-switch-ignore-inhibited?} (default: @code{#f}) (type: maybe-boolean) +Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or +idle) when the lid is closed. -@item @code{suspend-state} (default: @code{'("mem" "standby" "freeze")}) (type: list) -... +@item @code{holdoff-timeout-seconds} (default: @code{30}) (type: maybe-non-negative-integer) +Specifies the number of seconds after system startup or system resume +during which elogind will hold off on reacting to lid events. -@item @code{suspend-mode} (default: @code{'()}) (type: list) -... +@item @code{idle-action} (default: @code{ignore}) (type: maybe-action) +Action to take when the system is idle. -@item @code{hibernate-state} (default: @code{'("disk")}) (type: list) -... +@item @code{idle-action-seconds} (type: maybe-non-negative-integer) +The delay after which the action configured in @code{idle-action} is +taken after the system is idle. -@item @code{hibernate-mode} (default: @code{'("platform" "shutdown")}) (type: list) -... +@item @code{runtime-directory-size-percent} (type: maybe-percent) +Set the size limit, in percent, on the @env{XDG_RUNTIME_DIR} runtime +directory for each user who logs in. This specifies the per-user size +limit relative to the amount of physical @acronym{RAM,read access +memory}. This value takes precedence over that specified via +@code{runtime-directory-size}. -@item @code{hybrid-sleep-state} (default: @code{'("disk")}) (type: list) -... +@item @code{runtime-directory-size} (type: maybe-non-negative-integer) +Set the size limit, in bytes, on the @env{XDG_RUNTIME_DIR} runtime +directory for each user who logs in. -@item @code{hybrid-sleep-mode} (default: @code{'("suspend" "platform" "shutdown")}) (type: list) -... +@item @code{remove-ipc?} (default: @code{#t}) (type: maybe-boolean) +Whether @acronym{IPC,inter-process communication} objects belonging to +the user shall be removed when the user fully logs out. -@item @code{hibernate-delay-seconds} (default: @code{*unspecified*}) (type: integer) -... +@item @code{suspend-state} (default: @code{(mem standby freeze)}) (type: maybe-list-of-suspend-states) +The suspend state values to be write to @file{/sys/power/state} by +elogind when suspending the system. They will be tried in turn, until +one is written without error. -@item @code{suspend-estimation-seconds} (default: @code{*unspecified*}) (type: integer) -... +@item @code{suspend-mode} (type: maybe-list-of-suspend-modes) +The suspend mode values to write to @file{/sys/power/mem_sleep} by +elogind when suspending the system. -@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: +@item @code{suspend-estimation-seconds} (default: @code{3600}) (type: maybe-non-negative-integer) +Cause the RTC alarm to wake the system after the specified time span to +measure the system battery capacity level and estimate the battery +discharging rate, which is used for estimating the time span until the +system battery charge level goes down to 5%. This option is only used +by elogind when using the @code{'suspend-then-hibernate} action. -@lisp -(elogind-configuration - (system-sleep-hook-files - (list (local-file "sleep-script")))) -@end lisp +@item @code{hibernate-mode} (default: @code{(platform shutdown)}) (type: maybe-list-of-hibernation-modes) +The hibernation mode values to write to @file{/sys/power/disk} by +elogind when hibernating the system. -See `Hook directories' in the @code{loginctl(1)} man page for more information. +@item @code{hibernate-delay-seconds} (type: maybe-non-negative-integer) +The amount of time the system spends in suspend mode before the system +is automatically put into hibernate mode. -@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{hibernate-state} (type: maybe-list-of-strings) +Deprecated option. -@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{hybrid-sleep-state} (type: maybe-list-of-strings) +Deprecated option. -@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. +@item @code{hybrid-sleep-mode} (type: maybe-list-of-strings) +Deprecated option. @end table + @end deftp + +@c %end of fragment + @defvar accountsservice-service-type Type for the service that runs AccountsService, a system service that can list available accounts, change their passwords, and so on. diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm index fe034cfa8f4..04babf0e82d 100644 --- a/gnu/services/desktop.scm +++ b/gnu/services/desktop.scm @@ -37,6 +37,7 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu services desktop) + #:use-module ((gnu home services utils) #:select (object->camel-case-string)) #:use-module (gnu services) #:use-module (gnu services shepherd) #:use-module (gnu services base) @@ -228,6 +229,8 @@ (define (package-direct-input-selector tree) (loop (cdr tree) (car (assoc-ref (package-direct-inputs package) (car tree)))))))) +(define (pascal-case text) + (object->camel-case-string text 'upper)) ;;; @@ -1025,173 +1028,367 @@ (define gvfs-service-type ;;; Elogind login and seat management service. ;;; -(define-record-type* <elogind-configuration> elogind-configuration - make-elogind-configuration - elogind-configuration? - (elogind elogind-package - (default elogind)) - (kill-user-processes? elogind-kill-user-processes? - (default #f)) - (kill-only-users elogind-kill-only-users - (default '())) - (kill-exclude-users elogind-kill-exclude-users - (default '("root"))) - (inhibit-delay-max-seconds elogind-inhibit-delay-max-seconds - (default 5)) - (handle-power-key elogind-handle-power-key - (default 'poweroff)) - (handle-suspend-key elogind-handle-suspend-key - (default 'suspend)) - (handle-hibernate-key elogind-handle-hibernate-key - (default 'hibernate)) - (handle-lid-switch elogind-handle-lid-switch - (default 'suspend)) - (handle-lid-switch-docked elogind-handle-lid-switch-docked - (default 'ignore)) - (handle-lid-switch-external-power elogind-handle-lid-switch-external-power - (default *unspecified*)) - (power-key-ignore-inhibited? elogind-power-key-ignore-inhibited? - (default #f)) - (suspend-key-ignore-inhibited? elogind-suspend-key-ignore-inhibited? - (default #f)) - (hibernate-key-ignore-inhibited? elogind-hibernate-key-ignore-inhibited? - (default #f)) - (lid-switch-ignore-inhibited? elogind-lid-switch-ignore-inhibited? - (default #t)) - (holdoff-timeout-seconds elogind-holdoff-timeout-seconds - (default 30)) - (idle-action elogind-idle-action - (default 'ignore)) - (idle-action-seconds elogind-idle-action-seconds - (default (* 30 60))) - (runtime-directory-size-percent elogind-runtime-directory-size-percent - (default 10)) - (runtime-directory-size elogind-runtime-directory-size - (default #f)) - (remove-ipc? elogind-remove-ipc? - (default #t)) - - (suspend-state elogind-suspend-state - (default '("mem" "standby" "freeze"))) - (suspend-mode elogind-suspend-mode - (default '())) - (hibernate-state elogind-hibernate-state - (default '("disk"))) - (hibernate-mode elogind-hibernate-mode - (default '("platform" "shutdown"))) - (hybrid-sleep-state elogind-hybrid-sleep-state - (default '("disk"))) - (hybrid-sleep-mode elogind-hybrid-sleep-mode - (default - '("suspend" "platform" "shutdown"))) - (hibernate-delay-seconds elogind-hibernate-delay-seconds - (default *unspecified*)) - (suspend-estimation-seconds elogind-suspend-estimation-seconds - (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) - (match x - (#t "yes") - (#f "no") - (_ (error "expected #t or #f, instead got:" x)))) - (define char-set:user-name - (string->char-set "abcdefghijklmnopqrstuvwxyz0123456789_-")) - (define (valid-list? l pred) - (and-map (lambda (x) (string-every pred x)) l)) - (define (user-name-list users) - (unless (valid-list? users char-set:user-name) - (error "invalid user list" users)) - (string-join users " ")) - (define (enum val allowed) - (unless (memq val allowed) - (error "invalid value" val allowed)) - (symbol->string val)) - (define (non-negative-integer x) - (unless (exact-integer? x) (error "not an integer" x)) - (when (negative? x) (error "negative number not allowed" x)) - (number->string x)) - (define (maybe-non-negative-integer x) - (or (and (unspecified? x) x) - (non-negative-integer x))) - (define handle-actions - '(ignore poweroff reboot halt kexec suspend hibernate hybrid-sleep suspend-then-hibernate lock)) - (define (handle-action x) - (if (unspecified? x) - x ;let the unspecified value go through - (enum x handle-actions))) - (define (sleep-list tokens) - (unless (valid-list? tokens char-set:user-name) - (error "invalid sleep list" tokens)) - (string-join tokens " ")) - (define-syntax ini-file-clause - (syntax-rules () - ;; Produce an empty line when encountering an unspecified value. This - ;; is better than an empty string value, which can, in some cases, cause - ;; warnings such as "Failed to parse handle action setting". - ((_ config (prop (parser getter))) - (let ((value (parser (getter config)))) - (if (unspecified? value) - "" - (string-append prop "=" value "\n")))) - ((_ config str) - (if (unspecified? str) - "" - (string-append str "\n"))))) - (define-syntax-rule (ini-file config file clause ...) - (plain-file file (string-append (ini-file-clause config clause) ...))) - (ini-file - config "logind.conf" - "[Login]" - ("KillUserProcesses" (yesno elogind-kill-user-processes?)) - ("KillOnlyUsers" (user-name-list elogind-kill-only-users)) - ("KillExcludeUsers" (user-name-list elogind-kill-exclude-users)) - ("InhibitDelayMaxSec" (non-negative-integer elogind-inhibit-delay-max-seconds)) - ("HandlePowerKey" (handle-action elogind-handle-power-key)) - ("HandleSuspendKey" (handle-action elogind-handle-suspend-key)) - ("HandleHibernateKey" (handle-action elogind-handle-hibernate-key)) - ("HandleLidSwitch" (handle-action elogind-handle-lid-switch)) - ("HandleLidSwitchDocked" (handle-action elogind-handle-lid-switch-docked)) - ("HandleLidSwitchExternalPower" (handle-action elogind-handle-lid-switch-external-power)) - ("PowerKeyIgnoreInhibited" (yesno elogind-power-key-ignore-inhibited?)) - ("SuspendKeyIgnoreInhibited" (yesno elogind-suspend-key-ignore-inhibited?)) - ("HibernateKeyIgnoreInhibited" (yesno elogind-hibernate-key-ignore-inhibited?)) - ("LidSwitchIgnoreInhibited" (yesno elogind-lid-switch-ignore-inhibited?)) - ("HoldoffTimeoutSec" (non-negative-integer elogind-holdoff-timeout-seconds)) - ("IdleAction" (handle-action elogind-idle-action)) - ("IdleActionSec" (non-negative-integer elogind-idle-action-seconds)) - ("RuntimeDirectorySize" - (identity - (lambda (config) - (match (elogind-runtime-directory-size-percent config) - (#f (non-negative-integer (elogind-runtime-directory-size config))) - (percent (string-append (non-negative-integer percent) "%")))))) - ("RemoveIPC" (yesno elogind-remove-ipc?)) - "[Sleep]" - ("SuspendState" (sleep-list elogind-suspend-state)) - ("SuspendMode" (sleep-list elogind-suspend-mode)) - ("HibernateState" (sleep-list elogind-hibernate-state)) - ("HibernateMode" (sleep-list elogind-hibernate-mode)) - ("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)) - ("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?)))) +;;; Elogind configuration types. +(define-maybe boolean + (prefix elogind-)) + +(define (non-negative-integer? x) + (and (exact-integer? x) + (not (negative? x)))) + +(define-maybe non-negative-integer + (prefix elogind-)) + +(define (percent? x) + (and (non-negative-integer? x) + (>= x 0) + (<= x 100))) + +(define-maybe percent + (prefix elogind-)) + +(define char-set:user-name + (string->char-set "abcdefghijklmnopqrstuvwxyz0123456789_-")) + +(define (user-name? x) + (string-every char-set:user-name x)) + +(define list-of-user-names? + (list-of user-name?)) + +(define-maybe list-of-user-names + (prefix elogind-)) + +(define %elogind-actions + '( ignore poweroff reboot halt kexec suspend hibernate hybrid-sleep + suspend-then-hibernate lock factory-reset)) + +(define (action? x) + (member x %elogind-actions)) + +(define-maybe action + (prefix elogind-)) + +(define %linux-suspend-states + ;; The possible suspend states supported by the Linux kernel. + ;; See (info "(linux) Basic sysfs Interfaces for System Suspend and Hibernation"). + '(disk standby freeze mem)) + +(define (string->symbol/maybe x) + (if (string? x) + (string->symbol x) + x)) + +(define (suspend-state? x) + (member (string->symbol/maybe x) %linux-suspend-states)) + +(define list-of-suspend-states? + (list-of suspend-state?)) + +(define-maybe list-of-suspend-states + (prefix elogind-)) + +(define %linux-suspend-modes + ;; The possible suspend state variants supported by the Linux kernel. + ;; See (info "(linux) Basic sysfs Interfaces for System Suspend and Hibernation"). + '(s2idle shallow deep)) + +(define (suspend-mode? x) + (member (string->symbol/maybe x) %linux-suspend-modes)) + +(define list-of-suspend-modes? + (list-of suspend-mode?)) + +(define-maybe list-of-suspend-modes + (prefix elogind-)) + +(define %linux-hibernation-modes + ;; The possible hibernation operating modes supported by the Linux kernel. + ;; See (info "(linux) Basic sysfs Interfaces for System Suspend and Hibernation"). + '(platform shutdown reboot suspend test_resume)) + +(define (hibernation-mode? x) + (member (string->symbol/maybe x) %linux-hibernation-modes)) + +(define list-of-hibernation-modes? + (list-of hibernation-mode?)) + +(define-maybe list-of-hibernation-modes + (prefix elogind-)) + +(define (elogind-deprecated-empty-serializer name value) + (when (maybe-value-set? value) + (warn-about-deprecation name #f + #:replacement #f)) + "") + +(define list-of-file-likes? + (list-of file-like?)) + +(define-maybe list-of-strings + (prefix elogind-)) + +;;; Elogind serializers. +(define (elogind-serialize-boolean name value) + (let* ((name-str (symbol->string name)) + (name (if (string-suffix? "?" name-str) + (string-drop-right name-str 1) + name-str))) + (format #f "~a=~:[no~;yes~]~%" (pascal-case name) value))) + +(define (elogind-base-serializer name value) + (let* ((name-str (symbol->string name)) + (name (if (string-suffix? "seconds" name-str) + (string-drop-right name-str 4) ;seconds -> sec + name-str))) + (format #f "~a=~a~%" (pascal-case name) value))) + +(define elogind-serialize-action elogind-base-serializer) +(define elogind-serialize-non-negative-integer elogind-base-serializer) +(define elogind-serialize-percent elogind-base-serializer) + +(define (elogind-list-serializer name value) + (format #f "~a=~{~a~^ ~}~%" (pascal-case name) value)) + +(define elogind-serialize-list-of-strings elogind-list-serializer) +(define elogind-serialize-list-of-user-names elogind-list-serializer) +(define elogind-serialize-list-of-suspend-states elogind-list-serializer) +(define elogind-serialize-list-of-suspend-modes elogind-list-serializer) +(define elogind-serialize-list-of-hibernation-modes elogind-list-serializer) + +;;; XXX: For backward-compatible/historical reasons, the configuration object +;;; is flat, containing the fields of both the logind.conf and sleep.conf +;;; files. The list below contains the fields that should be serialized to +;;; sleep.conf. +(define %elogind-configuration-sleep-fields + '( suspend-state suspend-mode suspend-estimation-seconds + hibernate-mode hibernate-delay-seconds hibernate-state + hybrid-sleep-state hybrid-sleep-mode)) + +(define-configuration elogind-configuration + (elogind + (file-like elogind) + "The elogind package to use." + (serializer empty-serializer)) + + (system-sleep-hook-files + (list-of-file-likes '()) + "A list of executables (file-like objects) that will be installed into the +@file{/etc/elogind/system-sleep} hook directory. See `Hook directories' in +the @samp{loginctl(1)} man page for more information." + (serializer empty-serializer)) + + (system-shutdown-hook-files + (list-of-file-likes '()) + "A list of executables (file-like objects) that will be installed into the +@file{/etc/elogind/system-shutdown/} hook directory." + (serializer empty-serializer)) + + (allow-power-off-interrupts? + (maybe-boolean #f) + "Whether the executables in elogind's hook directories (see above) can + cause a power-off action to be cancelled (interrupted) by printing an + appropriate error message to stdout.") + + (allow-suspend-interrupts? + (maybe-boolean #f) + "Likewise as the @code{allow-power-off-interrupts?} option, but for the + suspend action.") + + (broadcast-power-off-interrupts? + (maybe-boolean #f) + "Whether an interrupt of a power-off action is broadcasted.") + + (broadcast-suspend-interrupts? + (maybe-boolean #f) + "Whether an interrupt of a suspend action is broadcasted.") + + ;; logind.conf options. + (kill-user-processes? + (maybe-boolean #f) + "Whether the processes of a user should be killed when the user logs + out.") + + (kill-only-users + maybe-list-of-user-names + "Usernames whose processes should be killed, regardless the value of + @code{kill-user-processes?}.") + + (kill-exclude-users + (maybe-list-of-user-names (list "root")) + "Usernames whose processes should @emph{not} be killed, regardless the + value of @code{kill-user-processes?}.") + + (inhibit-delay-max-seconds + (maybe-non-negative-integer 5) + "The maximum time a system shutdown or sleep request is delayed due to an + inhibitor lock of type delay being active before the inhibitor is ignored and + the operation executes anyway.") + + (handle-power-key + (maybe-action 'poweroff) + "The action done when the power key is pressed. The compiled default is + @code{'poweroff}.") + + (handle-suspend-key + (maybe-action 'suspend) + "The action done when the suspend key is pressed. The ") + + (handle-hibernate-key + (maybe-action 'hibernate) + "The action done when the hibernate key is pressed.") + + (handle-lid-switch + (maybe-action 'suspend) + "The action done when the lid is closed.") + + (handle-lid-switch-docked + (maybe-action 'ignore) + "The action done when the lid is closed and the device docked.") + + (handle-lid-switch-external-power + (maybe-action 'suspend) + "The action done when the lid is closed and the device is externally + powered.") + + (power-key-ignore-inhibited? + (maybe-boolean #f) + "Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or + idle) when the power key is pressed.") + + (suspend-key-ignore-inhibited? + (maybe-boolean #f) + "Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or + idle) when the suspend key is pressed.") + + (hibernate-key-ignore-inhibited? + (maybe-boolean #f) + "Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or + idle) when the hibernate key is pressed.") + + (lid-switch-ignore-inhibited? + (maybe-boolean #f) + "Whether to ignore high-level inhibitor locks (shutdown, reboot, sleep or + idle) when the lid is closed.") + + (holdoff-timeout-seconds + (maybe-non-negative-integer 30) + "Specifies the number of seconds after system startup or system resume +during which elogind will hold off on reacting to lid events.") + + (idle-action + (maybe-action 'ignore) + "Action to take when the system is idle.") + + (idle-action-seconds + maybe-non-negative-integer + "The delay after which the action configured in @code{idle-action} is +taken after the system is idle.") + + ;; XXX: Perhaps deprecate in the future and handle all the accepted forms + ;; directly in 'runtime-directory-size' instead. + (runtime-directory-size-percent + maybe-percent + "Set the size limit, in percent, on the @env{XDG_RUNTIME_DIR} runtime +directory for each user who logs in. This specifies the per-user size limit +relative to the amount of physical @acronym{RAM, read access memory}. This +value takes precedence over that specified via @code{runtime-directory-size}." + (serializer empty-serializer)) ;special cased at serialization time + + (runtime-directory-size + maybe-non-negative-integer + "Set the size limit, in bytes, on the @env{XDG_RUNTIME_DIR} runtime +directory for each user who logs in." + (serializer empty-serializer)) ;special cased at serialization time + + (remove-ipc? + (maybe-boolean #t) + "Whether @acronym{IPC, inter-process communication} objects belonging to +the user shall be removed when the user fully logs out.") + + ;; sleep.conf options. + ;; CAUTION: all sleep.conf option names must be registered in the above + ;; %ELOGIND-CONFIGURATION-SLEEP-FIELDS variable: otherwise they will be + ;; serialized to logind.conf instead of sleep.conf! + (suspend-state + (maybe-list-of-suspend-states '(mem standby freeze)) + "The suspend state values to be write to @file{/sys/power/state} by elogind + when suspending the system. They will be tried in turn, until one is written + without error.") + + (suspend-mode + (maybe-list-of-suspend-modes) + "The suspend mode values to write to @file{/sys/power/mem_sleep} by elogind + when suspending the system.") + + (suspend-estimation-seconds + (maybe-non-negative-integer (* 60 60)) ;1 hour + "Cause the RTC alarm to wake the system after the specified time span to + measure the system battery capacity level and estimate the battery discharging + rate, which is used for estimating the time span until the system battery + charge level goes down to 5%. This option is only used by elogind when using + the @code{'suspend-then-hibernate} action.") + + (hibernate-mode + (maybe-list-of-hibernation-modes '(platform shutdown)) + "The hibernation mode values to write to @file{/sys/power/disk} by elogind + when hibernating the system.") + + (hibernate-delay-seconds + maybe-non-negative-integer + "The amount of time the system spends in suspend mode before the system is + automatically put into hibernate mode.") + + ;; TODO: Remove in May 2026. + (hibernate-state + maybe-list-of-strings + "Deprecated option." + (serializer elogind-deprecated-empty-serializer)) + + ;; TODO: Remove in May 2026. + (hybrid-sleep-state + maybe-list-of-strings + "Deprecated option." + (serializer elogind-deprecated-empty-serializer)) + + ;; TODO: Remove in May 2026. + (hybrid-sleep-mode + maybe-list-of-strings + "Deprecated option." + (serializer elogind-deprecated-empty-serializer)) + + (prefix elogind-)) + +(define (logind.conf config) + (let ((logind-fields (remove (lambda (field) + (memq (configuration-field-name field) + %elogind-configuration-sleep-fields)) + elogind-configuration-fields))) + (match-record config <elogind-configuration> + (runtime-directory-size-percent runtime-directory-size) + ;; Handle the special-cased + ;; runtime-directory-size-percent/runtime-directory-size options pair. + (let ((runtime-directory-size + (if (maybe-value-set? runtime-directory-size-percent) + (format #f "~a%~%" runtime-directory-size-percent) ;10 -> 10% + runtime-directory-size))) + (mixed-text-file + "logind.conf" + "[Login]\n" + (if (maybe-value-set? runtime-directory-size) + (list "RuntimeDirectorySize=" runtime-directory-size) + "") + (serialize-configuration config logind-fields)))))) + +(define (sleep.conf config) + (let ((sleep-fields (filter (lambda (field) + (memq (configuration-field-name field) + %elogind-configuration-sleep-fields)) + elogind-configuration-fields))) + (mixed-text-file + "sleep.conf" + "[Sleep]\n" + (serialize-configuration config sleep-fields)))) (define (elogind-etc-directory config) "Return the /etc/elogind directory for CONFIG." @@ -1213,12 +1410,21 @@ (define (elogind-etc-directory config) (chmod dest #o500))) (mkdir-p #$output) ;in case neither directory gets created + + ;; Symlink the main configuration files. + (with-directory-excursion #$output + (mkdir-p "logind.conf.d") + (symlink #$(logind.conf config) "logind.conf.d/logind.conf") + (mkdir-p "sleep.conf.d") + (symlink #$(sleep.conf config) "sleep.conf.d/sleep.conf")) + (for-each (lambda (f) (copy-script f sleep-directory)) - '#$(elogind-system-sleep-hook-files config)) + '#$(elogind-configuration-system-sleep-hook-files config)) (for-each (lambda (f) (copy-script f shutdown-directory)) - '#$(elogind-system-shutdown-hook-files config)))))) + '#$(elogind-configuration-system-shutdown-hook-files + config)))))) (define (elogind-dbus-service config) "Return a @file{org.freedesktop.login1.service} file that tells D-Bus how to @@ -1231,7 +1437,7 @@ (define (elogind-dbus-service config) ;; <https://issues.guix.gnu.org/55444>. (define elogind - (elogind-package config)) + (elogind-configuration-elogind config)) (define wrapper (program-file "elogind-dbus-shepherd-sync" @@ -1288,7 +1494,7 @@ (define (pam-extension-procedure config) (define pam-elogind (pam-entry (control "required") - (module (file-append (elogind-package config) + (module (file-append (elogind-configuration-elogind config) "/lib/security/pam_elogind.so")))) (list (pam-extension @@ -1301,56 +1507,52 @@ (define (pam-extension-procedure config) (define (elogind-shepherd-service config) "Return a Shepherd service to start elogind according to @var{config}." - (define config-file - (elogind-configuration-file config)) - (list (shepherd-service (requirement '(user-processes dbus-system)) (provision '(elogind)) (start #~(make-forkexec-constructor - (list #$(file-append (elogind-package config) - "/libexec/elogind/elogind")) - #:environment-variables - (list (string-append "ELOGIND_CONF_FILE=" - #$config-file)))) + (list #$(file-append (elogind-configuration-elogind config) + "/libexec/elogind/elogind")))) (stop #~(make-kill-destructor)) - (actions (list (shepherd-configuration-action config-file)))))) + (actions (list (shepherd-configuration-action + "/etc/elogind/logind.conf")))))) (define elogind-service-type - (service-type (name 'elogind) - (extensions - (list (service-extension dbus-root-service-type - elogind-dbus-service) - (service-extension udev-service-type - (compose list elogind-package)) - (service-extension polkit-service-type - (compose list elogind-package)) - - ;; Start elogind from the Shepherd rather than waiting - ;; for bus activation. This ensures that it can handle - ;; events like lid close, etc. - (service-extension shepherd-root-service-type - elogind-shepherd-service) - - ;; Provide the 'loginctl' command. - (service-extension profile-service-type - (compose list elogind-package)) - - ;; Extend PAM with pam_elogind.so. - (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)))) - (default-value (elogind-configuration)) - (description "Run the @command{elogind} login and seat + (service-type + (name 'elogind) + (extensions + (list (service-extension dbus-root-service-type + elogind-dbus-service) + (service-extension udev-service-type + (compose list elogind-configuration-elogind)) + (service-extension polkit-service-type + (compose list elogind-configuration-elogind)) + + ;; Start elogind from the Shepherd rather than waiting + ;; for bus activation. This ensures that it can handle + ;; events like lid close, etc. + (service-extension shepherd-root-service-type + elogind-shepherd-service) + + ;; Provide the 'loginctl' command. + (service-extension profile-service-type + (compose list elogind-configuration-elogind)) + + ;; Extend PAM with pam_elogind.so. + (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)))) + (default-value (elogind-configuration)) + (description "Run the @command{elogind} login and seat management service. The @command{elogind} service integrates with PAM to allow other system components to know the set of logged-in users as well as their session types (graphical, console, remote, etc.). It can also clean up base-commit: 4fe4cf9fdd959126d3c53c3df4504d851e7b736a -- 2.49.0
bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Fri, 25 Apr 2025 14:56:02 GMT) Full text and rfc822 format available.Message #31 received at 77806 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> Cc: Josselin Poiret <dev <at> jpoiret.xyz>, Vivien Kraus <vivien <at> planete-kraus.eu>, Noé Lopez <noelopez <at> free.fr>, Liliana Marie Prikler <liliana.prikler <at> gmail.com>, Bas Alberts <bas <at> anti.computer>, 77806 <at> debbugs.gnu.org Subject: Re: bug#77806: [PATCH v3] services: elogind: Split sleep.conf and port to define-configuration. Date: Fri, 25 Apr 2025 16:54:46 +0200
Hi, Maxim Cournoyer <maxim.cournoyer <at> gmail.com> writes: > Fixes: bug#77806 I would provide the complete URL, as is usually done, to avoid ambiguity. > + (actions (list (shepherd-configuration-action > + "/etc/elogind/logind.conf")))))) Would it be possible to give the config file name in the store instead? That way, we would know which one is actually in effect (when one reconfigures, /etc/logind/logind.conf is changed through activation but elogind keeps honoring the previous version of it, which is why distinguishing between both can be helpful IMO.) I let Josselin comment on the rest. Thanks for the fix! Ludo’.
Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
:Ludovic Courtès <ludo <at> gnu.org>
:Message #36 received at 77806-done <at> debbugs.gnu.org (full text, mbox):
From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> To: Ludovic Courtès <ludo <at> gnu.org> Cc: Josselin Poiret <dev <at> jpoiret.xyz>, Vivien Kraus <vivien <at> planete-kraus.eu>, Noé Lopez <noelopez <at> free.fr>, Liliana Marie Prikler <liliana.prikler <at> gmail.com>, Bas Alberts <bas <at> anti.computer>, 77806-done <at> debbugs.gnu.org Subject: Re: bug#77806: elogind behavior changed: power key turns computer off Date: Sat, 26 Apr 2025 23:03:09 +0900
Hi, Ludovic Courtès <ludo <at> gnu.org> writes: > Hi, > > Maxim Cournoyer <maxim.cournoyer <at> gmail.com> writes: > >> Fixes: bug#77806 > > I would provide the complete URL, as is usually done, to avoid > ambiguity. Okay, done. >> + (actions (list (shepherd-configuration-action >> + "/etc/elogind/logind.conf")))))) > > Would it be possible to give the config file name in the store instead? > That way, we would know which one is actually in effect (when one > reconfigures, /etc/logind/logind.conf is changed through activation but > elogind keeps honoring the previous version of it, which is why > distinguishing between both can be helpful IMO.) I did what you had suggested earlier with a custom 'shepherd-configuration-action' job that accepts multiple files: --8<---------------cut here---------------start------------->8--- 1 file changed, 13 insertions(+), 2 deletions(-) gnu/services/desktop.scm | 15 +++++++++++++-- modified gnu/services/desktop.scm @@ -1505,6 +1505,16 @@ (define (pam-extension-procedure config) (session (cons pam-elogind (pam-service-session pam)))))) (shepherd-requirements '(elogind))))) +(define* (shepherd-configuration-action* files) + "Return a 'configuration' action to display FILES, which should be the names +of the service's configuration files." + (shepherd-action + (name 'configuration) + (documentation "Display the names of this service's configuration files.") + (procedure #~(lambda (_) + (format #t "~{~a~%~}" '#$files) + '#$files)))) + (define (elogind-shepherd-service config) "Return a Shepherd service to start elogind according to @var{config}." (list (shepherd-service @@ -1514,8 +1524,9 @@ (define (elogind-shepherd-service config) (list #$(file-append (elogind-configuration-elogind config) "/libexec/elogind/elogind")))) (stop #~(make-kill-destructor)) - (actions (list (shepherd-configuration-action - "/etc/elogind/logind.conf")))))) + (actions (list (shepherd-configuration-action* + (list (logind.conf config) + (sleep.conf config)))))))) (define elogind-service-type (service-type --8<---------------cut here---------------end--------------->8--- And it seems to work correctly on my machine: --8<---------------cut here---------------start------------->8--- $ sudo herd configuration elogind /gnu/store/z2hdrmyxjd0x7msf66638ppl9hx99fh3-logind.conf /gnu/store/hqbmn9idlydkkm554k1zrhi306ffsldl-sleep.conf maxim <at> terra ~$ cat /gnu/store/hqbmn9idlydkkm554k1zrhi306ffsldl-sleep.conf [Sleep] SuspendState=mem standby freeze SuspendEstimationSec=3600 HibernateMode=platform shutdown maxim <at> terra ~$ find /etc/elogind/ /etc/elogind/ /etc/elogind/logind.conf.d /etc/elogind/logind.conf.d/logind.conf /etc/elogind/sleep.conf.d /etc/elogind/sleep.conf.d/sleep.conf maxim <at> terra ~$ readlink /etc/elogind/logind.conf.d/logind.conf /gnu/store/z2hdrmyxjd0x7msf66638ppl9hx99fh3-logind.conf maxim <at> terra ~$ readlink /etc/elogind/sleep.conf.d/sleep.conf /gnu/store/hqbmn9idlydkkm554k1zrhi306ffsldl-sleep.conf --8<---------------cut here---------------end--------------->8--- Josselin pointed to some problem, which I've now fix (had to use "drop-ins" files instead of the canonical config file names, which are looked from the package's sysconfdir in the store instead of under /etc/elogind). If we find other we can fix them later, but it seems to me it can't be much worst than it is now, so I've now pushed this to master, with commit f10d00e4e25. Thanks to everyone who helped figure that one out! -- Thanks, Maxim
bug-guix <at> gnu.org
:bug#77806
; Package guix
.
(Sat, 03 May 2025 16:34:02 GMT) Full text and rfc822 format available.Message #39 received at 77806-done <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> Cc: Josselin Poiret <dev <at> jpoiret.xyz>, Vivien Kraus <vivien <at> planete-kraus.eu>, Noé Lopez <noelopez <at> free.fr>, Liliana Marie Prikler <liliana.prikler <at> gmail.com>, Bas Alberts <bas <at> anti.computer>, 77806-done <at> debbugs.gnu.org Subject: Re: bug#77806: elogind behavior changed: power key turns computer off Date: Sat, 03 May 2025 18:30:12 +0200
Hi, Maxim Cournoyer <maxim.cournoyer <at> gmail.com> writes: > Josselin pointed to some problem, which I've now fix (had to use > "drop-ins" files instead of the canonical config file names, which are > looked from the package's sysconfdir in the store instead of under > /etc/elogind). If we find other we can fix them later, but it seems to > me it can't be much worst than it is now, so I've now pushed this to > master, with commit f10d00e4e25. > > Thanks to everyone who helped figure that one out! Thanks to both of you for the quick fix! Ludo’.
Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org
.
(Sun, 01 Jun 2025 11:24:15 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.