Files
nixpkgs/nixos/modules/services/misc/autosuspend.nix
Dark Steveneq 646b892680
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s
push sheeet
2025-10-09 14:15:47 +02:00

254 lines
7.6 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
config,
pkgs,
lib,
...
}:
let
inherit (lib)
mapAttrs'
nameValuePair
filterAttrs
types
mkEnableOption
mkPackageOption
mkOption
literalExpression
mkIf
flatten
maintainers
attrValues
;
cfg = config.services.autosuspend;
settingsFormat = pkgs.formats.ini { };
checks = mapAttrs' (n: v: nameValuePair "check.${n}" (filterAttrs (_: v: v != null) v)) cfg.checks;
wakeups = mapAttrs' (
n: v: nameValuePair "wakeup.${n}" (filterAttrs (_: v: v != null) v)
) cfg.wakeups;
# Whether the given check is enabled
hasCheck =
class:
(filterAttrs (n: v: v.enabled && (if v.class == null then n else v.class) == class) cfg.checks)
!= { };
# Dependencies needed by specific checks
dependenciesForChecks = {
"Smb" = pkgs.samba;
"XIdleTime" = [
pkgs.xprintidle
pkgs.sudo
];
};
autosuspend-conf = settingsFormat.generate "autosuspend.conf" (
{ general = cfg.settings; } // checks // wakeups
);
autosuspend = cfg.package;
checkType = types.submodule {
freeformType = settingsFormat.type.nestedTypes.elemType;
options.enabled = mkEnableOption "this activity check" // {
default = true;
};
options.class = mkOption {
default = null;
type =
with types;
nullOr (enum [
"ActiveCalendarEvent"
"ActiveConnection"
"ExternalCommand"
"JsonPath"
"Kodi"
"KodiIdleTime"
"LastLogActivity"
"Load"
"LogindSessionsIdle"
"Mpd"
"NetworkBandwidth"
"Ping"
"Processes"
"Smb"
"Users"
"XIdleTime"
"XPath"
]);
description = ''
Name of the class implementing the check. If this option is not specified, the check's
name must represent a valid internal check class.
'';
};
};
wakeupType = types.submodule {
freeformType = settingsFormat.type.nestedTypes.elemType;
options.enabled = mkEnableOption "this wake-up check" // {
default = true;
};
options.class = mkOption {
default = null;
type =
with types;
nullOr (enum [
"Calendar"
"Command"
"File"
"Periodic"
"SystemdTimer"
"XPath"
"XPathDelta"
]);
description = ''
Name of the class implementing the check. If this option is not specified, the check's
name must represent a valid internal check class.
'';
};
};
in
{
options = {
services.autosuspend = {
enable = mkEnableOption "the autosuspend daemon";
package = mkPackageOption pkgs "autosuspend" { };
settings = mkOption {
type = types.submodule {
freeformType = settingsFormat.type.nestedTypes.elemType;
options = {
# Provide reasonable defaults for these two (required) options
suspend_cmd = mkOption {
default = "systemctl suspend";
type = with types; str;
description = ''
The command to execute in case the host shall be suspended. This line can contain
additional command line arguments to the command to execute.
'';
};
wakeup_cmd = mkOption {
default = ''sh -c 'echo 0 > /sys/class/rtc/rtc0/wakealarm && echo {timestamp:.0f} > /sys/class/rtc/rtc0/wakealarm' '';
type = with types; str;
description = ''
The command to execute for scheduling a wake up of the system. The given string is
processed using Pythons `str.format()` and a format argument called `timestamp`
encodes the UTC timestamp of the planned wake up time (float). Additionally `iso`
can be used to acquire the timestamp in ISO 8601 format.
'';
};
};
};
default = { };
example = literalExpression ''
{
enable = true;
interval = 30;
idle_time = 120;
}
'';
description = ''
Configuration for autosuspend, see
<https://autosuspend.readthedocs.io/en/latest/configuration_file.html#general-configuration>
for supported values.
'';
};
checks = mkOption {
default = { };
type = with types; attrsOf checkType;
description = ''
Checks for activity. For more information, see:
- <https://autosuspend.readthedocs.io/en/latest/configuration_file.html#activity-check-configuration>
- <https://autosuspend.readthedocs.io/en/latest/available_checks.html>
'';
example = literalExpression ''
{
# Basic activity check configuration.
# The check class name is derived from the section header (Ping in this case).
# Remember to enable desired checks. They are disabled by default.
Ping = {
hosts = "192.168.0.7";
};
# This check is disabled.
Smb.enabled = false;
# Example for a custom check name.
# This will use the Users check with the custom name RemoteUsers.
# Custom names are necessary in case a check class is used multiple times.
# Custom names can also be used for clarification.
RemoteUsers = {
class = "Users";
name = ".*";
terminal = ".*";
host = "[0-9].*";
};
# Here the Users activity check is used again with different settings and a different name
LocalUsers = {
class = "Users";
name = ".*";
terminal = ".*";
host = "localhost";
};
}
'';
};
wakeups = mkOption {
default = { };
type = with types; attrsOf wakeupType;
description = ''
Checks for wake up. For more information, see:
- <https://autosuspend.readthedocs.io/en/latest/configuration_file.html#wake-up-check-configuration>
- <https://autosuspend.readthedocs.io/en/latest/available_wakeups.html>
'';
example = literalExpression ''
{
# Wake up checks reuse the same configuration mechanism as activity checks.
Calendar = {
url = "http://example.org/test.ics";
};
}
'';
};
};
};
config = mkIf cfg.enable {
systemd.services.autosuspend = {
description = "A daemon to suspend your server in case of inactivity";
documentation = [ "https://autosuspend.readthedocs.io/en/latest/systemd_integration.html" ];
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
path = flatten (attrValues (filterAttrs (n: _: hasCheck n) dependenciesForChecks));
serviceConfig = {
ExecStart = ''${autosuspend}/bin/autosuspend -l ${autosuspend}/etc/autosuspend-logging.conf -c ${autosuspend-conf} daemon'';
};
};
systemd.services.autosuspend-detect-suspend = {
description = "Notifies autosuspend about suspension";
documentation = [ "https://autosuspend.readthedocs.io/en/latest/systemd_integration.html" ];
wantedBy = [ "sleep.target" ];
after = [ "sleep.target" ];
serviceConfig = {
ExecStart = ''${autosuspend}/bin/autosuspend -l ${autosuspend}/etc/autosuspend-logging.conf -c ${autosuspend-conf} presuspend'';
};
};
};
meta = {
maintainers = with maintainers; [ xlambein ];
};
}