nixos/users-groups: move linger to oneshot and add nixos test

This commit is contained in:
Adam Stephens 2024-03-21 19:51:05 -04:00
parent 564c3749d9
commit 790fb86a7f
No known key found for this signature in database
3 changed files with 60 additions and 13 deletions

View File

@ -496,6 +496,7 @@ let
in in
filter types.shellPackage.check shells; filter types.shellPackage.check shells;
lingeringUsers = map (u: u.name) (attrValues (flip filterAttrs cfg.users (n: u: u.linger)));
in { in {
imports = [ imports = [
(mkAliasOptionModuleMD [ "users" "extraUsers" ] [ "users" "users" ]) (mkAliasOptionModuleMD [ "users" "extraUsers" ] [ "users" "users" ])
@ -695,25 +696,31 @@ in {
''; '';
} else ""; # keep around for backwards compatibility } else ""; # keep around for backwards compatibility
system.activationScripts.update-lingering = let systemd.services.linger-users = lib.mkIf ((builtins.length lingeringUsers) > 0) {
lingerDir = "/var/lib/systemd/linger"; wantedBy = ["multi-user.target"];
lingeringUsers = map (u: u.name) (attrValues (flip filterAttrs cfg.users (n: u: u.linger))); after = ["systemd-logind.service"];
lingeringUsersFile = builtins.toFile "lingering-users" requires = ["systemd-logind.service"];
(concatStrings (map (s: "${s}\n")
(sort (a: b: a < b) lingeringUsers))); # this sorting is important for `comm` to work correctly script = let
in stringAfter [ "users" ] '' lingerDir = "/var/lib/systemd/linger";
if [ -e ${lingerDir} ] ; then lingeringUsersFile = builtins.toFile "lingering-users"
(concatStrings (map (s: "${s}\n")
(sort (a: b: a < b) lingeringUsers))); # this sorting is important for `comm` to work correctly
in ''
mkdir -vp ${lingerDir}
cd ${lingerDir} cd ${lingerDir}
for user in $(ls); do for user in $(ls); do
if ! id "$user" >/dev/null; then if ! id "$user" >/dev/null; then
echo "Removing linger for deleted user $user" echo "Removing linger for missing user $user"
rm --force -- "$user" rm --force -- "$user"
fi fi
done done
ls ${lingerDir} | sort | comm -3 -1 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl disable-linger ls | sort | comm -3 -1 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl disable-linger
ls ${lingerDir} | sort | comm -3 -2 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl enable-linger ls | sort | comm -3 -2 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl enable-linger
fi '';
'';
serviceConfig.Type = "oneshot";
};
# Warn about user accounts with deprecated password hashing schemes # Warn about user accounts with deprecated password hashing schemes
# This does not work when the users and groups are created by # This does not work when the users and groups are created by

View File

@ -899,6 +899,7 @@ in {
systemd-sysusers-immutable = runTest ./systemd-sysusers-immutable.nix; systemd-sysusers-immutable = runTest ./systemd-sysusers-immutable.nix;
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {}; systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
systemd-timesyncd-nscd-dnssec = handleTest ./systemd-timesyncd-nscd-dnssec.nix {}; systemd-timesyncd-nscd-dnssec = handleTest ./systemd-timesyncd-nscd-dnssec.nix {};
systemd-user-linger = handleTest ./systemd-user-linger.nix {};
systemd-user-tmpfiles-rules = handleTest ./systemd-user-tmpfiles-rules.nix {}; systemd-user-tmpfiles-rules = handleTest ./systemd-user-tmpfiles-rules.nix {};
systemd-misc = handleTest ./systemd-misc.nix {}; systemd-misc = handleTest ./systemd-misc.nix {};
systemd-userdbd = handleTest ./systemd-userdbd.nix {}; systemd-userdbd = handleTest ./systemd-userdbd.nix {};

View File

@ -0,0 +1,39 @@
import ./make-test-python.nix (
{ lib, ... }:
{
name = "systemd-user-linger";
nodes.machine =
{ ... }:
{
users.users = {
alice = {
isNormalUser = true;
linger = true;
uid = 1000;
};
bob = {
isNormalUser = true;
linger = false;
uid = 10001;
};
};
};
testScript =
{ ... }:
''
machine.wait_for_file("/var/lib/systemd/linger/alice")
machine.succeed("systemctl status user-1000.slice")
machine.fail("test -e /var/lib/systemd/linger/bob")
machine.fail("systemctl status user-1001.slice")
with subtest("missing users have linger purged"):
machine.succeed("touch /var/lib/systemd/linger/missing")
machine.systemctl("restart linger-users")
machine.succeed("test ! -e /var/lib/systemd/linger/missing")
'';
}
)