nixos/tuned: init
This commit is contained in:
@@ -42,6 +42,8 @@
|
|||||||
|
|
||||||
- [Corteza](https://cortezaproject.org/), a low-code platform. Available as [services.corteza](#opt-services.corteza.enable).
|
- [Corteza](https://cortezaproject.org/), a low-code platform. Available as [services.corteza](#opt-services.corteza.enable).
|
||||||
|
|
||||||
|
- [TuneD](https://tuned-project.org/), a system tuning service for Linux. Available as [services.tuned](#opt-services.tuned.enable).
|
||||||
|
|
||||||
- [Draupnir](https://github.com/the-draupnir-project/draupnir), a Matrix moderation bot. Available as [services.draupnir](#opt-services.draupnir.enable).
|
- [Draupnir](https://github.com/the-draupnir-project/draupnir), a Matrix moderation bot. Available as [services.draupnir](#opt-services.draupnir.enable).
|
||||||
|
|
||||||
- [postfix-tlspol](https://github.com/Zuplu/postfix-tlspol), MTA-STS and DANE resolver and TLS policy server for Postfix. Available as [services.postfix-tlspol](#opt-services.postfix-tlspol.enable).
|
- [postfix-tlspol](https://github.com/Zuplu/postfix-tlspol), MTA-STS and DANE resolver and TLS policy server for Postfix. Available as [services.postfix-tlspol](#opt-services.postfix-tlspol.enable).
|
||||||
|
|||||||
@@ -682,6 +682,7 @@
|
|||||||
./services/hardware/tlp.nix
|
./services/hardware/tlp.nix
|
||||||
./services/hardware/trezord.nix
|
./services/hardware/trezord.nix
|
||||||
./services/hardware/triggerhappy.nix
|
./services/hardware/triggerhappy.nix
|
||||||
|
./services/hardware/tuned.nix
|
||||||
./services/hardware/tuxedo-rs.nix
|
./services/hardware/tuxedo-rs.nix
|
||||||
./services/hardware/udev.nix
|
./services/hardware/udev.nix
|
||||||
./services/hardware/udisks2.nix
|
./services/hardware/udisks2.nix
|
||||||
|
|||||||
247
nixos/modules/services/hardware/tuned.nix
Normal file
247
nixos/modules/services/hardware/tuned.nix
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.tuned;
|
||||||
|
|
||||||
|
moduleFromName = name: lib.getAttrFromPath (lib.splitString "." name) config;
|
||||||
|
|
||||||
|
settingsFormat = pkgs.formats.iniWithGlobalSection { };
|
||||||
|
profileFormat = pkgs.formats.ini { };
|
||||||
|
ppdSettingsFormat = pkgs.formats.ini { };
|
||||||
|
|
||||||
|
settingsSubmodule = {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
daemon = lib.mkEnableOption "the use of a daemon for TuneD" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
dynamic_tuning = lib.mkEnableOption "dynamic tuning";
|
||||||
|
|
||||||
|
sleep_interval = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 1;
|
||||||
|
description = "Interval in which the TuneD daemon is waken up and checks for events (in seconds).";
|
||||||
|
};
|
||||||
|
|
||||||
|
update_interval = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 10;
|
||||||
|
description = "Update interval for dynamic tuning (in seconds).";
|
||||||
|
};
|
||||||
|
|
||||||
|
recommend_command = lib.mkEnableOption "recommend functionality" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
reapply_sysctl =
|
||||||
|
lib.mkEnableOption "the reapplying of global sysctls after TuneD sysctls are applied"
|
||||||
|
// {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
default_instance_priority = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 0;
|
||||||
|
description = "Default instance (unit) priority.";
|
||||||
|
};
|
||||||
|
|
||||||
|
profile_dirs = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/etc/tuned/profiles";
|
||||||
|
# Ensure we always have the vendored profiles available
|
||||||
|
apply = dirs: "${cfg.package}/lib/tuned/profiles," + dirs;
|
||||||
|
description = "Directories to search for profiles, separated by `,` or `;`.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ppdSettingsSubmodule = {
|
||||||
|
freeformType = ppdSettingsFormat.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
main = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
default = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "balanced";
|
||||||
|
description = "Default PPD profile.";
|
||||||
|
example = "performance";
|
||||||
|
};
|
||||||
|
|
||||||
|
battery_detection = lib.mkEnableOption "battery detection" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
description = "Core configuration for power-profiles-daemon support.";
|
||||||
|
};
|
||||||
|
|
||||||
|
profiles = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
default = {
|
||||||
|
power-saver = "powersave";
|
||||||
|
balanced = "balanced";
|
||||||
|
performance = "throughput-performance";
|
||||||
|
};
|
||||||
|
description = "Map of PPD profiles to native TuneD profiles.";
|
||||||
|
};
|
||||||
|
|
||||||
|
battery = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
default = {
|
||||||
|
balanced = "balanced-battery";
|
||||||
|
};
|
||||||
|
description = "Map of PPD battery states to TuneD profiles.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.services.tuned = {
|
||||||
|
enable = lib.mkEnableOption "TuneD";
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "tuned" { };
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = lib.types.submodule settingsSubmodule;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Configuration for TuneD.
|
||||||
|
See {manpage}`tuned-main.conf(5)`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
profiles = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
freeformType = profileFormat.type;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Profiles for TuneD.
|
||||||
|
See {manpage}`tuned.conf(5)`.
|
||||||
|
'';
|
||||||
|
example = {
|
||||||
|
my-cool-profile = {
|
||||||
|
main.include = "my-other-cool-profile";
|
||||||
|
|
||||||
|
my_sysctl = {
|
||||||
|
type = "sysctl";
|
||||||
|
replace = true;
|
||||||
|
|
||||||
|
"net.core.rmem_default" = 262144;
|
||||||
|
"net.core.wmem_default" = 262144;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ppdSupport = lib.mkEnableOption "translation of power-profiles-daemon API calls to TuneD" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
ppdSettings = lib.mkOption {
|
||||||
|
type = lib.types.submodule ppdSettingsSubmodule;
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Settings for TuneD's power-profiles-daemon compatibility service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
# From `tuned.service`
|
||||||
|
{
|
||||||
|
assertion = config.security.polkit.enable;
|
||||||
|
message = "`services.tuned` requires `security.polkit` to be enabled.";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
assertion = cfg.settings.dynamic_tuning -> cfg.settings.daemon;
|
||||||
|
message = "`services.tuned.settings.dynamic_tuning` requires `services.tuned.settings.daemon` to be `true`.";
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# Declare service conflicts, also sourced from `tuned.service`
|
||||||
|
++
|
||||||
|
map
|
||||||
|
(name: {
|
||||||
|
assertion = !(moduleFromName name).enable;
|
||||||
|
message = "`services.tuned` conflicts with `${name}`.";
|
||||||
|
})
|
||||||
|
[
|
||||||
|
"services.auto-cpufreq"
|
||||||
|
"services.power-profiles-daemon"
|
||||||
|
"services.tlp"
|
||||||
|
];
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
etc = lib.mkMerge [
|
||||||
|
{
|
||||||
|
"tuned/tuned-main.conf".source = settingsFormat.generate "tuned-main.conf" {
|
||||||
|
sections = { };
|
||||||
|
globalSection = cfg.settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
"tuned/ppd.conf".source = lib.mkIf cfg.ppdSupport (
|
||||||
|
ppdSettingsFormat.generate "ppd.conf" cfg.ppdSettings
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
(lib.mapAttrs' (
|
||||||
|
name: value:
|
||||||
|
lib.nameValuePair "tuned/profiles/${name}/tuned.conf" {
|
||||||
|
source = profileFormat.generate "tuned.conf" value;
|
||||||
|
}
|
||||||
|
) cfg.profiles)
|
||||||
|
];
|
||||||
|
|
||||||
|
systemPackages = [ cfg.package ];
|
||||||
|
};
|
||||||
|
|
||||||
|
security.polkit.enable = lib.mkDefault true;
|
||||||
|
|
||||||
|
services = {
|
||||||
|
dbus.packages = [ cfg.package ];
|
||||||
|
|
||||||
|
# Many DEs (like GNOME and KDE Plasma) enable PPD by default
|
||||||
|
# Let's try to make it easier to transition by only enabling this module
|
||||||
|
power-profiles-daemon.enable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
packages = [ cfg.package ];
|
||||||
|
|
||||||
|
services = {
|
||||||
|
tuned = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
tuned-ppd = lib.mkIf cfg.ppdSupport {
|
||||||
|
wantedBy = [ "graphical.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
tmpfiles = {
|
||||||
|
packages = [ cfg.package ];
|
||||||
|
|
||||||
|
# NOTE(@getchoo): `cfg.package` should contain a `tuned.conf` for tmpfiles.d already. Avoid a naming conflict!
|
||||||
|
settings.tuned-profiles = {
|
||||||
|
# Required for tuned-gui
|
||||||
|
"/etc/tuned/profiles".d = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1477,6 +1477,7 @@ in
|
|||||||
ttyd = runTest ./web-servers/ttyd.nix;
|
ttyd = runTest ./web-servers/ttyd.nix;
|
||||||
tt-rss = runTest ./web-apps/tt-rss.nix;
|
tt-rss = runTest ./web-apps/tt-rss.nix;
|
||||||
txredisapi = runTest ./txredisapi.nix;
|
txredisapi = runTest ./txredisapi.nix;
|
||||||
|
tuned = runTest ./tuned.nix;
|
||||||
tuptime = runTest ./tuptime.nix;
|
tuptime = runTest ./tuptime.nix;
|
||||||
turbovnc-headless-server = runTest ./turbovnc-headless-server.nix;
|
turbovnc-headless-server = runTest ./turbovnc-headless-server.nix;
|
||||||
turn-rs = runTest ./turn-rs.nix;
|
turn-rs = runTest ./turn-rs.nix;
|
||||||
|
|||||||
51
nixos/tests/tuned.nix
Normal file
51
nixos/tests/tuned.nix
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
name = "tuned";
|
||||||
|
meta = { inherit (pkgs.tuned.meta) maintainers; };
|
||||||
|
|
||||||
|
nodes.machine = {
|
||||||
|
imports = [ ./common/x11.nix ];
|
||||||
|
|
||||||
|
services.tuned = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
profiles = {
|
||||||
|
test-profile = {
|
||||||
|
sysctls = {
|
||||||
|
type = "sysctl";
|
||||||
|
replace = true;
|
||||||
|
|
||||||
|
"net.core.rmem_default" = 262144;
|
||||||
|
"net.core.wmem_default" = 262144;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
enableOCR = true;
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
with subtest("Wait for service startup"):
|
||||||
|
machine.wait_for_x()
|
||||||
|
machine.wait_for_unit("tuned.service")
|
||||||
|
machine.wait_for_unit("tuned-ppd.service")
|
||||||
|
|
||||||
|
with subtest("Get service status"):
|
||||||
|
machine.succeed("systemctl status tuned.service")
|
||||||
|
|
||||||
|
# NOTE(@getchoo): `pkgs.tuned` provides its own `tuned.conf` for tmpfiles.d
|
||||||
|
# A naming conflict with it and a `systemd.tmpfiles.settings` entry appeared in the initial PR for this module
|
||||||
|
# This breaks the GUI in some cases, and it was annoying to figure out. Make sure it doesn't happen again!
|
||||||
|
with subtest("Ensure systemd-tmpfiles paths are configured"):
|
||||||
|
machine.succeed("systemd-tmpfiles --cat-config | grep '/etc/tuned/profiles'")
|
||||||
|
machine.succeed("systemd-tmpfiles --cat-config | grep '/run/tuned'")
|
||||||
|
|
||||||
|
with subtest("Test GUI"):
|
||||||
|
machine.execute("tuned-gui >&2 &")
|
||||||
|
machine.wait_for_window("tuned")
|
||||||
|
machine.wait_for_text("Start TuneD Daemon")
|
||||||
|
machine.screenshot("gui")
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
hdparm,
|
hdparm,
|
||||||
iproute2,
|
iproute2,
|
||||||
nix-update-script,
|
nix-update-script,
|
||||||
|
nixosTests,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
powertop,
|
powertop,
|
||||||
python3Packages,
|
python3Packages,
|
||||||
@@ -135,6 +136,9 @@ stdenv.mkDerivation (finalAttrs: {
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
passthru = {
|
passthru = {
|
||||||
|
tests = lib.optionalAttrs stdenv.hostPlatform.isLinux {
|
||||||
|
nixos = nixosTests.tuned;
|
||||||
|
};
|
||||||
updateScript = nix-update-script { };
|
updateScript = nix-update-script { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user