lol

tuned: init at 2.25.1 (#357480)

authored by

Seth Flynn and committed by
GitHub
f80495af edbc31e6

+508
+2
nixos/doc/manual/release-notes/rl-2511.section.md
··· 52 52 53 53 - [Corteza](https://cortezaproject.org/), a low-code platform. Available as [services.corteza](#opt-services.corteza.enable). 54 54 55 + - [TuneD](https://tuned-project.org/), a system tuning service for Linux. Available as [services.tuned](#opt-services.tuned.enable). 56 + 55 57 - [Draupnir](https://github.com/the-draupnir-project/draupnir), a Matrix moderation bot. Available as [services.draupnir](#opt-services.draupnir.enable). 56 58 57 59 - [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).
+1
nixos/modules/module-list.nix
··· 683 683 ./services/hardware/tlp.nix 684 684 ./services/hardware/trezord.nix 685 685 ./services/hardware/triggerhappy.nix 686 + ./services/hardware/tuned.nix 686 687 ./services/hardware/tuxedo-rs.nix 687 688 ./services/hardware/udev.nix 688 689 ./services/hardware/udisks2.nix
+247
nixos/modules/services/hardware/tuned.nix
··· 1 + { 2 + config, 3 + lib, 4 + pkgs, 5 + ... 6 + }: 7 + 8 + let 9 + cfg = config.services.tuned; 10 + 11 + moduleFromName = name: lib.getAttrFromPath (lib.splitString "." name) config; 12 + 13 + settingsFormat = pkgs.formats.iniWithGlobalSection { }; 14 + profileFormat = pkgs.formats.ini { }; 15 + ppdSettingsFormat = pkgs.formats.ini { }; 16 + 17 + settingsSubmodule = { 18 + freeformType = settingsFormat.type; 19 + 20 + options = { 21 + daemon = lib.mkEnableOption "the use of a daemon for TuneD" // { 22 + default = true; 23 + }; 24 + 25 + dynamic_tuning = lib.mkEnableOption "dynamic tuning"; 26 + 27 + sleep_interval = lib.mkOption { 28 + type = lib.types.int; 29 + default = 1; 30 + description = "Interval in which the TuneD daemon is waken up and checks for events (in seconds)."; 31 + }; 32 + 33 + update_interval = lib.mkOption { 34 + type = lib.types.int; 35 + default = 10; 36 + description = "Update interval for dynamic tuning (in seconds)."; 37 + }; 38 + 39 + recommend_command = lib.mkEnableOption "recommend functionality" // { 40 + default = true; 41 + }; 42 + 43 + reapply_sysctl = 44 + lib.mkEnableOption "the reapplying of global sysctls after TuneD sysctls are applied" 45 + // { 46 + default = true; 47 + }; 48 + 49 + default_instance_priority = lib.mkOption { 50 + type = lib.types.int; 51 + default = 0; 52 + description = "Default instance (unit) priority."; 53 + }; 54 + 55 + profile_dirs = lib.mkOption { 56 + type = lib.types.str; 57 + default = "/etc/tuned/profiles"; 58 + # Ensure we always have the vendored profiles available 59 + apply = dirs: "${cfg.package}/lib/tuned/profiles," + dirs; 60 + description = "Directories to search for profiles, separated by `,` or `;`."; 61 + }; 62 + }; 63 + }; 64 + 65 + ppdSettingsSubmodule = { 66 + freeformType = ppdSettingsFormat.type; 67 + 68 + options = { 69 + main = lib.mkOption { 70 + type = lib.types.submodule { 71 + options = { 72 + default = lib.mkOption { 73 + type = lib.types.str; 74 + default = "balanced"; 75 + description = "Default PPD profile."; 76 + example = "performance"; 77 + }; 78 + 79 + battery_detection = lib.mkEnableOption "battery detection" // { 80 + default = true; 81 + }; 82 + }; 83 + }; 84 + default = { }; 85 + description = "Core configuration for power-profiles-daemon support."; 86 + }; 87 + 88 + profiles = lib.mkOption { 89 + type = lib.types.attrsOf lib.types.str; 90 + default = { 91 + power-saver = "powersave"; 92 + balanced = "balanced"; 93 + performance = "throughput-performance"; 94 + }; 95 + description = "Map of PPD profiles to native TuneD profiles."; 96 + }; 97 + 98 + battery = lib.mkOption { 99 + type = lib.types.attrsOf lib.types.str; 100 + default = { 101 + balanced = "balanced-battery"; 102 + }; 103 + description = "Map of PPD battery states to TuneD profiles."; 104 + }; 105 + }; 106 + }; 107 + in 108 + 109 + { 110 + options.services.tuned = { 111 + enable = lib.mkEnableOption "TuneD"; 112 + 113 + package = lib.mkPackageOption pkgs "tuned" { }; 114 + 115 + settings = lib.mkOption { 116 + type = lib.types.submodule settingsSubmodule; 117 + default = { }; 118 + description = '' 119 + Configuration for TuneD. 120 + See {manpage}`tuned-main.conf(5)`. 121 + ''; 122 + }; 123 + 124 + profiles = lib.mkOption { 125 + type = lib.types.attrsOf ( 126 + lib.types.submodule { 127 + freeformType = profileFormat.type; 128 + } 129 + ); 130 + default = { }; 131 + description = '' 132 + Profiles for TuneD. 133 + See {manpage}`tuned.conf(5)`. 134 + ''; 135 + example = { 136 + my-cool-profile = { 137 + main.include = "my-other-cool-profile"; 138 + 139 + my_sysctl = { 140 + type = "sysctl"; 141 + replace = true; 142 + 143 + "net.core.rmem_default" = 262144; 144 + "net.core.wmem_default" = 262144; 145 + }; 146 + }; 147 + }; 148 + }; 149 + 150 + ppdSupport = lib.mkEnableOption "translation of power-profiles-daemon API calls to TuneD" // { 151 + default = true; 152 + }; 153 + 154 + ppdSettings = lib.mkOption { 155 + type = lib.types.submodule ppdSettingsSubmodule; 156 + default = { }; 157 + description = '' 158 + Settings for TuneD's power-profiles-daemon compatibility service. 159 + ''; 160 + }; 161 + }; 162 + 163 + config = lib.mkIf cfg.enable { 164 + assertions = [ 165 + # From `tuned.service` 166 + { 167 + assertion = config.security.polkit.enable; 168 + message = "`services.tuned` requires `security.polkit` to be enabled."; 169 + } 170 + 171 + { 172 + assertion = cfg.settings.dynamic_tuning -> cfg.settings.daemon; 173 + message = "`services.tuned.settings.dynamic_tuning` requires `services.tuned.settings.daemon` to be `true`."; 174 + } 175 + ] 176 + # Declare service conflicts, also sourced from `tuned.service` 177 + ++ 178 + map 179 + (name: { 180 + assertion = !(moduleFromName name).enable; 181 + message = "`services.tuned` conflicts with `${name}`."; 182 + }) 183 + [ 184 + "services.auto-cpufreq" 185 + "services.power-profiles-daemon" 186 + "services.tlp" 187 + ]; 188 + 189 + environment = { 190 + etc = lib.mkMerge [ 191 + { 192 + "tuned/tuned-main.conf".source = settingsFormat.generate "tuned-main.conf" { 193 + sections = { }; 194 + globalSection = cfg.settings; 195 + }; 196 + 197 + "tuned/ppd.conf".source = lib.mkIf cfg.ppdSupport ( 198 + ppdSettingsFormat.generate "ppd.conf" cfg.ppdSettings 199 + ); 200 + } 201 + 202 + (lib.mapAttrs' ( 203 + name: value: 204 + lib.nameValuePair "tuned/profiles/${name}/tuned.conf" { 205 + source = profileFormat.generate "tuned.conf" value; 206 + } 207 + ) cfg.profiles) 208 + ]; 209 + 210 + systemPackages = [ cfg.package ]; 211 + }; 212 + 213 + security.polkit.enable = lib.mkDefault true; 214 + 215 + services = { 216 + dbus.packages = [ cfg.package ]; 217 + 218 + # Many DEs (like GNOME and KDE Plasma) enable PPD by default 219 + # Let's try to make it easier to transition by only enabling this module 220 + power-profiles-daemon.enable = false; 221 + }; 222 + 223 + systemd = { 224 + packages = [ cfg.package ]; 225 + 226 + services = { 227 + tuned = { 228 + wantedBy = [ "multi-user.target" ]; 229 + }; 230 + 231 + tuned-ppd = lib.mkIf cfg.ppdSupport { 232 + wantedBy = [ "graphical.target" ]; 233 + }; 234 + }; 235 + 236 + tmpfiles = { 237 + packages = [ cfg.package ]; 238 + 239 + # NOTE(@getchoo): `cfg.package` should contain a `tuned.conf` for tmpfiles.d already. Avoid a naming conflict! 240 + settings.tuned-profiles = { 241 + # Required for tuned-gui 242 + "/etc/tuned/profiles".d = { }; 243 + }; 244 + }; 245 + }; 246 + }; 247 + }
+1
nixos/tests/all-tests.nix
··· 1499 1499 ttyd = runTest ./web-servers/ttyd.nix; 1500 1500 tt-rss = runTest ./web-apps/tt-rss.nix; 1501 1501 txredisapi = runTest ./txredisapi.nix; 1502 + tuned = runTest ./tuned.nix; 1502 1503 tuptime = runTest ./tuptime.nix; 1503 1504 turbovnc-headless-server = runTest ./turbovnc-headless-server.nix; 1504 1505 turn-rs = runTest ./turn-rs.nix;
+51
nixos/tests/tuned.nix
··· 1 + { pkgs, ... }: 2 + 3 + { 4 + name = "tuned"; 5 + meta = { inherit (pkgs.tuned.meta) maintainers; }; 6 + 7 + nodes.machine = { 8 + imports = [ ./common/x11.nix ]; 9 + 10 + services.tuned = { 11 + enable = true; 12 + 13 + profiles = { 14 + test-profile = { 15 + sysctls = { 16 + type = "sysctl"; 17 + replace = true; 18 + 19 + "net.core.rmem_default" = 262144; 20 + "net.core.wmem_default" = 262144; 21 + }; 22 + }; 23 + }; 24 + }; 25 + }; 26 + 27 + enableOCR = true; 28 + 29 + testScript = '' 30 + with subtest("Wait for service startup"): 31 + machine.wait_for_x() 32 + machine.wait_for_unit("tuned.service") 33 + machine.wait_for_unit("tuned-ppd.service") 34 + 35 + with subtest("Get service status"): 36 + machine.succeed("systemctl status tuned.service") 37 + 38 + # NOTE(@getchoo): `pkgs.tuned` provides its own `tuned.conf` for tmpfiles.d 39 + # A naming conflict with it and a `systemd.tmpfiles.settings` entry appeared in the initial PR for this module 40 + # This breaks the GUI in some cases, and it was annoying to figure out. Make sure it doesn't happen again! 41 + with subtest("Ensure systemd-tmpfiles paths are configured"): 42 + machine.succeed("systemd-tmpfiles --cat-config | grep '/etc/tuned/profiles'") 43 + machine.succeed("systemd-tmpfiles --cat-config | grep '/run/tuned'") 44 + 45 + with subtest("Test GUI"): 46 + machine.execute("tuned-gui >&2 &") 47 + machine.wait_for_window("tuned") 48 + machine.wait_for_text("Start TuneD Daemon") 49 + machine.screenshot("gui") 50 + ''; 51 + }
+154
pkgs/by-name/tu/tuned/package.nix
··· 1 + { 2 + lib, 3 + stdenv, 4 + asciidoctor, 5 + desktop-file-utils, 6 + dmidecode, 7 + ethtool, 8 + fetchFromGitHub, 9 + gawk, 10 + gobject-introspection, 11 + hdparm, 12 + iproute2, 13 + nix-update-script, 14 + nixosTests, 15 + pkg-config, 16 + powertop, 17 + python3Packages, 18 + tuna, 19 + util-linux, 20 + versionCheckHook, 21 + virt-what, 22 + wrapGAppsHook3, 23 + }: 24 + 25 + stdenv.mkDerivation (finalAttrs: { 26 + pname = "tuned"; 27 + version = "2.25.1"; 28 + 29 + outputs = [ 30 + "out" 31 + "doc" 32 + "man" 33 + ]; 34 + 35 + src = fetchFromGitHub { 36 + owner = "redhat-performance"; 37 + repo = "tuned"; 38 + tag = "v${finalAttrs.version}"; 39 + hash = "sha256-MMyYMgdvoAIeLCqUZMoQYsYYbgkXku47nZWq2aowPFg="; 40 + }; 41 + 42 + patches = [ 43 + # Some tests require a TTY to run 44 + ./remove-tty-tests.patch 45 + ]; 46 + 47 + postPatch = '' 48 + patchShebangs . 49 + 50 + substituteInPlace tuned-gui.py tuned.service tuned/ppd/tuned-ppd.service \ 51 + --replace-warn "/usr/sbin/" "$out/bin/" 52 + 53 + substituteInPlace tuned-gui.py \ 54 + --replace-warn "/usr/share/" "$out/share/" 55 + 56 + substituteInPlace tuned-gui.desktop \ 57 + --replace-warn "/usr/sbin/tuned-gui" "tuned-gui" 58 + 59 + substituteInPlace experiments/powertop2tuned.py \ 60 + --replace-warn "/usr/sbin/powertop" "${lib.getExe powertop}" 61 + ''; 62 + 63 + strictDeps = true; 64 + 65 + nativeBuildInputs = [ 66 + asciidoctor 67 + desktop-file-utils 68 + gobject-introspection 69 + pkg-config 70 + wrapGAppsHook3 71 + python3Packages.wrapPython 72 + ]; 73 + 74 + propagatedBuildInputs = with python3Packages; [ 75 + dbus-python 76 + pygobject3 77 + pyinotify 78 + pyperf 79 + python-linux-procfs 80 + pyudev 81 + tuna 82 + ]; 83 + 84 + makeFlags = [ 85 + "PREFIX=" 86 + 87 + "DATADIR=/share" 88 + "DESTDIR=${placeholder "out"}" 89 + "KERNELINSTALLHOOKDIR=/lib/kernel/install.d" 90 + "PYTHON=${lib.getExe python3Packages.python}" 91 + "PYTHON_SITELIB=/${python3Packages.python.sitePackages}" 92 + "TMPFILESDIR=/lib/tmpfiles.d" 93 + "TUNED_PROFILESDIR=/lib/tuned/profile" 94 + "UNITDIR=/lib/systemd/system" 95 + ]; 96 + 97 + installTargets = [ 98 + "install" 99 + "install-ppd" 100 + ]; 101 + 102 + dontWrapGApps = true; 103 + makeWrapperArgs = [ 104 + "\${gappsWrapperArgs[@]}" 105 + "--prefix" 106 + "PATH" 107 + ":" 108 + (lib.makeBinPath [ 109 + dmidecode 110 + ethtool 111 + gawk 112 + hdparm 113 + iproute2 114 + util-linux 115 + virt-what 116 + ]) 117 + ]; 118 + 119 + doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform; 120 + checkTarget = "test"; 121 + 122 + doInstallCheck = true; 123 + nativeInstallCheckInputs = [ 124 + python3Packages.pythonImportsCheckHook 125 + versionCheckHook 126 + ]; 127 + 128 + pythonImportsCheck = [ "tuned" ]; 129 + 130 + postInstall = '' 131 + rm -rf $out/{run,var} 132 + ''; 133 + 134 + postFixup = '' 135 + wrapPythonPrograms 136 + ''; 137 + 138 + passthru = { 139 + tests = lib.optionalAttrs stdenv.hostPlatform.isLinux { 140 + nixos = nixosTests.tuned; 141 + }; 142 + updateScript = nix-update-script { }; 143 + }; 144 + 145 + meta = { 146 + description = "Tuning Profile Delivery Mechanism for Linux"; 147 + homepage = "https://tuned-project.org"; 148 + changelog = "https://github.com/redhat-performance/tuned/releases/tag/v${finalAttrs.version}"; 149 + license = lib.licenses.gpl2Only; 150 + maintainers = with lib.maintainers; [ getchoo ]; 151 + mainProgram = "tuned"; 152 + platforms = lib.platforms.linux; 153 + }; 154 + })
+52
pkgs/by-name/tu/tuned/remove-tty-tests.patch
··· 1 + diff --git a/tests/unit/hardware/test_device_matcher_udev.py b/tests/unit/hardware/test_device_matcher_udev.py 2 + index 1903955..f973107 100644 3 + --- a/tests/unit/hardware/test_device_matcher_udev.py 4 + +++ b/tests/unit/hardware/test_device_matcher_udev.py 5 + @@ -10,27 +10,7 @@ class DeviceMatcherUdevTestCase(unittest.TestCase): 6 + cls.matcher = DeviceMatcherUdev() 7 + 8 + def test_simple_search(self): 9 + - try: 10 + - device = pyudev.Devices.from_sys_path(self.udev_context, 11 + - "/sys/devices/virtual/tty/tty0") 12 + - except AttributeError: 13 + - device = pyudev.Device.from_sys_path(self.udev_context, 14 + - "/sys/devices/virtual/tty/tty0") 15 + - self.assertTrue(self.matcher.match("tty0", device)) 16 + - try: 17 + - device = pyudev.Devices.from_sys_path(self.udev_context, 18 + - "/sys/devices/virtual/tty/tty1") 19 + - except AttributeError: 20 + - device = pyudev.Device.from_sys_path(self.udev_context, 21 + - "/sys/devices/virtual/tty/tty1") 22 + - self.assertFalse(self.matcher.match("tty0", device)) 23 + + return True 24 + 25 + def test_regex_search(self): 26 + - try: 27 + - device = pyudev.Devices.from_sys_path(self.udev_context, 28 + - "/sys/devices/virtual/tty/tty0") 29 + - except AttributeError: 30 + - device = pyudev.Device.from_sys_path(self.udev_context, 31 + - "/sys/devices/virtual/tty/tty0") 32 + - self.assertTrue(self.matcher.match("tty.", device)) 33 + - self.assertFalse(self.matcher.match("tty[1-9]", device)) 34 + + return True 35 + diff --git a/tests/unit/hardware/test_inventory.py b/tests/unit/hardware/test_inventory.py 36 + index 8490922..8bd004b 100644 37 + --- a/tests/unit/hardware/test_inventory.py 38 + +++ b/tests/unit/hardware/test_inventory.py 39 + @@ -18,12 +18,7 @@ class InventoryTestCase(unittest.TestCase): 40 + cls._dummier = DummyPlugin() 41 + 42 + def test_get_device(self): 43 + - try: 44 + - device1 = pyudev.Devices.from_name(self._context, "tty", "tty0") 45 + - except AttributeError: 46 + - device1 = pyudev.Device.from_name(self._context, "tty", "tty0") 47 + - device2 = self._inventory.get_device("tty", "tty0") 48 + - self.assertEqual(device1,device2) 49 + + return True 50 + 51 + def test_get_devices(self): 52 + device_list1 = self._context.list_devices(subsystem = "tty")