{ config, lib, namespace, ... }: with lib; let inherit (lib.${namespace}) mkBoolOpt; cfg = config.${namespace}.headless; in { options.${namespace}.headless = { enable = mkBoolOpt true "Enable headless stuff"; }; config = mkIf cfg.enable { assertions = [ { assertion = !config.${namespace}.desktop.gnome.enable && !config.${namespace}.desktop.hyprland.enable && !config.${namespace}.desktop.cosmic.enable; message = "mjallen.headless.enable = true is incompatible with having a desktop environment enabled (gnome, hyprland, or cosmic)."; } ]; boot.initrd.systemd.suppressedUnits = lib.mkIf config.systemd.enableEmergencyMode [ "emergency.service" "emergency.target" ]; systemd = { # Given that our systems are headless, emergency mode is useless. # We prefer the system to attempt to continue booting so # that we can hopefully still access it remotely. enableEmergencyMode = false; sleep.settings.Sleep = { AllowSuspend = "no"; AllowHibernation = "no"; }; # For more detail, see: # https://0pointer.de/blog/projects/watchdog.html settings.Manager = { # systemd will send a signal to the hardware watchdog at half # the interval defined here, so every 7.5s. # If the hardware watchdog does not get a signal for 15s, # it will forcefully reboot the system. RuntimeWatchdogSec = lib.mkDefault "15s"; # Forcefully reboot if the final stage of the reboot # hangs without progress for more than 30s. # For more info, see: # https://utcc.utoronto.ca/~cks/space/blog/linux/SystemdShutdownWatchdog RebootWatchdogSec = lib.mkDefault "30s"; # Forcefully reboot when a host hangs after kexec. # This may be the case when the firmware does not support kexec. KExecWatchdogSec = lib.mkDefault "1m"; }; }; }; }