mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
angrr now uses TOML configuration, and also adds the ability to define profile policies. 1. Update the package itself. 2. Update the NixOS module to create, validate, and install config file. 3. Update the NixOS test of angrr to test new functionalities.
241 lines
12 KiB
Nix
241 lines
12 KiB
Nix
{ pkgs, ... }:
|
|
let
|
|
drvForTest =
|
|
name:
|
|
pkgs.runCommand "angrr-test-${name}" { } ''
|
|
mkdir --parents "$out"
|
|
echo "${name}" >"$out/${name}"
|
|
'';
|
|
in
|
|
{
|
|
name = "angrr";
|
|
nodes = {
|
|
machine = {
|
|
services.angrr = {
|
|
enable = true;
|
|
settings = {
|
|
temporary-root-policies = {
|
|
result = {
|
|
path-regex = "/result[^/]*$";
|
|
period = "7d";
|
|
};
|
|
direnv = {
|
|
path-regex = "/\\.direnv/";
|
|
period = "14d";
|
|
};
|
|
};
|
|
profile-policies = {
|
|
system = {
|
|
profile-paths = [ "/nix/var/nix/profiles/system" ];
|
|
keep-since = "7d"; # do not keep based on time
|
|
keep-latest-n = 2; # keep latest
|
|
keep-current-system = true;
|
|
keep-booted-system = true;
|
|
};
|
|
user = {
|
|
profile-paths = [
|
|
"~/.local/state/nix/profiles/profile"
|
|
"/nix/var/nix/profiles/per-user/root/profile"
|
|
];
|
|
# keep-since = "0d"; # do not keep based on time
|
|
keep-latest-n = 2;
|
|
};
|
|
};
|
|
touch = {
|
|
project-globs = [
|
|
"!result-glob-ignored"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
# `angrr.service` integrates to `nix-gc.service` by default
|
|
nix.gc.automatic = true;
|
|
|
|
# Create a normal nix user for test
|
|
users.users.normal.isNormalUser = true;
|
|
# For `nix build /run/current-system --out-link`,
|
|
# `nix-build` does not support this use case.
|
|
nix.settings.experimental-features = [ "nix-command" ];
|
|
|
|
# Test direnv integration
|
|
programs.direnv.enable = true;
|
|
# Verbose logging for angrr in direnv
|
|
environment.variables.ANGRR_DIRENV_LOG = "debug";
|
|
|
|
# Add some store paths to machine for test
|
|
environment.etc."drvs-for-test".text = ''
|
|
${drvForTest "drv1"}
|
|
${drvForTest "drv2"}
|
|
${drvForTest "drv3"}
|
|
${drvForTest "drv4"}
|
|
${drvForTest "drv5"}
|
|
${drvForTest "drv6"}
|
|
${drvForTest "drv7"}
|
|
${drvForTest "drv8"}
|
|
${drvForTest "fake-booted-system"}
|
|
'';
|
|
|
|
# Unit start limit workaround
|
|
systemd.services.angrr.unitConfig.StartLimitBurst = 10;
|
|
};
|
|
};
|
|
|
|
testScript = ''
|
|
start_all()
|
|
|
|
machine.wait_for_unit("default.target")
|
|
|
|
machine.systemctl("stop nix-gc.timer")
|
|
|
|
# Creates some auto gc roots
|
|
# Use /run/current-system so that we do not need to build anything new
|
|
machine.succeed("nix build /run/current-system --out-link /tmp/result-root-auto-gc-root-1")
|
|
machine.succeed("nix build /run/current-system --out-link /tmp/result-root-auto-gc-root-2")
|
|
machine.succeed("su normal --command 'nix build /run/current-system --out-link /tmp/result-user-auto-gc-root-1'")
|
|
machine.succeed("su normal --command 'nix build /run/current-system --out-link /tmp/result-user-auto-gc-root-2'")
|
|
|
|
machine.systemctl("start nix-gc.service")
|
|
# Not auto gc root will be removed
|
|
machine.succeed("readlink /tmp/result-root-auto-gc-root-1")
|
|
machine.succeed("readlink /tmp/result-root-auto-gc-root-2")
|
|
machine.succeed("readlink /tmp/result-user-auto-gc-root-1")
|
|
machine.succeed("readlink /tmp/result-user-auto-gc-root-2")
|
|
|
|
# Change time to 8 days after (greater than 7d)
|
|
machine.succeed("date -s '8 days'")
|
|
|
|
# Touch GC roots `-2`
|
|
machine.succeed("touch /tmp/result-root-auto-gc-root-2 --no-dereference")
|
|
machine.succeed("touch /tmp/result-user-auto-gc-root-2 --no-dereference")
|
|
|
|
machine.systemctl("start angrr.service")
|
|
# Only GC roots `-1` are removed
|
|
machine.succeed("test ! -e /tmp/result-root-auto-gc-root-1")
|
|
machine.succeed("readlink /tmp/result-root-auto-gc-root-2")
|
|
machine.succeed("test ! -e /tmp/result-user-auto-gc-root-1")
|
|
machine.succeed("readlink /tmp/result-user-auto-gc-root-2")
|
|
|
|
# Change time again
|
|
machine.succeed("date -s '8 days'")
|
|
machine.systemctl("start angrr.service")
|
|
# All auto GC roots are removed
|
|
machine.succeed("test ! -e /tmp/result-root-auto-gc-root-2")
|
|
machine.succeed("test ! -e /tmp/result-user-auto-gc-root-2")
|
|
|
|
# Direnv integration test
|
|
machine.succeed("mkdir /tmp/test-direnv")
|
|
machine.succeed("echo >/tmp/test-direnv/.envrc") # Simply create an empty .envrc
|
|
machine.succeed("nix build /run/current-system --out-link /tmp/test-direnv/.direnv/gc-root")
|
|
machine.succeed("nix build /run/current-system --out-link /tmp/test-direnv/result")
|
|
machine.succeed("cd /tmp/test-direnv; direnv allow; direnv exec . true")
|
|
|
|
# The root will be removed if we does not use the direnv recently
|
|
machine.succeed("date -s '15 days'")
|
|
machine.systemctl("start angrr.service")
|
|
machine.succeed("test ! -e /tmp/test-direnv/.direnv/gc-root")
|
|
machine.succeed("test ! -e /tmp/test-direnv/result")
|
|
|
|
# Recreate the root
|
|
machine.succeed("nix build /run/current-system --out-link /tmp/test-direnv/.direnv/gc-root")
|
|
machine.succeed("nix build /run/current-system --out-link /tmp/test-direnv/result")
|
|
machine.succeed("nix build /run/current-system --out-link /tmp/test-direnv/result-glob-ignored")
|
|
machine.succeed("nix build /run/current-system --out-link /tmp/test-outside-direnv/result")
|
|
|
|
# The root will not be remove if we use the direnv recently
|
|
machine.succeed("date -s '15 days'")
|
|
# test the case that $PWD is different from project root
|
|
machine.succeed("cd /tmp; direnv exec /tmp/test-direnv true")
|
|
machine.systemctl("start angrr.service")
|
|
machine.succeed("readlink /tmp/test-direnv/.direnv/gc-root")
|
|
machine.succeed("readlink /tmp/test-direnv/result")
|
|
machine.succeed("test ! -e /tmp/test-direnv/result-glob-ignored")
|
|
machine.succeed("test ! -e /tmp/test-outside-direnv/result")
|
|
|
|
# System profile policy test
|
|
# Create a profile for test
|
|
machine.succeed("mkdir /tmp/profile-test")
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set ${drvForTest "drv1"}") # generation 1
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set ${drvForTest "drv2"}") # generation 2
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set ${drvForTest "drv3"}") # generation 3
|
|
machine.succeed("ln --symbolic --force --no-dereference ${drvForTest "fake-booted-system"} /run/booted-system")
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set /run/booted-system") # generation 4
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set /run/current-system") # generation 5
|
|
machine.succeed("date -s '8 days'")
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set ${drvForTest "drv4"}") # generation 6
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set ${drvForTest "drv5"}") # generation 7
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set ${drvForTest "drv6"}") # generation 8
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set ${drvForTest "drv7"}") # generation 9
|
|
machine.succeed("nix-env --profile /nix/var/nix/profiles/system --set ${drvForTest "drv8"}") # generation 10
|
|
# Rollback to generation 2 to simulate current system
|
|
for _ in range(0, 10 - 2):
|
|
machine.succeed("nix-env --rollback --profile /nix/var/nix/profiles/system")
|
|
|
|
# Run policy
|
|
machine.systemctl("start angrr.service")
|
|
|
|
# Test
|
|
machine.succeed("sh -c 'test $(readlink /nix/var/nix/profiles/system) = system-2-link'")
|
|
machine.succeed("test ! -e /nix/var/nix/profiles/system-1-link")
|
|
machine.succeed("readlink /nix/var/nix/profiles/system-2-link") # Keep since it is current generation
|
|
machine.succeed("test ! -e /nix/var/nix/profiles/system-3-link")
|
|
machine.succeed("readlink /nix/var/nix/profiles/system-4-link") # Keep by keep-booted-system
|
|
machine.succeed("readlink /nix/var/nix/profiles/system-5-link") # Keep by keep-current-system
|
|
machine.succeed("readlink /nix/var/nix/profiles/system-6-link") # Keep by keep-since
|
|
machine.succeed("readlink /nix/var/nix/profiles/system-7-link") # Keep by keep-since
|
|
machine.succeed("readlink /nix/var/nix/profiles/system-8-link") # Keep by keep-since
|
|
machine.succeed("readlink /nix/var/nix/profiles/system-9-link") # Keep by keep-latest-n
|
|
machine.succeed("readlink /nix/var/nix/profiles/system-10-link") # Keep by keep-latest-n
|
|
|
|
# User profile policy test 1
|
|
# Normal user
|
|
machine.succeed("su normal --command 'nix profile add ${drvForTest "drv1"}'")
|
|
machine.succeed("su normal --command 'nix profile add ${drvForTest "drv2"}'")
|
|
machine.succeed("su normal --command 'nix profile add ${drvForTest "drv3"}'")
|
|
# Root user
|
|
machine.succeed("nix profile add ${drvForTest "drv1"}")
|
|
machine.succeed("nix profile add ${drvForTest "drv2"}")
|
|
machine.succeed("nix profile add ${drvForTest "drv3"}")
|
|
|
|
# Run policy
|
|
machine.systemctl("start angrr.service")
|
|
|
|
# Test
|
|
machine.succeed("sh -c 'test $(readlink ~normal/.local/state/nix/profiles/profile) = profile-3-link'")
|
|
machine.succeed("test ! -e ~normal/.local/state/nix/profiles/profile-1-link")
|
|
machine.succeed("readlink ~normal/.local/state/nix/profiles/profile-2-link") # Keep by keep-latest-n
|
|
machine.succeed("readlink ~normal/.local/state/nix/profiles/profile-3-link") # Keep since it is current generation
|
|
machine.succeed("sh -c 'test $(readlink /nix/var/nix/profiles/per-user/root/profile) = profile-3-link'")
|
|
machine.succeed("test ! -e /nix/var/nix/profiles/per-user/root/profile-1-link")
|
|
machine.succeed("readlink /nix/var/nix/profiles/per-user/root/profile-2-link") # Keep by keep-latest-n
|
|
machine.succeed("readlink /nix/var/nix/profiles/per-user/root/profile-3-link") # Keep since it is current generation
|
|
|
|
# User profile policy test 2
|
|
# Create GC roots again
|
|
machine.succeed("su normal --command 'nix profile add ${drvForTest "drv1"}'")
|
|
machine.succeed("su normal --command 'nix profile add ${drvForTest "drv2"}'")
|
|
machine.succeed("su normal --command 'nix profile add ${drvForTest "drv3"}'")
|
|
machine.succeed("nix profile add ${drvForTest "drv1"}")
|
|
machine.succeed("nix profile add ${drvForTest "drv2"}")
|
|
machine.succeed("nix profile add ${drvForTest "drv3"}")
|
|
|
|
# Run policy in owned-only mode as normal user
|
|
machine.succeed("su normal --command 'angrr run --no-prompt'")
|
|
|
|
# Test
|
|
machine.succeed("sh -c 'test $(readlink ~normal/.local/state/nix/profiles/profile) = profile-6-link'")
|
|
machine.succeed("test ! -e ~normal/.local/state/nix/profiles/profile-1-link")
|
|
machine.succeed("test ! -e ~normal/.local/state/nix/profiles/profile-2-link")
|
|
machine.succeed("test ! -e ~normal/.local/state/nix/profiles/profile-3-link")
|
|
machine.succeed("test ! -e ~normal/.local/state/nix/profiles/profile-4-link")
|
|
machine.succeed("readlink ~normal/.local/state/nix/profiles/profile-5-link") # Keep by keep-latest-n
|
|
machine.succeed("readlink ~normal/.local/state/nix/profiles/profile-6-link") # Keep since it is current generation
|
|
machine.succeed("sh -c 'test $(readlink /nix/var/nix/profiles/per-user/root/profile) = profile-6-link'")
|
|
machine.succeed("test ! -e /nix/var/nix/profiles/per-user/root/profile-1-link")
|
|
machine.succeed("readlink /nix/var/nix/profiles/per-user/root/profile-2-link")
|
|
machine.succeed("readlink /nix/var/nix/profiles/per-user/root/profile-3-link")
|
|
machine.succeed("readlink /nix/var/nix/profiles/per-user/root/profile-4-link") # Not monitored
|
|
machine.succeed("readlink /nix/var/nix/profiles/per-user/root/profile-5-link") # Not monitored
|
|
machine.succeed("readlink /nix/var/nix/profiles/per-user/root/profile-6-link") # Not monitored
|
|
'';
|
|
}
|