[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Trying to add elogind sleep/shutdown hook support
From: |
45mg.writes |
Subject: |
Trying to add elogind sleep/shutdown hook support |
Date: |
Wed, 11 Dec 2024 15:31:54 -0500 |
Hi Guix,
So I've been trying to patch `elogind-service-type` in order to add
support for the `system-sleep` and `system-shutdown` hook directories
[1]. This would give users a way to run scripts before/after
suspend/hibernate, a feature that is currently missing in Guix [2]. I've
run into a strange unbound-variable error that I'm not able to
troubleshoot further, and I would really appreciate any guidance.
The requirements are simple - put script files in
/etc/elogind/system-sleep/ or /etc/elogind/system-shutdown/ directories,
and they will be run pre/post suspend/hibernate/poweroff/whatever, with
arguments indicating what is happening.
I'm trying to do this by adding corresponding fields to
`elogind-configuration`
each taking a list of local (script) files, and then having
`elogind-service` extend `activation-service-type`. `elogind-activation`
then takes care of installing the files into the hook directories.
Here's a patch showing what I have so far:
diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm
index 274aeeef9b..1237d53b6f 100644
--- a/gnu/services/desktop.scm
+++ b/gnu/services/desktop.scm
@@ -1084,7 +1084,10 @@ (define-record-type* <elogind-configuration>
elogind-configuration
(hibernate-delay-seconds elogind-hibernate-delay-seconds
(default *unspecified*))
(suspend-estimation-seconds elogind-suspend-estimation-seconds
- (default *unspecified*)))
+ (default *unspecified*))
+ (system-sleep-hook-files elogind-system-sleep-hook-files (default '()))
+ (system-shutdown-hook-files elogind-system-shutdown-hook-files (default
'())))
+; TODO AllowPowerOffInterrupts, AllowSuspendInterrupts,
BroadcastPowerOffInterrupts, BroadcastSuspendInterrupts
(define (elogind-configuration-file config)
(define (yesno x)
@@ -1174,6 +1177,19 @@ (define (elogind-configuration-file config)
("HibernateDelaySec" (maybe-non-negative-integer
elogind-hibernate-delay-seconds))
("SuspendEstimationSec" (maybe-non-negative-integer
elogind-suspend-estimation-seconds))))
+(define (elogind-activation config)
+ "Return the activation GEXP for CONFIG."
+ (with-imported-modules (source-module-closure '((guix build utils) (srfi
srfi-26)))
+ #~(let ((sleep-dir "/etc/elogind/system-sleep")
+ (shutdown-dir "/etc/elogind/system-shutdown"))
+ (use-modules (guix build utils) (srfi srfi-26))
+ (for-each
+ (cut install-file <> sleep-dir)
+ '#$(elogind-system-sleep-hook-files config))
+ (for-each
+ (cut install-file <> shutdown-dir)
+ '#$(elogind-system-shutdown-hook-files config)))))
+
(define (elogind-dbus-service config)
"Return a @file{org.freedesktop.login1.service} file that tells D-Bus
how to
\"start\" elogind. In practice though, our elogind is started when
booting by
@@ -1294,6 +1310,10 @@ (define elogind-service-type
(service-extension pam-root-service-type
pam-extension-procedure)
+ ;; Install sleep/shutdown hook files.
+ (service-extension activation-service-type
+ elogind-activation)
+
;; We need /run/user, /run/systemd, etc.
(service-extension file-system-service-type
(const %elogind-file-systems))))
And here is a test configuration file I'm running it with (a
stripped-down version of my own system config):
(use-modules (gnu))
(use-service-modules cups desktop networking ssh xorg)
(operating-system
(locale "en_US.utf8")
(timezone "America/New_York")
(keyboard-layout (keyboard-layout "us"))
(host-name "guixy")
;; The list of user accounts ('root' is implicit).
(users (cons* (user-account
(name "me")
(comment "Me")
(group "users")
(home-directory "/home/me")
(supplementary-groups '("wheel" "netdev" "audio"
"video")))
%base-user-accounts))
(packages %base-packages)
(services
(append
(list
(service elogind-service-type
(elogind-configuration
(system-sleep-hook-files (list (local-file
"./test-sleep-script"))))
))
%base-services))
(bootloader (bootloader-configuration
(bootloader grub-bootloader)
(targets (list "/dev/sda"))
(keyboard-layout keyboard-layout)))
(swap-devices (list (swap-space
(target (uuid
"f04306ed-0fcb-44ab-b3fd-1921e03f8654")))))
(file-systems (cons* (file-system
(mount-point "/")
(device (uuid
"ddcfb0e2-7e45-4c44-86ce-ac81dd3e53ab"
'btrfs))
(type "btrfs")) %base-file-systems)))
`test-sleep-script` is an executable in the same directory just
containing
#!/bin/sh
echo "$@" >> /home/me/elogind-test-log
I'm testing this by running the following in my Guix checkout (after
`guix shell -D guix --pure -- ./bootstrap`, and similarly for
`./configure --localstatedir=/var` and `make`):
sudo $(./pre-inst-env guix system container path/to/test-config.scm)
This is the output I see:
system container is running as PID 12670
WARNING: (guile-user): imported module (guix build utils) overrides core
binding `delete'
Run 'sudo guix container exec 12670 /run/current-system/profile/bin/bash
--login'
or run 'sudo nsenter -a -t 12670' to get a shell into it.
WARNING: (guile-user): imported module (guix build utils) overrides core
binding `delete'
making '/gnu/store/2jwl0mc296r71yf03q9ic75zmc39y3ni-system' the current
system...
populating /etc from /gnu/store/y89n82vyqlzcsn08bj34rgjjixkkfhla-etc...
WARNING: (guile-user): imported module (guix build utils) overrides core
binding `delete'
WARNING: (guile-user): imported module (guix build utils) overrides core
binding `delete'
setting up privileged programs in '/run/privileged/bin'...
WARNING: (guile-user): imported module (guix build utils) overrides core
binding `delete'
Please wait while gathering entropy to generate the key pair;
this may take time...
WARNING: (guile-user): imported module (guix build utils) overrides core
binding `delete'
Backtrace:
13 (primitive-load "/gnu/store/9v4y45fcazxp8czkabawfqyc2bx…")
In gnu/build/linux-container.scm:
300:8 12 (call-with-temporary-directory #<procedure 7f46a4c38d20…>)
397:16 11 (_ "/tmp/guix-directory.RDCnGc")
62:6 10 (call-with-clean-exit #<procedure 7f46a4c43100 at gnu/b…>)
In unknown file:
9 (primitive-load "/gnu/store/2jwl0mc296r71yf03q9ic75zmc3…")
In ice-9/eval.scm:
619:8 8 (_ #f)
In unknown file:
7 (primitive-load "/gnu/store/yz4fklxd6qpcsv4x54m6a1dk4ck…")
In srfi/srfi-1.scm:
634:9 6 (for-each #<procedure primitive-load (_)> _)
In unknown file:
5 (primitive-load "/gnu/store/z8yvff5ni8w91ms4glmwhyczpsk…")
In ice-9/eval.scm:
619:8 4 (_ #(#<directory (guile-user) 7f46a7f16c80> "/etc/el…" …))
159:9 3 (_ #(#<directory (guile-user) 7f46a7f16c80> "/etc/el…" …))
163:9 2 (_ #(#<directory (guile-user) 7f46a7f16c80> "/etc/el…" …))
223:20 1 (proc #(#<directory (guile-user) 7f46a7f16c80> "/etc…" …))
In unknown file:
0 (%resolve-variable (7 . <>) #<directory (guile-user) 7f…>)
ERROR: In procedure %resolve-variable:
Unbound variable: <>
Any ideas on where to go from here would be most appreciated.
[1]
https://manpages.debian.org/unstable/elogind/loginctl.1.en.html#Hook_directories
[2]
https://www.reddit.com/r/GUIX/comments/s3ab3f/running_scripts_commands_on_suspend_resume/?rdt=46057
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Trying to add elogind sleep/shutdown hook support,
45mg.writes <=