Display-manager greetd unintentionally restarts on every nixos-rebuild

I created my own NixOS module for the display manager greetd with the greeter tuigreet. I also overlayed nixpkgs with derivations for both programs. NixOS rebuilds keep restarting the service I create in that module (even without any configuration changes) and because my WM/DE is a child process of greetd, this crashes my whole desktop environment on every rebuild, which is really nerve-racking.

The module creates a new service greetd.service, which has an alias display-manager.service. Unfortunately, I do not know why display-manager.service is automagically started with graphical.target, maybe that’s the issue. restartIfChanged is set to false for greetd.service.

I’ve intentionally not used services.xserver.displayManager stuff because I use wayland exclusively and do not want to enable xorg or anything related (I vote for display managers being seperated from xserver because they are independent, as this console greeter tuigreet demonstrates). However, I oriented on xserver.nix and lightdm.nix for my greetd module. The module looks like this:

{ config, lib, pkgs, ... } :
with lib;
let
  gcfg = config.services.greetd;

  configText = ''
  [terminal]
  vt = 1

  [default_session]
  ${optionalString gcfg.tuigreet.enable
    ''
      command="${pkgs.tuigreet}/bin/tuigreet --cmd ${gcfg.tuigreet.cmd} ${optionalString gcfg.tuigreet.showTime "-t"} ${optionalString gcfg.tuigreet.showIssue "-i"} ${optionalString (gcfg.tuigreet.customGreeting != "") ''-g \"${gcfg.tuigreet.customGreeting}\"''} ${optionalString gcfg.tuigreet.showAsterisks "--asterisks"}"
    ''}
  user = "greeter"
  '';

in

{
  options = {
    services.greetd = {
      enable = mkOption {
        type = types.bool;
        default = false;
        description = "Wether to enable greetd as the display manager";
      };
      tuigreet = {
        enable = mkOption {
          type = types.bool;
          default = false;
          description = "Wether to use tuigreet as greetd greeter";
        };
        cmd = mkOption {
          type = types.str;
          description = "Command to execute on login";
        };
        showIssue = mkOption {
          type = types.bool;
          default = false;
          description = "Wether to show the issue in tuigreet";
        };
        showAsterisks = mkOption {
          type = types.bool;
          default = false;
          description = "Wether to show asterisks in the password field";
        };
        showTime = mkOption {
          type = types.bool;
          default = false;
          description = "Wether to show the current time in tuigreet";
        };
        customGreeting = mkOption {
          type = types.str;
          default = "";
          description = "Custom greeting string";
        };
      };
    };
  };

  config = mkIf gcfg.enable {
  assertions = [
    { assertion = !((gcfg.tuigreet.customGreeting != "") && gcfg.tuigreet.showIssue);
      message = "tuigreet cannot show a customGreeting and issue at the same time!";
    }
  ];


  # create config file in /etc
  environment = {
    etc."greetd/config.toml".text = configText;
    etc."greetd/config.toml".user = "greeter";
    etc."greetd/config.toml".group = "greeter";
  };

  # unit display-manager is started during graphical.target
  systemd.defaultUnit = "graphical.target";

  # create systemd service
  systemd.services.greetd = {
    description = ''
      Greeter daemon
    '';
    # after = [ "systemd-user-sessions.service" "plymouth-quit-wait.service" "getty@tty1.service" "user.slice" ];
    after = [ "rc-local.service" "networking.service" "systemd-machined.service" "systemd-user-sessions.service" "getty@tty1.service" "systemd-logind.service" "acpid.service" ];
    conflicts = [ "getty@tty1.service" ];
    restartIfChanged = false;
    serviceConfig = {
      Type = "simple";
      ExecStart = "${pkgs.greetd}/bin/greetd";
      IgnoreSIGPIPE = "no";
      SendSIGHUP = "yes";
      TimeoutStopSec = "30s";
      KeyringMode = "shared";
      Restart = "always";
      RestartSec = "1";
      StartLimitBurst = "5";
      StartLimitInterval = "30";
    };
    aliases = [ "display-manager.service" ];
    enable = true;
  };

  systemd.services.greetd.environment.XDG_DATA_DIRS= "${config.services.xserver.displayManager.sessionData.desktops}/share/";


  # create greetd user
  users.users.greeter = {
    isNormalUser = false;
    description = "greetd user";
    group = "greeter";
    extraGroups = [ "video" ];
  };
  # create greeter group
  users.groups.greeter.name = "greeter";
  };
}
1 Like