The prior use of the UID is uninteresting in general for consumers who wants to learn things about _what_ the build is, not what is the UID of the build user running it. Achieving this with a place where a mapping between cgroup names and build requests are maintained is non trivial because there's no "global" daemon that keeps track of this information and such a daemon would require a persistent location to track this. Rather than solving that, we will just encode the derivation hash inside the cgroup name. Userspace can simply pull this apart and query Nix to obtain the original corresponding derivation for more information. This provides userspace with a way to map cgroup names to pnames for example. Going further, if you have a map between attribute paths and derivation hashes, you can power a database of cgroup metrics per attribute paths by combining all of that. In addition to this rename, we adopt a systemd-ish convention for template units (`@`). As a result, userspace tooling that will scrape cgroup metrics will discover a consistent path as long as they filter out the UID part, especially in context of Id6c458aad30eaa08c3609ac8280a7dde8e8f3cf9 change. This problem is tracked under #1073. Change-Id: I238d0568a3e4b1ff3057781c0639528d666b4d37 Signed-off-by: Raito Bezarius <raito@lix.systems>
52 lines
1.7 KiB
Nix
52 lines
1.7 KiB
Nix
{ nixpkgs, ... }:
|
|
|
|
{
|
|
name = "cgroups";
|
|
|
|
nodes =
|
|
{
|
|
host =
|
|
{ config, pkgs, ... }:
|
|
{ virtualisation.additionalPaths = [ pkgs.stdenvNoCC ];
|
|
nix.extraOptions =
|
|
''
|
|
extra-experimental-features = nix-command auto-allocate-uids cgroups
|
|
extra-system-features = uid-range
|
|
'';
|
|
nix.settings = {
|
|
download-attempts = 1;
|
|
use-cgroups = true;
|
|
};
|
|
nix.nixPath = [ "nixpkgs=${nixpkgs}" ];
|
|
};
|
|
};
|
|
|
|
testScript = { nodes }: ''
|
|
start_all()
|
|
|
|
host.wait_for_unit("multi-user.target")
|
|
|
|
# Start build in background
|
|
host.execute("nix build --use-cgroups --auto-allocate-uids --file ${./hang.nix} >&2 &")
|
|
pid = int(host.succeed("pgrep nix"))
|
|
service = "/sys/fs/cgroup/system.slice/system-nix\\\\x2ddaemon.slice/nix-daemon@*.service"
|
|
|
|
# Wait for cgroups to be created
|
|
host.succeed(f"until [ -e {service}/supervisor ]; do sleep 1; done", timeout=30)
|
|
host.succeed(f"until [ -e {service}/nix-build@* ]; do sleep 1; done", timeout=30)
|
|
|
|
# Check that there aren't processes where there shouldn't be, and that there are where there should be
|
|
host.succeed(f'[ -z "$(cat {service}/cgroup.procs)" ]')
|
|
host.succeed(f'[ -n "$(cat {service}/supervisor/cgroup.procs)" ]')
|
|
host.succeed(f'[ -n "$(cat {service}/nix-build@*/cgroup.procs)" ]')
|
|
|
|
# Perform an interrupt
|
|
host.execute(f"kill -SIGINT {pid}")
|
|
|
|
# Check that there aren't any cgroups anymore, neither any state records
|
|
host.succeed(f"until [ ! -e {service}/nix-build@* ]; do sleep 1; done", timeout=30)
|
|
host.succeed("until [ ! -e /nix/var/nix/cgroups/nix-build@* ]; do sleep 1; done", timeout=30)
|
|
'';
|
|
|
|
}
|