Skip to content

Commit

Permalink
Merge pull request #263375 from lorenzleutgeb/benchexec
Browse files Browse the repository at this point in the history
benchexec: init at 3.21
  • Loading branch information
SuperSandro2000 authored May 18, 2024
2 parents c7829cd + 9f2f635 commit c21d10b
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 0 deletions.
5 changes: 5 additions & 0 deletions nixos/doc/manual/release-notes/rl-2405.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi

- [Handheld Daemon](https://github.com/hhd-dev/hhd), support for gaming handhelds like the Legion Go, ROG Ally, and GPD Win. Available as [services.handheld-daemon](#opt-services.handheld-daemon.enable).

- [BenchExec](https://github.com/sosy-lab/benchexec), a framework for reliable benchmarking and resource measurement, available as [programs.benchexec](#opt-programs.benchexec.enable),
As well as related programs
[CPU Energy Meter](https://github.com/sosy-lab/cpu-energy-meter), available as [programs.cpu-energy-meter](#opt-programs.cpu-energy-meter.enable), and
[PQoS Wrapper](https://gitlab.com/sosy-lab/software/pqos-wrapper), available as [programs.pqos-wrapper](#opt-programs.pqos-wrapper.enable).

- [Guix](https://guix.gnu.org), a functional package manager inspired by Nix. Available as [services.guix](#opt-services.guix.enable).

- [PhotonVision](https://photonvision.org/), a free, fast, and easy-to-use computer vision solution for the FIRST® Robotics Competition.
Expand Down
3 changes: 3 additions & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@
./programs/bash/ls-colors.nix
./programs/bash/undistract-me.nix
./programs/bcc.nix
./programs/benchexec.nix
./programs/browserpass.nix
./programs/calls.nix
./programs/captive-browser.nix
Expand All @@ -167,6 +168,7 @@
./programs/chromium.nix
./programs/clash-verge.nix
./programs/cnping.nix
./programs/cpu-energy-meter.nix
./programs/command-not-found/command-not-found.nix
./programs/coolercontrol.nix
./programs/criu.nix
Expand Down Expand Up @@ -250,6 +252,7 @@
./programs/pantheon-tweaks.nix
./programs/partition-manager.nix
./programs/plotinus.nix
./programs/pqos-wrapper.nix
./programs/projecteur.nix
./programs/proxychains.nix
./programs/qdmr.nix
Expand Down
98 changes: 98 additions & 0 deletions nixos/modules/programs/benchexec.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{ lib
, pkgs
, config
, options
, ...
}:
let
cfg = config.programs.benchexec;
opt = options.programs.benchexec;

filterUsers = x:
if builtins.isString x then config.users.users ? ${x} else
if builtins.isInt x then x else
throw "filterUsers expects string (username) or int (UID)";

uid = x:
if builtins.isString x then config.users.users.${x}.uid else
if builtins.isInt x then x else
throw "uid expects string (username) or int (UID)";
in
{
options.programs.benchexec = {
enable = lib.mkEnableOption "BenchExec";
package = lib.options.mkPackageOption pkgs "benchexec" { };

users = lib.options.mkOption {
type = with lib.types; listOf (either str int);
description = ''
Users that intend to use BenchExec.
Provide usernames of users that are configured via {option}`${options.users.users}` as string,
and UIDs of "mutable users" as integers.
Control group delegation will be configured via systemd.
For more information, see <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#setting-up-cgroups>.
'';
default = [ ];
example = lib.literalExpression ''
[
"alice" # username of a user configured via ${options.users.users}
1007 # UID of a mutable user
]
'';
};
};

config = lib.mkIf cfg.enable {
assertions = (map
(user: {
assertion = config.users.users ? ${user};
message = ''
The user '${user}' intends to use BenchExec (via `${opt.users}`), but is not configured via `${options.users.users}`.
'';
})
(builtins.filter builtins.isString cfg.users)
) ++ (map
(id: {
assertion = config.users.mutableUsers;
message = ''
The user with UID '${id}' intends to use BenchExec (via `${opt.users}`), but mutable users are disabled via `${options.users.mutableUsers}`.
'';
})
(builtins.filter builtins.isInt cfg.users)
) ++ [
{
assertion = config.systemd.enableUnifiedCgroupHierarchy == true;
message = ''
The BenchExec module `${opt.enable}` only supports control groups 2 (`${options.systemd.enableUnifiedCgroupHierarchy} = true`).
'';
}
];

environment.systemPackages = [ cfg.package ];

# See <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#setting-up-cgroups>.
systemd.services = builtins.listToAttrs (map
(user: {
name = "user@${builtins.toString (uid user)}";
value = {
serviceConfig.Delegate = "yes";
overrideStrategy = "asDropin";
};
})
(builtins.filter filterUsers cfg.users));

# See <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#requirements>.
virtualisation.lxc.lxcfs.enable = lib.mkDefault true;

# See <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#requirements>.
programs = {
cpu-energy-meter.enable = lib.mkDefault true;
pqos-wrapper.enable = lib.mkDefault true;
};

# See <https://github.com/sosy-lab/benchexec/blob/3.18/doc/INSTALL.md#kernel-requirements>.
security.unprivilegedUsernsClone = true;
};

meta.maintainers = with lib.maintainers; [ lorenzleutgeb ];
}
27 changes: 27 additions & 0 deletions nixos/modules/programs/cpu-energy-meter.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{ config
, lib
, pkgs
, ...
}: {
options.programs.cpu-energy-meter = {
enable = lib.mkEnableOption "CPU Energy Meter";
package = lib.mkPackageOption pkgs "cpu-energy-meter" { };
};

config =
let
cfg = config.programs.cpu-energy-meter;
in
lib.mkIf cfg.enable {
hardware.cpu.x86.msr.enable = true;

security.wrappers.${cfg.package.meta.mainProgram} = {
owner = "nobody";
group = config.hardware.cpu.x86.msr.group;
source = lib.getExe cfg.package;
capabilities = "cap_sys_rawio=ep";
};
};

meta.maintainers = with lib.maintainers; [ lorenzleutgeb ];
}
27 changes: 27 additions & 0 deletions nixos/modules/programs/pqos-wrapper.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{ config
, lib
, pkgs
, ...
}:
let
cfg = config.programs.pqos-wrapper;
in
{
options.programs.pqos-wrapper = {
enable = lib.mkEnableOption "PQoS Wrapper for BenchExec";
package = lib.mkPackageOption pkgs "pqos-wrapper" { };
};

config = lib.mkIf cfg.enable {
hardware.cpu.x86.msr.enable = true;

security.wrappers.${cfg.package.meta.mainProgram} = {
owner = "nobody";
group = config.hardware.cpu.x86.msr.group;
source = lib.getExe cfg.package;
capabilities = "cap_sys_rawio=eip";
};
};

meta.maintainers = with lib.maintainers; [ lorenzleutgeb ];
}
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ in {
bcachefs = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bcachefs.nix {};
beanstalkd = handleTest ./beanstalkd.nix {};
bees = handleTest ./bees.nix {};
benchexec = handleTest ./benchexec.nix {};
binary-cache = handleTest ./binary-cache.nix {};
bind = handleTest ./bind.nix {};
bird = handleTest ./bird.nix {};
Expand Down
54 changes: 54 additions & 0 deletions nixos/tests/benchexec.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import ./make-test-python.nix ({ pkgs, lib, ... }:
let
user = "alice";
in
{
name = "benchexec";

nodes.benchexec = {
imports = [ ./common/user-account.nix ];

programs.benchexec = {
enable = true;
users = [ user ];
};
};

testScript = { ... }:
let
runexec = lib.getExe' pkgs.benchexec "runexec";
echo = builtins.toString pkgs.benchexec;
test = lib.getExe (pkgs.writeShellApplication rec {
name = "test";
meta.mainProgram = name;
text = "echo '${echo}'";
});
wd = "/tmp";
stdout = "${wd}/runexec.out";
stderr = "${wd}/runexec.err";
in
''
start_all()
machine.wait_for_unit("multi-user.target")
benchexec.succeed(''''\
systemd-run \
--property='StandardOutput=file:${stdout}' \
--property='StandardError=file:${stderr}' \
--unit=runexec --wait --user --machine='${user}@' \
--working-directory ${wd} \
'${runexec}' \
--debug \
--read-only-dir / \
--hidden-dir /home \
'${test}' \
'''')
benchexec.succeed("grep -s '${echo}' ${wd}/output.log")
benchexec.succeed("test \"$(grep -Ec '((start|wall|cpu)time|memory)=' ${stdout})\" = 4")
benchexec.succeed("! grep -E '(WARNING|ERROR)' ${stderr}")
'';

interactive.nodes.benchexec.services.kmscon = {
enable = true;
fonts = [{ name = "Fira Code"; package = pkgs.fira-code; }];
};
})
62 changes: 62 additions & 0 deletions pkgs/by-name/be/benchexec/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{ lib
, fetchFromGitHub
, python3
, libseccomp
, nixosTests
, testers
, benchexec
}:
python3.pkgs.buildPythonApplication rec {
pname = "benchexec";
version = "3.21";

src = fetchFromGitHub {
owner = "sosy-lab";
repo = "benchexec";
rev = version;
hash = "sha256-bE3brmmLHZQakDKvd47I1hm9Dcsu6DrSeJyjWWtEZWI=";
};

pyproject = true;

nativeBuildInputs = with python3.pkgs; [ setuptools ];

# NOTE: CPU Energy Meter is not added,
# because BenchExec should call the wrapper configured
# via `security.wrappers.cpu-energy-meter`
# in `programs.cpu-energy-meter`, which will have the required
# capabilities to access MSR.
# If we add `cpu-energy-meter` here, BenchExec will instead call an executable
# without `CAP_SYS_RAWIO` and fail.
propagatedBuildInputs = with python3.pkgs; [
coloredlogs
lxml
pystemd
pyyaml
];

makeWrapperArgs = [ "--set-default LIBSECCOMP ${lib.getLib libseccomp}/lib/libseccomp.so" ];

passthru.tests =
let
testVersion = result: testers.testVersion {
command = "${result} --version";
package = benchexec;
};
in
{
nixos = nixosTests.benchexec;
benchexec-version = testVersion "benchexec";
runexec-version = testVersion "runexec";
table-generator-version = testVersion "table-generator";
containerexec-version = testVersion "containerexec";
};

meta = with lib; {
description = "A Framework for Reliable Benchmarking and Resource Measurement.";
homepage = "https://github.com/sosy-lab/benchexec";
maintainers = with maintainers; [ lorenzleutgeb ];
license = licenses.asl20;
mainProgram = "benchexec";
};
}
40 changes: 40 additions & 0 deletions pkgs/by-name/cp/cpu-energy-meter/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{ lib
, stdenv
, fetchFromGitHub
, libcap
}:
stdenv.mkDerivation rec {
pname = "cpu-energy-meter";
version = "1.2";

src = fetchFromGitHub {
owner = "sosy-lab";
repo = "cpu-energy-meter";
rev = version;
hash = "sha256-QW65Z8mRYLHcyLeOtNAHjwPNWAUP214wqIYclK+whFw=";
};

postPatch = ''
substituteInPlace Makefile \
--replace "DESTDIR :=" "DESTDIR := $out" \
--replace "PREFIX := /usr/local" "PREFIX :="
'';

buildInputs = [ libcap ];

env.NIX_CFLAGS_COMPILE = "-fcommon";

postInstall = ''
install -Dm444 -t $out/etc/udev/rules.d $src/debian/additional_files/59-msr.rules
'';

meta = with lib; {
description = "A tool for measuring energy consumption of Intel CPUs";
homepage = "https://github.com/sosy-lab/cpu-energy-meter";
changelog = "https://github.com/sosy-lab/cpu-energy-meter/blob/main/CHANGELOG.md";
maintainers = with maintainers; [ lorenzleutgeb ];
license = licenses.bsd3;
platforms = [ "x86_64-linux" ];
mainProgram = "cpu-energy-meter";
};
}
28 changes: 28 additions & 0 deletions pkgs/by-name/pq/pqos-wrapper/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{ lib
, intel-cmt-cat
, fetchFromGitLab
, python3
}:
python3.pkgs.buildPythonApplication rec {
pname = "pqos-wrapper";
version = "unstable-2022-01-31";

src = fetchFromGitLab {
group = "sosy-lab";
owner = "software";
repo = pname;
rev = "ce816497a07dcb4b931652b98359e4601a292b15";
hash = "sha256-SaYr6lVucpJjVtGgxRbDGYbOoBwdfEDVKtvD+M1L0o4=";
};

makeWrapperArgs = [ "--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ intel-cmt-cat ]}" ];

meta = with lib; {
description = "Wrapper for Intel PQoS for the purpose of using it in BenchExec";
homepage = "https://gitlab.com/sosy-lab/software/pqos-wrapper";
maintainers = with maintainers; [ lorenzleutgeb ];
license = licenses.asl20;
platforms = [ "x86_64-linux" ];
mainProgram = "pqos_wrapper";
};
}

0 comments on commit c21d10b

Please sign in to comment.