nixos/benchexec: init

This commit is contained in:
Lorenz Leutgeb 2024-05-17 21:19:41 +02:00
parent 0e2c447486
commit 88d736df69
4 changed files with 154 additions and 0 deletions

View File

@ -158,6 +158,7 @@
./programs/bash/ls-colors.nix ./programs/bash/ls-colors.nix
./programs/bash/undistract-me.nix ./programs/bash/undistract-me.nix
./programs/bcc.nix ./programs/bcc.nix
./programs/benchexec.nix
./programs/browserpass.nix ./programs/browserpass.nix
./programs/calls.nix ./programs/calls.nix
./programs/captive-browser.nix ./programs/captive-browser.nix

View File

@ -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 ];
}

View File

@ -144,6 +144,7 @@ in {
bcachefs = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bcachefs.nix {}; bcachefs = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bcachefs.nix {};
beanstalkd = handleTest ./beanstalkd.nix {}; beanstalkd = handleTest ./beanstalkd.nix {};
bees = handleTest ./bees.nix {}; bees = handleTest ./bees.nix {};
benchexec = handleTest ./benchexec.nix {};
binary-cache = handleTest ./binary-cache.nix {}; binary-cache = handleTest ./binary-cache.nix {};
bind = handleTest ./bind.nix {}; bind = handleTest ./bind.nix {};
bird = handleTest ./bird.nix {}; bird = handleTest ./bird.nix {};

54
nixos/tests/benchexec.nix Normal file
View File

@ -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; }];
};
})