Merge pull request #263375 from lorenzleutgeb/benchexec

benchexec: init at 3.21

Sandro c21d10ba c7829cdc

Changed files
+345
nixos
pkgs
by-name
be
benchexec
cp
cpu-energy-meter
pq
pqos-wrapper
+5
nixos/doc/manual/release-notes/rl-2405.section.md
···
- [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.
+3
nixos/modules/module-list.nix
···
./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
···
./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
···
./programs/pantheon-tweaks.nix
./programs/partition-manager.nix
./programs/plotinus.nix
+
./programs/pqos-wrapper.nix
./programs/projecteur.nix
./programs/proxychains.nix
./programs/qdmr.nix
+98
nixos/modules/programs/benchexec.nix
···
+
{ 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
nixos/modules/programs/cpu-energy-meter.nix
···
+
{ 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
nixos/modules/programs/pqos-wrapper.nix
···
+
{ 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
nixos/tests/all-tests.nix
···
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 {};
+54
nixos/tests/benchexec.nix
···
+
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
pkgs/by-name/be/benchexec/package.nix
···
+
{ 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
pkgs/by-name/cp/cpu-energy-meter/package.nix
···
+
{ 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
pkgs/by-name/pq/pqos-wrapper/package.nix
···
+
{ 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";
+
};
+
}