Unverified Commit d729632b authored by Adam C. Stephens's avatar Adam C. Stephens Committed by GitHub
Browse files

Merge pull request #297782 from adamcstephens/fix-linger

nixos/users-groups: fix broken linger
parents 85b4838d 790fb86a
Loading
Loading
Loading
Loading
+22 −14
Original line number Diff line number Diff line
@@ -496,6 +496,7 @@ let
    in
      filter types.shellPackage.check shells;

  lingeringUsers = map (u: u.name) (attrValues (flip filterAttrs cfg.users (n: u: u.linger)));
in {
  imports = [
    (mkAliasOptionModuleMD [ "users" "extraUsers" ] [ "users" "users" ])
@@ -695,25 +696,32 @@ in {
      '';
    } else ""; # keep around for backwards compatibility

    system.activationScripts.update-lingering = let
    systemd.services.linger-users = lib.mkIf ((builtins.length lingeringUsers) > 0) {
      wantedBy = ["multi-user.target"];
      after = ["systemd-logind.service"];
      requires = ["systemd-logind.service"];

      script = let
        lingerDir = "/var/lib/systemd/linger";
      lingeringUsers = map (u: u.name) (attrValues (flip filterAttrs cfg.users (n: u: u.linger)));
        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 stringAfter [ "users" ] ''
      if [ -e ${lingerDir} ] ; then
      in ''
        mkdir -vp ${lingerDir}
        cd ${lingerDir}
        for user in ${lingerDir}/*; do
          if ! id "$user" >/dev/null 2>&1; then
        for user in $(ls); do
          if ! id "$user" >/dev/null; then
            echo "Removing linger for missing user $user"
            rm --force -- "$user"
          fi
        done
        ls ${lingerDir} | 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
      fi
        ls | sort | comm -3 -1 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl disable-linger
        ls | sort | comm -3 -2 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl  enable-linger
      '';

      serviceConfig.Type = "oneshot";
    };

    # Warn about user accounts with deprecated password hashing schemes
    # This does not work when the users and groups are created by
    # systemd-sysusers because the users are created too late then.
+1 −0
Original line number Diff line number Diff line
@@ -902,6 +902,7 @@ in {
  systemd-sysusers-immutable = runTest ./systemd-sysusers-immutable.nix;
  systemd-timesyncd = handleTest ./systemd-timesyncd.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-misc = handleTest ./systemd-misc.nix {};
  systemd-userdbd = handleTest ./systemd-userdbd.nix {};
+39 −0
Original line number Diff line number Diff line
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")
      '';
  }
)