Systemd on initrd: replacement for preDeviceCommands?

I have a preDeviceCommands that prints a message, and powersoff after some time. Since I have LUKS and power-on-ac, this powers off the laptop automatically if no password is input:

  boot.initrd.preDeviceCommands = ''
    echo -e "Something something" \
      | ${pkgs.neo-cowsay}/bin/cowsay --bold --aurora \
      && (sleep 60 && echo "Bye bye..." && poweroff -f &)
  '';

Is there any way to achieve the same behaviour (including the message with cowsay), when using systemd on initr (boot.initrd.systemd.enable = true;)?

You could configure the cryptsetup service to poweroff the system if it fails and add a timeout to the LUKS device. Not sure about getting the cowsay part though… Maybe a preStart and set the StandardOutput to the console?

boot.initrd = {
  luks.devices.foo.crypttabExtraOpts = [ "timeout=60s" ];
  systemd.services."systemd-cryptsetup@" = {
    overrideStrategy = "asDropin";
    unitConfig.FailureAction = "poweroff";
    serviceConfig.StandardOutput = "journal+console";
    preStart = ''
      echo "Something something" | ${pkgs.neo-cowsay}/bin/cowsay --bold --aurora
    '';
  };
  systemd.storePaths = [ "${pkgs.neo-cowsay}/bin/cowsay" ];
};

The slightly more straightforward thing would be a custom service that just does your script (and would be killed by initrd-cleanup.service). But I like doing it with the cryptsetup service’s failure because it’s more representative of what’s actually going on. Only problem is e.g. if cryptsetup actually fails for a non-timeout reason, then the system will just poweroff instead of letting you debug. With a custom service, you could have conflicts = [ "emergency.target" ]; to avoid this.

Thanks! That helped a lot. I done a few small changes and its working great:

  boot.initrd = {
    systemd.enable = true;
    systemd.services."systemd-cryptsetup@" = {
      overrideStrategy = "asDropin";
      serviceConfig = {
        StandardOutput = "journal+console";
        TimeoutSec = 90;
      };
      unitConfig = {
        FailureAction = "poweroff-force";
      };
      preStart = ''echo -e "\nSomething Something\n" \
        | ${pkgs.neo-cowsay}/bin/cowsay --bold --aurora
      '';
    };
    systemd.storePaths = [ "${pkgs.neo-cowsay}/bin/cowsay" ];
  };

I’ve set the unit timeout instead of using LUKS timeout, because the later would require the device id.