aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/configuration.nix252
-rw-r--r--test/default.nix81
-rw-r--r--test/flake.lock49
-rw-r--r--test/flake.nix255
-rw-r--r--test/hsu.nix23
-rw-r--r--test/interactive/configuration.nix68
-rw-r--r--test/interactive/hakurei.nix47
-rw-r--r--test/interactive/raceattr.nix30
-rw-r--r--test/interactive/trace.nix35
-rw-r--r--test/interactive/vm.nix56
-rw-r--r--test/internal/sandbox/assert.go272
-rw-r--r--test/internal/sandbox/assert_test.go34
-rw-r--r--test/internal/sandbox/fs.go102
-rw-r--r--test/internal/sandbox/fs_test.go80
-rw-r--r--test/internal/sandbox/mount.go159
-rw-r--r--test/internal/sandbox/mount_test.go144
-rw-r--r--test/internal/sandbox/ptrace.go87
-rw-r--r--test/internal/sandbox/seccomp.go44
-rw-r--r--test/nixos.nix407
-rw-r--r--test/options.md1175
-rw-r--r--test/options.nix364
-rw-r--r--test/package.nix144
-rw-r--r--test/sandbox/case/default.nix97
-rw-r--r--test/sandbox/case/device.nix255
-rw-r--r--test/sandbox/case/mapuid.nix282
-rw-r--r--test/sandbox/case/pd.nix206
-rw-r--r--test/sandbox/case/pdlike.nix277
-rw-r--r--test/sandbox/case/preset.nix274
-rw-r--r--test/sandbox/case/tty.nix288
-rw-r--r--test/sandbox/configuration.nix113
-rw-r--r--test/sandbox/default.nix41
-rw-r--r--test/sandbox/test.py88
-rw-r--r--test/sandbox/tool/main.go106
-rw-r--r--test/sandbox/tool/package.nix32
-rw-r--r--test/sharefs/configuration.nix44
-rw-r--r--test/sharefs/default.nix44
-rw-r--r--test/sharefs/raceattr.go122
-rw-r--r--test/sharefs/test.py60
-rw-r--r--test/test.py315
39 files changed, 0 insertions, 6552 deletions
diff --git a/test/configuration.nix b/test/configuration.nix
deleted file mode 100644
index 62d8239d..00000000
--- a/test/configuration.nix
+++ /dev/null
@@ -1,252 +0,0 @@
-{
- lib,
- pkgs,
- config,
- ...
-}:
-{
- users.users = {
- alice = {
- isNormalUser = true;
- description = "Alice Foobar";
- password = "foobar";
- uid = 1000;
- };
- untrusted = {
- isNormalUser = true;
- description = "Untrusted user";
- password = "foobar";
- uid = 1001;
-
- # For deny unmapped uid test:
- packages = [ config.environment.hakurei.package ];
- };
- };
-
- home-manager.users.alice.home.stateVersion = "24.11";
-
- # Automatically login on tty1 as a normal user:
- services.getty.autologinUser = "alice";
-
- security.pam.loginLimits = [
- {
- domain = "@users";
- item = "rtprio";
- type = "-";
- value = 1;
- }
- ];
-
- environment = {
- systemPackages = with pkgs; [
- # For D-Bus tests:
- mako
- libnotify
- ];
-
- variables = {
- SWAYSOCK = "/tmp/sway-ipc.sock";
- WLR_RENDERER = "pixman";
- };
-
- # To help with OCR:
- etc."xdg/foot/foot.ini".text = lib.generators.toINI { } {
- main = {
- font = "inconsolata:size=14";
- };
- colors = rec {
- foreground = "000000";
- background = "ffffff";
- regular2 = foreground;
- };
- };
- };
-
- fonts.packages = [ pkgs.inconsolata ];
-
- # Automatically configure and start Sway when logging in on tty1:
- programs.bash.loginShellInit = ''
- if [ "$(tty)" = "/dev/tty1" ]; then
- set -e
-
- mkdir -p ~/.config/sway
- (sed s/Mod4/Mod1/ /etc/sway/config &&
- echo 'output * bg ${pkgs.nixos-artwork.wallpapers.simple-light-gray.gnomeFilePath} fill' &&
- echo 'output Virtual-1 res 1680x1050') > ~/.config/sway/config
-
- sway --validate
- systemd-cat --identifier=session sway && touch /tmp/sway-exit-ok
- fi
- '';
-
- programs.sway.enable = true;
-
- # For PulseAudio tests:
- security.rtkit.enable = true;
- services.pipewire = {
- enable = true;
- alsa.enable = true;
- alsa.support32Bit = true;
- pulse.enable = true;
- jack.enable = true;
- };
-
- virtualisation = {
- # Hopefully reduces spurious test failures:
- memorySize = if pkgs.stdenv.hostPlatform.is32bit then 2046 else 8192;
-
- qemu.options = [
- # Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch:
- "-vga none -device virtio-gpu-pci"
-
- # Increase Go test compiler performance:
- "-smp 16"
- ];
- };
-
- # Disk image is too small for some tests:
- boot.tmp.useTmpfs = true;
-
- environment.hakurei = {
- enable = true;
- stateDir = "/var/lib/hakurei";
- users.alice = 0;
-
- extraHomeConfig =
- { config, ... }:
- {
- # To test merge deduplication:
- options._hakurei.stateVersion = lib.mkOption { type = lib.types.str; };
-
- config = {
- home = { inherit (config._hakurei) stateVersion; };
- _hakurei.stateVersion = "23.05";
- };
- };
-
- commonPaths = [
- {
- type = "bind";
- src = "/var/tmp";
- write = true;
- }
- ];
-
- apps = {
- "cat.gensokyo.extern.bash.linger-timeout" = {
- name = "hakurei-check-linger-timeout";
- identity = 9999;
- share = pkgs.bash;
- packages = [ pkgs.bash ];
- command = ''
- sleep infinity & disown
- exit
- '';
- wait_delay = 1;
- enablements = {
- wayland = false;
- pipewire = false;
- };
- };
-
- "cat.gensokyo.extern.foot.noEnablements" = {
- name = "ne-foot";
- identity = 1;
- shareUid = true;
- verbose = true;
- share = pkgs.foot;
- packages = with pkgs; [
- foot
-
- # For wayland-info:
- wayland-utils
- ];
- command = "foot";
- enablements = {
- dbus = false;
- pipewire = false;
- };
- };
-
- "cat.gensokyo.extern.foot.noEnablements.immediate" = {
- name = "ne-foot-immediate";
- identity = 1;
- shareUid = true;
- verbose = true;
- wait_delay = -1;
- share = pkgs.foot;
- packages = [ ];
- command = "foot";
- enablements = {
- dbus = false;
- pipewire = false;
- };
- };
-
- "cat.gensokyo.extern.foot.pulseaudio" = {
- name = "pa-foot";
- identity = 2;
- verbose = true;
- share = pkgs.foot;
- packages = [ pkgs.foot ];
- command = "foot";
- enablements.dbus = false;
- };
-
- "cat.gensokyo.extern.Alacritty.x11" = {
- name = "x11-alacritty";
- identity = 1;
- shareUid = true;
- verbose = true;
- share = pkgs.alacritty;
- packages = with pkgs; [
- # For X11 terminal emulator:
- alacritty
-
- # For glinfo:
- mesa-demos
- ];
- command = "alacritty";
- enablements = {
- wayland = false;
- x11 = true;
- dbus = false;
- pipewire = false;
- };
- };
-
- "cat.gensokyo.extern.foot.directWayland" = {
- name = "da-foot";
- identity = 4;
- verbose = true;
- insecureWayland = true;
- share = pkgs.foot;
- packages = with pkgs; [
- foot
-
- # For wayland-info:
- wayland-utils
- ];
- command = "foot";
- enablements = {
- dbus = false;
- pipewire = false;
- };
- };
-
- "cat.gensokyo.extern.strace.wantFail" = {
- name = "strace-failure";
- identity = 5;
- verbose = true;
- share = pkgs.strace;
- command = "strace true";
- enablements = {
- wayland = false;
- x11 = false;
- dbus = false;
- pipewire = false;
- };
- };
- };
- };
-}
diff --git a/test/default.nix b/test/default.nix
deleted file mode 100644
index 81daa0a2..00000000
--- a/test/default.nix
+++ /dev/null
@@ -1,81 +0,0 @@
-{
- lib,
- testers,
- buildFHSEnv,
- writeShellScriptBin,
-
- system,
- self,
- withRace ? false,
-}:
-
-testers.nixosTest {
- name = "hakurei" + (if withRace then "-race" else "");
- nodes.machine =
- { options, pkgs, ... }:
- let
- fhs =
- let
- hakurei = options.environment.hakurei.package.default;
- in
- buildFHSEnv {
- pname = "hakurei-fhs";
- inherit (hakurei) version;
- targetPkgs = _: hakurei.targetPkgs;
- extraOutputsToInstall = [ "dev" ];
- profile = ''
- export PKG_CONFIG_PATH="/usr/share/pkgconfig:$PKG_CONFIG_PATH"
- '';
- };
- in
- {
- environment.systemPackages = [
- # For go tests:
- (writeShellScriptBin "hakurei-test" ''
- # Assert hst CGO_ENABLED=0: ${
- with pkgs;
- runCommand "hakurei-hst-cgo" { nativeBuildInputs = [ self.packages.${system}.hakurei.go ]; } ''
- cp -r ${options.environment.hakurei.package.default.src} "$out"
- chmod -R +w "$out"
- cp ${writeText "hst_cgo_test.go" ''package hakurei_test;import("testing";"hakurei.app/hst");func TestTemplate(t *testing.T){hst.Template()}''} "$out/hst_cgo_test.go"
- (cd "$out" && HOME="$(mktemp -d)" CGO_ENABLED=0 go test .)
- ''
- }
-
- cd ${self.packages.${system}.hakurei.src}
- ${fhs}/bin/hakurei-fhs -c \
- 'CC="clang -O3 -Werror" go test --tags=noskip ${if withRace then "-race" else "-count 16"} ./...' \
- &> /tmp/hakurei-test.log && \
- touch /tmp/hakurei-test-ok
- touch /tmp/hakurei-test-done
- '')
- ];
-
- # Run with Go race detector:
- environment.hakurei = lib.mkIf withRace rec {
- # race detector does not support static linking
- package = (pkgs.callPackage ./package.nix { }).overrideAttrs (previousAttrs: {
- env = previousAttrs.env // {
- GOFLAGS = previousAttrs.env.GOFLAGS + " -race";
- };
- });
- hsuPackage = options.environment.hakurei.hsuPackage.default.override { hakurei = package; };
- };
-
- imports = [
- ./configuration.nix
-
- self.nixosModules.hakurei
- self.inputs.home-manager.nixosModules.home-manager
- ];
- };
-
- # adapted from nixos sway integration tests
-
- # testScriptWithTypes:49: error: Cannot call function of unknown type
- # (machine.succeed if succeed else machine.execute)(
- # ^
- # Found 1 error in 1 file (checked 1 source file)
- skipTypeCheck = true;
- testScript = builtins.readFile ./test.py;
-}
diff --git a/test/flake.lock b/test/flake.lock
deleted file mode 100644
index 5537506a..00000000
--- a/test/flake.lock
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "nodes": {
- "home-manager": {
- "inputs": {
- "nixpkgs": [
- "nixpkgs"
- ]
- },
- "locked": {
- "lastModified": 1787146702,
- "narHash": "sha256-YbRcLdU/yK4gWsQg7V8WTKZHfXL33g8+wSFUX3wyevs=",
- "owner": "nix-community",
- "repo": "home-manager",
- "rev": "173b7e8d40fdc8c296a9c99854314f17a3a1704c",
- "type": "github"
- },
- "original": {
- "owner": "nix-community",
- "ref": "release-26.05",
- "repo": "home-manager",
- "type": "github"
- }
- },
- "nixpkgs": {
- "locked": {
- "lastModified": 1787101114,
- "narHash": "sha256-gwrPcFf/rDjHPaVflbDZ040ZDmBTRj/7+s8ZmE2SaIM=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "b18a4b905f8d028dc4476412e6d6891728695379",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixos-26.05",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "root": {
- "inputs": {
- "home-manager": "home-manager",
- "nixpkgs": "nixpkgs"
- }
- }
- },
- "root": "root",
- "version": 7
-}
diff --git a/test/flake.nix b/test/flake.nix
deleted file mode 100644
index 01a07f78..00000000
--- a/test/flake.nix
+++ /dev/null
@@ -1,255 +0,0 @@
-{
- description = "hakurei container tool and nixos module";
-
- inputs = {
- nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
-
- home-manager = {
- url = "github:nix-community/home-manager/release-26.05";
- inputs.nixpkgs.follows = "nixpkgs";
- };
- };
-
- outputs =
- {
- self,
- nixpkgs,
- home-manager,
- }:
- let
- supportedSystems = [
- "aarch64-linux"
- "i686-linux"
- "x86_64-linux"
- ];
-
- forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
- nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
- in
- {
- nixosModules.hakurei = import ./nixos.nix self.packages;
-
- checks = forAllSystems (
- system:
- let
- pkgs = nixpkgsFor.${system};
-
- inherit (pkgs)
- runCommandLocal
- callPackage
- nixfmt
- deadnix
- statix
- ;
- in
- {
- hakurei = callPackage ./. { inherit system self; };
- race = callPackage ./. {
- inherit system self;
- withRace = true;
- };
-
- sandbox = callPackage ./sandbox { inherit self; };
- sandbox-race = callPackage ./sandbox {
- inherit self;
- withRace = true;
- };
-
- sharefs = callPackage ./sharefs { inherit system self; };
-
- formatting = runCommandLocal "check-formatting" { nativeBuildInputs = [ nixfmt ]; } ''
- cd ${./.}
-
- echo "running nixfmt..."
- nixfmt --width=256 --check .
-
- touch $out
- '';
-
- lint =
- runCommandLocal "check-lint"
- {
- nativeBuildInputs = [
- deadnix
- statix
- ];
- }
- ''
- cd ${./.}
-
- echo "running deadnix..."
- deadnix --fail
-
- echo "running statix..."
- statix check .
-
- touch $out
- '';
- }
- );
-
- packages = forAllSystems (
- system:
- let
- inherit (self.packages.${system}) hakurei hsu;
- pkgs = nixpkgsFor.${system};
- in
- {
- default = hakurei;
- hakurei = pkgs.pkgsStatic.callPackage ./package.nix {
- inherit (pkgs)
- # passthru.buildInputs
- go_1_27
- clang
-
- # nativeBuildInputs
- pkg-config
- wayland-scanner
- makeBinaryWrapper
-
- # appPackages
- glibc
- xdg-dbus-proxy
-
- # for check
- util-linux
- nettools
- ;
- };
- hsu = pkgs.callPackage ./hsu.nix { inherit (self.packages.${system}) hakurei; };
- sharefs = pkgs.linkFarm "sharefs" {
- "bin/sharefs" = "${hakurei}/libexec/sharefs";
- "bin/mount.fuse.sharefs" = "${hakurei}/libexec/sharefs";
- };
-
- dist =
- pkgs.runCommand "${hakurei.name}-dist"
- {
- buildInputs = hakurei.targetPkgs ++ [
- pkgs.pkgsStatic.musl
- ];
- }
- ''
- cd $(mktemp -d) \
- && cp -r ${hakurei.src}/. . \
- && chmod +w cmd && cp -r ${hsu.src}/. cmd/hsu/ \
- && chmod -R +w .
-
- CC="musl-clang -O3 -Werror -Qunused-arguments" \
- GOCACHE="$(mktemp -d)" \
- PATH="${pkgs.pkgsStatic.musl.bin}/bin:$PATH" \
- DESTDIR="$out" \
- ./all.sh
- '';
- }
- );
-
- devShells = forAllSystems (
- system:
- let
- inherit (self.packages.${system}) hakurei;
- pkgs = nixpkgsFor.${system};
- in
- {
- default = pkgs.mkShell {
- buildInputs = hakurei.targetPkgs;
- hardeningDisable = [ "fortify" ];
- };
- withPackage = pkgs.mkShell { buildInputs = [ hakurei ] ++ hakurei.targetPkgs; };
-
- vm =
- let
- nixos = nixpkgs.lib.nixosSystem {
- inherit system;
- modules = [
- {
- environment = {
- systemPackages = [
- (pkgs.buildFHSEnv {
- pname = "hakurei-fhs";
- inherit (hakurei) version;
- targetPkgs = _: hakurei.targetPkgs;
- extraOutputsToInstall = [ "dev" ];
- profile = ''
- export PKG_CONFIG_PATH="/usr/share/pkgconfig:$PKG_CONFIG_PATH"
- '';
- })
- ];
-
- hakurei =
- let
- # this is used for interactive vm testing during development, where tests might be broken
- package = self.packages.${pkgs.stdenv.hostPlatform.system}.hakurei.override {
- buildGo127Module = previousArgs: pkgs.pkgsStatic.buildGo127Module (previousArgs // { doCheck = false; });
- };
- in
- {
- inherit package;
- hsuPackage = self.packages.${pkgs.stdenv.hostPlatform.system}.hsu.override { hakurei = package; };
- };
- };
- }
-
- ./interactive/configuration.nix
- ./interactive/vm.nix
- ./interactive/hakurei.nix
- ./interactive/trace.nix
- ./interactive/raceattr.nix
-
- self.nixosModules.hakurei
- home-manager.nixosModules.home-manager
- ];
- };
- in
- pkgs.mkShell {
- buildInputs = [ nixos.config.system.build.vm ];
- shellHook = "exec run-nixos-vm $@";
- };
-
- generateDoc =
- let
- inherit (pkgs) lib;
-
- doc =
- let
- eval = lib.evalModules {
- specialArgs = {
- inherit pkgs;
- };
- modules = [ (import ./options.nix self.packages) ];
- };
- cleanEval = lib.filterAttrsRecursive (n: _: n != "_module") eval;
- in
- pkgs.nixosOptionsDoc { inherit (cleanEval) options; };
- docText = pkgs.runCommand "hakurei-module-docs.md" { } ''
- cat ${doc.optionsCommonMark} > $out
- sed -i '/*Declared by:*/,+1 d' $out
- '';
- in
- pkgs.mkShell {
- shellHook = ''
- exec cat ${docText} > options.md
- '';
- };
-
- generateSyscallTable =
- let
- GOARCH = {
- x86_64-linux = "amd64";
- aarch64-linux = "arm64";
- };
- in
- pkgs.mkShell {
- shellHook = "exec ${pkgs.writeShellScript "generate-syscall-table" ''
- set -e
- ${pkgs.perl}/bin/perl \
- container/std/mksysnum_linux.pl \
- ${pkgs.linuxHeaders}/include/asm/unistd_64.h | \
- ${pkgs.go}/bin/gofmt > \
- container/std/syscall_linux_${GOARCH.${system}}.go
- ''}";
- };
- }
- );
- };
-}
diff --git a/test/hsu.nix b/test/hsu.nix
deleted file mode 100644
index 7acb3529..00000000
--- a/test/hsu.nix
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- lib,
- buildGoModule,
- hakurei ? abort "hakurei package required",
-}:
-
-buildGoModule {
- pname = "${hakurei.pname}-hsu";
- inherit (hakurei) version;
-
- src = ../cmd/hsu;
- inherit (hakurei) vendorHash;
- env.CGO_ENABLED = 0;
-
- preBuild = ''
- go mod init hsu >& /dev/null
- '';
-
- ldflags = lib.attrsets.foldlAttrs (
- ldflags: name: value:
- ldflags ++ [ "-X main.${name}=${value}" ]
- ) [ "-s -w" ] { hakureiPath = "${hakurei}/libexec/hakurei"; };
-}
diff --git a/test/interactive/configuration.nix b/test/interactive/configuration.nix
deleted file mode 100644
index 9d1bddd8..00000000
--- a/test/interactive/configuration.nix
+++ /dev/null
@@ -1,68 +0,0 @@
-{ pkgs, ... }:
-{
- system.stateVersion = "23.05";
-
- users.users = {
- alice = {
- isNormalUser = true;
- description = "Alice Foobar";
- password = "foobar";
- uid = 1000;
- extraGroups = [ "wheel" ];
- };
- untrusted = {
- isNormalUser = true;
- description = "Untrusted user";
- password = "foobar";
- uid = 1001;
- };
- };
-
- home-manager.users.alice.home.stateVersion = "24.11";
-
- security = {
- sudo.wheelNeedsPassword = false;
- rtkit.enable = true;
- pam.loginLimits = [
- {
- domain = "@users";
- item = "rtprio";
- type = "-";
- value = 1;
- }
- ];
- };
-
- services = {
- getty.autologinUser = "alice";
- pipewire = {
- enable = true;
- alsa.enable = true;
- alsa.support32Bit = true;
- pulse.enable = true;
- jack.enable = true;
- };
- };
-
- environment.variables = {
- SWAYSOCK = "/tmp/sway-ipc.sock";
- WLR_RENDERER = "pixman";
- };
-
- programs = {
- sway.enable = true;
-
- bash.loginShellInit = ''
- if [ "$(tty)" = "/dev/tty1" ]; then
- set -e
-
- mkdir -p ~/.config/sway
- (sed s/Mod4/Mod1/ /etc/sway/config &&
- echo 'output * bg ${pkgs.nixos-artwork.wallpapers.simple-light-gray.gnomeFilePath} fill') > ~/.config/sway/config
-
- sway --validate
- systemd-cat --identifier=session sway && touch /tmp/sway-exit-ok
- fi
- '';
- };
-}
diff --git a/test/interactive/hakurei.nix b/test/interactive/hakurei.nix
deleted file mode 100644
index ef5d0ada..00000000
--- a/test/interactive/hakurei.nix
+++ /dev/null
@@ -1,47 +0,0 @@
-{ pkgs, ... }:
-{
- environment.hakurei = rec {
- enable = true;
- stateDir = "/var/lib/hakurei";
- sharefs.source = "${stateDir}/sdcard";
- users.alice = 0;
- apps = {
- "cat.gensokyo.extern.foot.noEnablements" = {
- name = "ne-foot";
- identity = 1;
- shareUid = true;
- verbose = true;
- share = pkgs.foot;
- packages = [ pkgs.foot ];
- command = "foot";
- enablements = {
- dbus = false;
- pipewire = false;
- };
- };
-
- "cat.gensokyo.extern.foot.badDaemon" = {
- name = "bd-foot";
- identity = 1;
- shareUid = true;
- verbose = true;
- share = pkgs.foot;
- packages = [ pkgs.foot ];
- command = "foot";
- enablements = {
- dbus = false;
- };
- extraPaths = [
- {
- type = "daemon";
- dst = "/proc/nonexistent";
- path = "/usr/bin/env";
- args = [ "false" ];
- }
- ];
- };
- };
-
- extraHomeConfig.home.stateVersion = "23.05";
- };
-}
diff --git a/test/interactive/raceattr.nix b/test/interactive/raceattr.nix
deleted file mode 100644
index de54f4cf..00000000
--- a/test/interactive/raceattr.nix
+++ /dev/null
@@ -1,30 +0,0 @@
-{ lib, pkgs, ... }:
-{
- security.wrappers.raceattr =
- let
- inherit (pkgs) buildGoModule;
- in
- {
- setuid = true;
- owner = "root";
- group = "root";
- source = "${
- (buildGoModule rec {
- name = "raceattr";
- pname = name;
- tags = [ "raceattr" ];
-
- src = builtins.path {
- name = "${pname}-src";
- path = lib.cleanSource ../sharefs;
- filter = path: type: (type == "directory") || (type == "regular" && lib.hasSuffix ".go" path);
- };
- vendorHash = null;
-
- preBuild = ''
- go mod init hakurei.app/raceattr >& /dev/null
- '';
- })
- }/bin/raceattr";
- };
-}
diff --git a/test/interactive/trace.nix b/test/interactive/trace.nix
deleted file mode 100644
index b9ef872c..00000000
--- a/test/interactive/trace.nix
+++ /dev/null
@@ -1,35 +0,0 @@
-{ lib, pkgs, ... }:
-let
- tracing = name: "\"/sys/kernel/debug/tracing/${name}\"";
-in
-{
- environment.systemPackages = [
- (pkgs.writeShellScriptBin "hakurei-set-up-tracing" ''
- set -e
- echo "$1" > ${tracing "set_graph_function"}
- echo function_graph > ${tracing "current_tracer"}
- echo funcgraph-tail > ${tracing "trace_options"}
- echo funcgraph-retval > ${tracing "trace_options"}
- echo nofuncgraph-cpu > ${tracing "trace_options"}
- echo nofuncgraph-overhead > ${tracing "trace_options"}
- echo nofuncgraph-duration > ${tracing "trace_options"}
- '')
- (pkgs.writeShellScriptBin "hakurei-print-trace" "exec cat ${tracing "trace"}")
- (pkgs.writeShellScriptBin "hakurei-consume-trace" "exec cat ${tracing "trace_pipe"}")
- ];
-
- boot.kernelPatches = [
- {
- name = "funcgraph-retval";
- patch = null;
- structuredExtraConfig = with lib.kernel; {
- FUNCTION_GRAPH_RETVAL = yes;
-
- RUST = lib.mkForce unset;
- DRM_NOVA = lib.mkForce unset;
- DRM_PANIC_SCREEN_QR_CODE = lib.mkForce unset;
- NOVA_CORE = lib.mkForce unset;
- };
- }
- ];
-}
diff --git a/test/interactive/vm.nix b/test/interactive/vm.nix
deleted file mode 100644
index 522878e9..00000000
--- a/test/interactive/vm.nix
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- virtualisation.vmVariant.virtualisation = {
- memorySize = 4096;
- qemu.options = [
- "-vga none -device virtio-gpu-pci"
- "-smp 8"
- ];
-
- mountHostNixStore = true;
- writableStore = true;
- writableStoreUseTmpfs = false;
-
- sharedDirectories = {
- cwd = {
- target = "/mnt/.ro-cwd";
- source = ''"$OLDPWD"'';
- securityModel = "none";
- };
- };
-
- fileSystems = {
- "/mnt/.ro-cwd".options = [
- "ro"
- "noatime"
- ];
- "/mnt/cwd".overlay = {
- lowerdir = [ "/mnt/.ro-cwd" ];
- upperdir = "/tmp/.cwd/upper";
- workdir = "/tmp/.cwd/work";
- };
-
- "/mnt/src".overlay = {
- lowerdir = [ ../.. ];
- upperdir = "/tmp/.src/upper";
- workdir = "/tmp/.src/work";
- };
- };
- };
-
- systemd.services = {
- logrotate-checkconf.enable = false;
- hakurei-src-fix-ownership = {
- wantedBy = [ "multi-user.target" ];
- wants = [ "mnt-src.mount" ];
- after = [ "mnt-src.mount" ];
- serviceConfig = {
- Type = "oneshot";
- RemainAfterExit = true;
- };
- script = ''
- chown -R alice:users /mnt/src/
- chmod -R +w /mnt/src/
- '';
- };
- };
-}
diff --git a/test/internal/sandbox/assert.go b/test/internal/sandbox/assert.go
deleted file mode 100644
index e6fe926b..00000000
--- a/test/internal/sandbox/assert.go
+++ /dev/null
@@ -1,272 +0,0 @@
-//go:build testtool
-
-// Package sandbox provides utilities for checking sandbox outcome.
-//
-// This package must never be used outside integration tests, there is a much
-// better native implementation of mountinfo in the public sandbox/vfs package.
-// Files in this package are excluded by the build system to prevent accidental
-// misuse.
-package sandbox
-
-import (
- "crypto/sha512"
- "encoding/hex"
- "encoding/json"
- "errors"
- "io/fs"
- "log"
- "net"
- "os"
- "path/filepath"
- "syscall"
-)
-
-var (
- assert = log.New(os.Stderr, "sandbox: ", 0)
- printfFunc = assert.Printf
- fatalfFunc = assert.Fatalf
-)
-
-func printf(format string, v ...any) { printfFunc(format, v...) }
-func fatalf(format string, v ...any) { fatalfFunc(format, v...) }
-
-type TestCase struct {
- Env []string `json:"env"`
- FS *FS `json:"fs"`
- Mount []*MountinfoEntry `json:"mount"`
- Seccomp bool `json:"seccomp"`
-
- TrySocket string `json:"try_socket,omitempty"`
- SocketAbstract bool `json:"socket_abstract,omitempty"`
- SocketPathname bool `json:"socket_pathname,omitempty"`
-}
-
-type T struct {
- FS fs.FS
-
- MountsPath string
-}
-
-func (t *T) MustCheckFile(wantFilePath string) {
- var want *TestCase
- mustDecode(wantFilePath, &want)
- t.MustCheck(want)
-}
-
-func mustAbs(s string) string {
- if !filepath.IsAbs(s) {
- fatalf("[FAIL] %q is not absolute", s)
- panic("unreachable")
- }
- return s
-}
-
-func (t *T) MustCheck(want *TestCase) {
- checkWritableDirPaths := []string{
- "/dev/shm",
- "/tmp",
- os.Getenv("XDG_RUNTIME_DIR"),
- }
- for _, a := range checkWritableDirPaths {
- pathname := filepath.Join(mustAbs(a), ".hakurei-check")
- if err := os.WriteFile(pathname, make([]byte, 1<<8), 0600); err != nil {
- fatalf("[FAIL] %s", err)
- } else if err = os.Remove(pathname); err != nil {
- fatalf("[FAIL] %s", err)
- } else {
- printf("[ OK ] %s is writable", a)
- }
- }
-
- if want.Env != nil {
- var (
- fail bool
- i int
- got string
- )
- for i, got = range os.Environ() {
- if i == len(want.Env) {
- fatalf("got more than %d environment variables", len(want.Env))
- }
- if got != want.Env[i] {
- fail = true
- printf("[FAIL] %s", got)
- } else {
- printf("[ OK ] %s", got)
- }
- }
-
- i++
- if i != len(want.Env) {
- fatalf("got %d environment variables, want %d", i, len(want.Env))
- }
-
- if fail {
- fatalf("[FAIL] some environment variables did not match")
- }
- } else {
- printf("[SKIP] skipping environ check")
- }
-
- if want.FS != nil && t.FS != nil {
- if err := want.FS.Compare(".", t.FS); err != nil {
- fatalf("%v", err)
- }
- } else {
- printf("[SKIP] skipping fs check")
- }
-
- if want.Mount != nil {
- var fail bool
- m := mustParseMountinfo(t.MountsPath)
- i := 0
- for ent := range m.Entries() {
- if i == len(want.Mount) {
- fatalf("got more than %d entries", i)
- }
- if !ent.EqualWithIgnore(want.Mount[i], "//ignore") {
- fail = true
- printf("[FAIL] %s", ent)
- } else {
- printf("[ OK ] %s", ent)
- }
-
- i++
- }
- if err := m.Err(); err != nil {
- fatalf("%v", err)
- }
-
- if i != len(want.Mount) {
- fatalf("got %d entries, want %d", i, len(want.Mount))
- }
-
- if fail {
- fatalf("[FAIL] some mount points did not match")
- }
- } else {
- printf("[SKIP] skipping mounts check")
- }
-
- if want.Seccomp {
- if trySyscalls() != nil {
- os.Exit(1)
- }
- } else {
- printf("[SKIP] skipping seccomp check")
- }
-
- if want.TrySocket != "" {
- abstractConn, abstractErr := net.Dial("unix", "@"+want.TrySocket)
- pathnameConn, pathnameErr := net.Dial("unix", want.TrySocket)
- ok := true
-
- if abstractErr == nil {
- if err := abstractConn.Close(); err != nil {
- ok = false
- log.Printf("Close: %v", err)
- }
- }
- if pathnameErr == nil {
- if err := pathnameConn.Close(); err != nil {
- ok = false
- log.Printf("Close: %v", err)
- }
- }
-
- abstractWantErr := error(syscall.EPERM)
- pathnameWantErr := error(syscall.ENOENT)
- if want.SocketAbstract {
- abstractWantErr = nil
- }
- if want.SocketPathname {
- pathnameWantErr = nil
- }
-
- if !errors.Is(abstractErr, abstractWantErr) {
- ok = false
- log.Printf("abstractErr: %v, want %v", abstractErr, abstractWantErr)
- }
- if !errors.Is(pathnameErr, pathnameWantErr) {
- ok = false
- log.Printf("pathnameErr: %v, want %v", pathnameErr, pathnameWantErr)
- }
-
- if !ok {
- os.Exit(1)
- }
- }
-}
-
-func MustCheckFilter(pid int, want string) {
- err := CheckFilter(pid, want)
- if err == nil {
- return
- }
-
- perr, ok := errors.AsType[*ptraceError](err)
- if !ok {
- fatalf("%s", err)
- }
- switch perr.op {
- case "PTRACE_ATTACH":
- fatalf("cannot attach to process %d: %v", pid, err)
- case "PTRACE_SECCOMP_GET_FILTER":
- if perr.errno == syscall.ENOENT {
- fatalf("seccomp filter not installed for process %d", pid)
- }
- fatalf("cannot get filter: %v", err)
- default:
- fatalf("cannot check filter: %v", err)
- }
-
- *(*int)(nil) = 0 // not reached
-}
-
-func CheckFilter(pid int, want string) error {
- if err := ptraceAttach(pid); err != nil {
- return err
- }
- defer func() {
- if err := ptraceDetach(pid); err != nil {
- printf("cannot detach from process %d: %v", pid, err)
- }
- }()
-
- h := sha512.New()
-
- if buf, err := getFilter[[8]byte](pid, 0); err != nil {
- return err
- } else {
- for _, b := range buf {
- h.Write(b[:])
- }
- }
-
- if got := hex.EncodeToString(h.Sum(nil)); got != want {
- printf("[FAIL] %s", got)
- return syscall.ENOTRECOVERABLE
- } else {
- printf("[ OK ] %s", got)
- return nil
- }
-}
-
-func mustDecode(wantFilePath string, v any) {
- if f, err := os.Open(wantFilePath); err != nil {
- fatalf("cannot open %q: %v", wantFilePath, err)
- } else if err = json.NewDecoder(f).Decode(v); err != nil {
- fatalf("cannot decode %q: %v", wantFilePath, err)
- } else if err = f.Close(); err != nil {
- fatalf("cannot close %q: %v", wantFilePath, err)
- }
-}
-
-func mustParseMountinfo(name string) *Mountinfo {
- m := NewMountinfo(name)
- if err := m.Parse(); err != nil {
- fatalf("%v", err)
- panic("unreachable")
- }
- return m
-}
diff --git a/test/internal/sandbox/assert_test.go b/test/internal/sandbox/assert_test.go
deleted file mode 100644
index 012ae23d..00000000
--- a/test/internal/sandbox/assert_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-//go:build testtool
-
-package sandbox
-
-import (
- "encoding/json"
- "os"
- "path/filepath"
- "testing"
-)
-
-type F func(format string, v ...any)
-
-func SwapPrint(f F) (old F) { old = printfFunc; printfFunc = f; return }
-func SwapFatal(f F) (old F) { old = fatalfFunc; fatalfFunc = f; return }
-
-func MustWantFile(t *testing.T, v any) (wantFile string) {
- wantFile = filepath.Join(t.TempDir(), "want.json")
- if f, err := os.OpenFile(wantFile, os.O_CREATE|os.O_WRONLY, 0400); err != nil {
- t.Fatalf("cannot create %q: %v", wantFile, err)
- } else if err = json.NewEncoder(f).Encode(v); err != nil {
- t.Fatalf("cannot encode to %q: %v", wantFile, err)
- } else if err = f.Close(); err != nil {
- t.Fatalf("cannot close %q: %v", wantFile, err)
- }
-
- t.Cleanup(func() {
- if err := os.Remove(wantFile); err != nil {
- t.Fatalf("cannot remove %q: %v", wantFile, err)
- }
- })
-
- return
-}
diff --git a/test/internal/sandbox/fs.go b/test/internal/sandbox/fs.go
deleted file mode 100644
index b37d30b9..00000000
--- a/test/internal/sandbox/fs.go
+++ /dev/null
@@ -1,102 +0,0 @@
-//go:build testtool
-
-package sandbox
-
-import (
- "errors"
- "fmt"
- "io/fs"
- "path/filepath"
- "strings"
-)
-
-var (
- ErrFSBadLength = errors.New("bad dir length")
- ErrFSBadData = errors.New("data differs")
- ErrFSBadMode = errors.New("mode differs")
- ErrFSInvalidEnt = errors.New("invalid entry condition")
-)
-
-type FS struct {
- Mode fs.FileMode `json:"mode"`
- Dir map[string]*FS `json:"dir"`
- Data *string `json:"data"`
-}
-
-func printDir(prefix string, dir []fs.DirEntry) {
- names := make([]string, len(dir))
- for i, ent := range dir {
- name := ent.Name()
- if ent.IsDir() {
- name += "/"
- }
- names[i] = fmt.Sprintf("%q", name)
- }
- printf("[FAIL] d %s: %s", prefix, strings.Join(names, " "))
-}
-
-func (s *FS) Compare(prefix string, e fs.FS) error {
- if s.Data != nil {
- if s.Dir != nil {
- panic("invalid state")
- }
- panic("invalid compare call")
- }
-
- if s.Dir == nil {
- printf("[ OK ] s %s", prefix)
- return nil
- }
-
- var dir []fs.DirEntry
- if d, err := fs.ReadDir(e, prefix); err != nil {
- return err
- } else if len(d) != len(s.Dir) {
- printDir(prefix, d)
- return ErrFSBadLength
- } else {
- dir = d
- }
-
- for _, got := range dir {
- name := got.Name()
-
- if want, ok := s.Dir[name]; !ok {
- printDir(prefix, dir)
- return fs.ErrNotExist
- } else if want.Dir != nil && !got.IsDir() {
- printDir(prefix, dir)
- return ErrFSInvalidEnt
- } else {
- name = filepath.Join(prefix, name)
-
- if fi, err := got.Info(); err != nil {
- return err
- } else if fi.Mode() != want.Mode {
- printf("[FAIL] m %s: %x, want %x",
- name, uint32(fi.Mode()), uint32(want.Mode))
- return ErrFSBadMode
- }
-
- if want.Data != nil {
- if want.Dir != nil {
- panic("invalid state")
- }
- if v, err := fs.ReadFile(e, name); err != nil {
- return err
- } else if string(v) != *want.Data {
- printf("[FAIL] f %s", name)
- printf("got: %s", v)
- printf("want: %s", *want.Data)
- return ErrFSBadData
- }
- printf("[ OK ] f %s", name)
- } else if err := want.Compare(name, e); err != nil {
- return err
- }
- }
- }
- printf("[ OK ] d %s", prefix)
-
- return nil
-}
diff --git a/test/internal/sandbox/fs_test.go b/test/internal/sandbox/fs_test.go
deleted file mode 100644
index a7813ee5..00000000
--- a/test/internal/sandbox/fs_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-//go:build testtool
-
-package sandbox_test
-
-import (
- "errors"
- "fmt"
- "io/fs"
- "strings"
- "testing"
- "testing/fstest"
-
- "hakurei.app/test/internal/sandbox"
-)
-
-var (
- fsPasswdSample = "u0_a20:x:65534:65534:Hakurei:/var/lib/persist/module/hakurei/u0/a20:/run/current-system/sw/bin/zsh"
- fsGroupSample = "hakurei:x:65534:"
-)
-
-func TestCompare(t *testing.T) {
- testCases := []struct {
- name string
-
- sample fstest.MapFS
- want *sandbox.FS
- wantOut string
- wantErr error
- }{
- {"skip", fstest.MapFS{}, &sandbox.FS{}, "[ OK ] s .\x00", nil},
- {"simple pass", fstest.MapFS{".hakurei": {Mode: 0x800001ed}},
- &sandbox.FS{Dir: map[string]*sandbox.FS{".hakurei": {Mode: 0x800001ed}}},
- "[ OK ] s .hakurei\x00[ OK ] d .\x00", nil},
- {"bad length", fstest.MapFS{".hakurei": {Mode: 0x800001ed}},
- &sandbox.FS{Dir: make(map[string]*sandbox.FS)},
- "[FAIL] d .: \".hakurei/\"\x00", sandbox.ErrFSBadLength},
- {"top level bad mode", fstest.MapFS{".hakurei": {Mode: 0x800001ed}},
- &sandbox.FS{Dir: map[string]*sandbox.FS{".hakurei": {Mode: 0xdeadbeef}}},
- "[FAIL] m .hakurei: 800001ed, want deadbeef\x00", sandbox.ErrFSBadMode},
- {"invalid entry condition", fstest.MapFS{"test": {Data: []byte{'0'}, Mode: 0644}},
- &sandbox.FS{Dir: map[string]*sandbox.FS{"test": {Dir: make(map[string]*sandbox.FS)}}},
- "[FAIL] d .: \"test\"\x00", sandbox.ErrFSInvalidEnt},
- {"nonexistent", fstest.MapFS{"test": {Data: []byte{'0'}, Mode: 0644}},
- &sandbox.FS{Dir: map[string]*sandbox.FS{".test": {}}},
- "[FAIL] d .: \"test\"\x00", fs.ErrNotExist},
- {"file", fstest.MapFS{"etc": {Mode: 0x800001c0},
- "etc/passwd": {Data: []byte(fsPasswdSample), Mode: 0644},
- "etc/group": {Data: []byte(fsGroupSample), Mode: 0644},
- }, &sandbox.FS{Dir: map[string]*sandbox.FS{"etc": {Mode: 0x800001c0, Dir: map[string]*sandbox.FS{
- "passwd": {Mode: 0x1a4, Data: &fsPasswdSample},
- "group": {Mode: 0x1a4, Data: &fsGroupSample},
- }}}}, "[ OK ] f etc/group\x00[ OK ] f etc/passwd\x00[ OK ] d etc\x00[ OK ] d .\x00", nil},
- {"file differ", fstest.MapFS{"etc": {Mode: 0x800001c0},
- "etc/passwd": {Data: []byte(fsPasswdSample), Mode: 0644},
- "etc/group": {Data: []byte(fsGroupSample), Mode: 0644},
- }, &sandbox.FS{Dir: map[string]*sandbox.FS{"etc": {Mode: 0x800001c0, Dir: map[string]*sandbox.FS{
- "passwd": {Mode: 0x1a4, Data: &fsGroupSample},
- "group": {Mode: 0x1a4, Data: &fsGroupSample},
- }}}}, "[ OK ] f etc/group\x00[FAIL] f etc/passwd\x00got: u0_a20:x:65534:65534:Hakurei:/var/lib/persist/module/hakurei/u0/a20:/run/current-system/sw/bin/zsh\x00want: hakurei:x:65534:\x00", sandbox.ErrFSBadData},
- }
-
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- gotOut := new(strings.Builder)
- oldPrint := sandbox.SwapPrint(func(format string, v ...any) { _, _ = fmt.Fprintf(gotOut, format+"\x00", v...) })
- t.Cleanup(func() { sandbox.SwapPrint(oldPrint) })
-
- err := tc.want.Compare(".", tc.sample)
- if !errors.Is(err, tc.wantErr) {
- t.Errorf("Compare: error = %v; wantErr %v",
- err, tc.wantErr)
- }
-
- if gotOut.String() != tc.wantOut {
- t.Errorf("Compare: output %q; want %q",
- gotOut, tc.wantOut)
- }
- })
- }
-}
diff --git a/test/internal/sandbox/mount.go b/test/internal/sandbox/mount.go
deleted file mode 100644
index 791a68b9..00000000
--- a/test/internal/sandbox/mount.go
+++ /dev/null
@@ -1,159 +0,0 @@
-//go:build testtool
-
-package sandbox
-
-/*
-#cgo linux pkg-config: --static mount
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <libmount.h>
-
-const char *HAKUREI_MOUNTINFO_PATH = "/proc/self/mountinfo";
-*/
-import "C"
-
-import (
- "errors"
- "fmt"
- "iter"
- "runtime"
- "sync"
- "unsafe"
-)
-
-var (
- ErrMountinfoParse = errors.New("invalid mountinfo records")
- ErrMountinfoIter = errors.New("cannot allocate iterator")
- ErrMountinfoFault = errors.New("cannot iterate on filesystems")
-)
-
-type (
- Mountinfo struct {
- mu sync.RWMutex
- p string
- err error
-
- tb *C.struct_libmnt_table
- itr *C.struct_libmnt_iter
-
- fs *C.struct_libmnt_fs
- }
-
- // MountinfoEntry represents deterministic mountinfo parts of a libmnt_fs entry.
- MountinfoEntry struct {
- // mount ID: a unique ID for the mount (may be reused after umount(2)).
- ID int `json:"id"`
- // parent ID: the ID of the parent mount (or of self for the root of this mount namespace's mount tree).
- Parent int `json:"parent"`
- // root: the pathname of the directory in the filesystem which forms the root of this mount.
- Root string `json:"root"`
- // mount point: the pathname of the mount point relative to the process's root directory.
- Target string `json:"target"`
- // mount options: per-mount options (see mount(2)).
- VfsOptstr string `json:"vfs_optstr"`
- // filesystem type: the filesystem type in the form "type[.subtype]".
- FsType string `json:"fstype"`
- // mount source: filesystem-specific information or "none".
- Source string `json:"source"`
- // super options: per-superblock options (see mount(2)).
- FsOptstr string `json:"fs_optstr"`
- }
-)
-
-func (m *Mountinfo) copy(v *MountinfoEntry) {
- if m.fs == nil {
- panic("invalid entry")
- }
- v.ID = int(C.mnt_fs_get_id(m.fs))
- v.Parent = int(C.mnt_fs_get_parent_id(m.fs))
- v.Root = C.GoString(C.mnt_fs_get_root(m.fs))
- v.Target = C.GoString(C.mnt_fs_get_target(m.fs))
- v.VfsOptstr = C.GoString(C.mnt_fs_get_vfs_options(m.fs))
- v.FsType = C.GoString(C.mnt_fs_get_fstype(m.fs))
- v.Source = C.GoString(C.mnt_fs_get_source(m.fs))
- v.FsOptstr = C.GoString(C.mnt_fs_get_fs_options(m.fs))
-}
-
-func NewMountinfo(p string) *Mountinfo { m := new(Mountinfo); m.p = p; return m }
-
-func (m *Mountinfo) Err() error { m.mu.RLock(); defer m.mu.RUnlock(); return m.err }
-
-func (m *Mountinfo) Parse() error {
- m.mu.Lock()
- defer m.mu.Unlock()
-
- if m.tb != nil {
- panic("open called twice")
- }
-
- if m.p == "" {
- m.tb = C.mnt_new_table_from_file(C.HAKUREI_MOUNTINFO_PATH)
- } else {
- name := C.CString(m.p)
- m.tb = C.mnt_new_table_from_file(name)
- C.free(unsafe.Pointer(name))
- }
- if m.tb == nil {
- return ErrMountinfoParse
- }
- m.itr = C.mnt_new_iter(C.MNT_ITER_FORWARD)
- if m.itr == nil {
- C.mnt_unref_table(m.tb)
- return ErrMountinfoIter
- }
-
- runtime.SetFinalizer(m, (*Mountinfo).Unref)
- return nil
-}
-
-func (m *Mountinfo) Unref() {
- m.mu.Lock()
- defer m.mu.Unlock()
-
- if m.tb == nil {
- panic("unref called before parse")
- }
-
- C.mnt_unref_table(m.tb)
- C.mnt_free_iter(m.itr)
- runtime.SetFinalizer(m, nil)
-}
-
-func (m *Mountinfo) Entries() iter.Seq[*MountinfoEntry] {
- return func(yield func(*MountinfoEntry) bool) {
- m.mu.Lock()
- defer m.mu.Unlock()
-
- C.mnt_reset_iter(m.itr, -1)
-
- var rc C.int
- ent := new(MountinfoEntry)
- for rc = C.mnt_table_next_fs(m.tb, m.itr, &m.fs); rc == 0; rc = C.mnt_table_next_fs(m.tb, m.itr, &m.fs) {
- m.copy(ent)
- if !yield(ent) {
- return
- }
- }
- if rc < 0 {
- m.err = ErrMountinfoFault
- return
- }
- }
-}
-
-func (e *MountinfoEntry) EqualWithIgnore(want *MountinfoEntry, ignore string) bool {
- return (e.ID == want.ID || want.ID == -1) &&
- (e.Parent == want.Parent || want.Parent == -1) &&
- (e.Root == want.Root || want.Root == ignore) &&
- (e.Target == want.Target || want.Target == ignore) &&
- (e.VfsOptstr == want.VfsOptstr || want.VfsOptstr == ignore) &&
- (e.FsType == want.FsType || want.FsType == ignore) &&
- (e.Source == want.Source || want.Source == ignore) &&
- (e.FsOptstr == want.FsOptstr || want.FsOptstr == ignore)
-}
-
-func (e *MountinfoEntry) String() string {
- return fmt.Sprintf("%d %d %s %s %s %s %s %s",
- e.ID, e.Parent, e.Root, e.Target, e.VfsOptstr, e.FsType, e.Source, e.FsOptstr)
-}
diff --git a/test/internal/sandbox/mount_test.go b/test/internal/sandbox/mount_test.go
deleted file mode 100644
index a565b0a0..00000000
--- a/test/internal/sandbox/mount_test.go
+++ /dev/null
@@ -1,144 +0,0 @@
-//go:build testtool
-
-package sandbox_test
-
-import (
- "os"
- "path/filepath"
- "testing"
-
- "hakurei.app/test/internal/sandbox"
-)
-
-func TestMountinfo(t *testing.T) {
- testCases := []struct {
- name string
-
- sample string
- want []*sandbox.MountinfoEntry
- }{
- {"util-linux", `15 20 0:3 / /proc rw,relatime - proc /proc rw
-16 20 0:15 / /sys rw,relatime - sysfs /sys rw
-17 20 0:5 / /dev rw,relatime - devtmpfs udev rw,size=1983516k,nr_inodes=495879,mode=755
-18 17 0:10 / /dev/pts rw,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=000
-19 17 0:16 / /dev/shm rw,relatime - tmpfs tmpfs rw
-20 1 8:4 / / rw,noatime - ext3 /dev/sda4 rw,errors=continue,user_xattr,acl,barrier=0,data=ordered
-21 16 0:17 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,mode=755
-22 21 0:18 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd
-23 21 0:19 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpuset
-24 21 0:20 / /sys/fs/cgroup/ns rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,ns
-25 21 0:21 / /sys/fs/cgroup/cpu rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpu
-26 21 0:22 / /sys/fs/cgroup/cpuacct rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpuacct
-27 21 0:23 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,memory
-28 21 0:24 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,devices
-29 21 0:25 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,freezer
-30 21 0:26 / /sys/fs/cgroup/net_cls rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,net_cls
-31 21 0:27 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,blkio
-32 16 0:28 / /sys/kernel/security rw,relatime - autofs systemd-1 rw,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
-33 17 0:29 / /dev/hugepages rw,relatime - autofs systemd-1 rw,fd=23,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
-34 16 0:30 / /sys/kernel/debug rw,relatime - autofs systemd-1 rw,fd=24,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
-35 15 0:31 / /proc/sys/fs/binfmt_misc rw,relatime - autofs systemd-1 rw,fd=25,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
-36 17 0:32 / /dev/mqueue rw,relatime - autofs systemd-1 rw,fd=26,pgrp=1,timeout=300,minproto=5,maxproto=5,direct
-37 15 0:14 / /proc/bus/usb rw,relatime - usbfs /proc/bus/usb rw
-38 33 0:33 / /dev/hugepages rw,relatime - hugetlbfs hugetlbfs rw
-39 36 0:12 / /dev/mqueue rw,relatime - mqueue mqueue rw
-40 20 8:6 / /boot rw,noatime - ext3 /dev/sda6 rw,errors=continue,barrier=0,data=ordered
-41 20 253:0 / /home/kzak rw,noatime - ext4 /dev/mapper/kzak-home rw,barrier=1,data=ordered
-42 35 0:34 / /proc/sys/fs/binfmt_misc rw,relatime - binfmt_misc none rw
-43 16 0:35 / /sys/fs/fuse/connections rw,relatime - fusectl fusectl rw
-44 41 0:36 / /home/kzak/.gvfs rw,nosuid,nodev,relatime - fuse.gvfs-fuse-daemon gvfs-fuse-daemon rw,user_id=500,group_id=500
-45 20 0:37 / /var/lib/nfs/rpc_pipefs rw,relatime - rpc_pipefs sunrpc rw
-47 20 0:38 / /mnt/sounds rw,relatime - cifs //foo.home/bar/ rw,unc=\\foo.home\bar,username=kzak,domain=SRGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.111.1,posixpaths,serverino,acl,rsize=16384,wsize=57344
-49 20 0:56 / /mnt/test/foobar rw,relatime,nosymfollow shared:323 - tmpfs tmpfs rw`, []*sandbox.MountinfoEntry{
- e(15, 20, "/", "/proc", "rw,relatime", "proc", "/proc", "rw"),
- e(16, 20, "/", "/sys", "rw,relatime", "sysfs", "/sys", "rw"),
- e(17, 20, "/", "/dev", "rw,relatime", "devtmpfs", "udev", "rw,size=1983516k,nr_inodes=495879,mode=755"),
- e(18, 17, "/", "/dev/pts", "rw,relatime", "devpts", "devpts", "rw,gid=5,mode=620,ptmxmode=000"),
- e(19, 17, "/", "/dev/shm", "rw,relatime", "tmpfs", "tmpfs", "rw"),
- e(20, 1, "/", "/", "rw,noatime", "ext3", "/dev/sda4", "rw,errors=continue,user_xattr,acl,barrier=0,data=ordered"),
- e(21, 16, "/", "/sys/fs/cgroup", "rw,nosuid,nodev,noexec,relatime", "tmpfs", "tmpfs", "rw,mode=755"),
- e(22, 21, "/", "/sys/fs/cgroup/systemd", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd"),
- e(23, 21, "/", "/sys/fs/cgroup/cpuset", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,cpuset"),
- e(24, 21, "/", "/sys/fs/cgroup/ns", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,ns"),
- e(25, 21, "/", "/sys/fs/cgroup/cpu", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,cpu"),
- e(26, 21, "/", "/sys/fs/cgroup/cpuacct", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,cpuacct"),
- e(27, 21, "/", "/sys/fs/cgroup/memory", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,memory"),
- e(28, 21, "/", "/sys/fs/cgroup/devices", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,devices"),
- e(29, 21, "/", "/sys/fs/cgroup/freezer", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,freezer"),
- e(30, 21, "/", "/sys/fs/cgroup/net_cls", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,net_cls"),
- e(31, 21, "/", "/sys/fs/cgroup/blkio", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,blkio"),
- e(32, 16, "/", "/sys/kernel/security", "rw,relatime", "autofs", "systemd-1", "rw,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"),
- e(33, 17, "/", "/dev/hugepages", "rw,relatime", "autofs", "systemd-1", "rw,fd=23,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"),
- e(34, 16, "/", "/sys/kernel/debug", "rw,relatime", "autofs", "systemd-1", "rw,fd=24,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"),
- e(35, 15, "/", "/proc/sys/fs/binfmt_misc", "rw,relatime", "autofs", "systemd-1", "rw,fd=25,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"),
- e(36, 17, "/", "/dev/mqueue", "rw,relatime", "autofs", "systemd-1", "rw,fd=26,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"),
- e(37, 15, "/", "/proc/bus/usb", "rw,relatime", "usbfs", "/proc/bus/usb", "rw"),
- e(38, 33, "/", "/dev/hugepages", "rw,relatime", "hugetlbfs", "hugetlbfs", "rw"),
- e(39, 36, "/", "/dev/mqueue", "rw,relatime", "mqueue", "mqueue", "rw"),
- e(40, 20, "/", "/boot", "rw,noatime", "ext3", "/dev/sda6", "rw,errors=continue,barrier=0,data=ordered"),
- e(41, 20, "/", "/home/kzak", "rw,noatime", "ext4", "/dev/mapper/kzak-home", "rw,barrier=1,data=ordered"),
- e(42, 35, "/", "/proc/sys/fs/binfmt_misc", "rw,relatime", "binfmt_misc", "none", "rw"),
- e(43, 16, "/", "/sys/fs/fuse/connections", "rw,relatime", "fusectl", "fusectl", "rw"),
- e(44, 41, "/", "/home/kzak/.gvfs", "rw,nosuid,nodev,relatime", "fuse.gvfs-fuse-daemon", "gvfs-fuse-daemon", "rw,user_id=500,group_id=500"),
- e(45, 20, "/", "/var/lib/nfs/rpc_pipefs", "rw,relatime", "rpc_pipefs", "sunrpc", "rw"),
- e(47, 20, "/", "/mnt/sounds", "rw,relatime", "cifs", "//foo.home/bar/", "rw,unc=\\\\foo.home\\bar,username=kzak,domain=SRGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.111.1,posixpaths,serverino,acl,rsize=16384,wsize=57344"),
- e(49, 20, "/", "/mnt/test/foobar", "rw,relatime,nosymfollow", "tmpfs", "tmpfs", "rw"),
- }},
- }
-
- for _, tc := range testCases {
- name := filepath.Join(t.TempDir(), "sample")
- if err := os.WriteFile(name, []byte(tc.sample), 0400); err != nil {
- t.Fatalf("cannot write sample: %v", err)
- }
-
- t.Run(tc.name, func(t *testing.T) {
- m := sandbox.NewMountinfo(name)
- if err := m.Parse(); err != nil {
- t.Fatalf("Parse: error = %v", err)
- }
-
- i := 0
- for ent := range m.Entries() {
- if i == len(tc.want) {
- t.Errorf("Entries: got more than %d entries", i)
- t.FailNow()
- }
- if !ent.EqualWithIgnore(tc.want[i], "\x00") {
- t.Errorf("Entries: entry %d\n got: %#v\nwant: %#v", i,
- ent, &tc.want[i])
- t.FailNow()
- } else {
- t.Logf("%s", ent)
- }
-
- i++
- }
-
- if err := m.Err(); err != nil {
- t.Fatalf("Mountinfo: error = %v", err)
- }
-
- m.Unref()
- })
-
- if err := os.Remove(name); err != nil {
- t.Fatalf("cannot remove %q: %v", name, err)
- }
- }
-}
-
-func e(
- id, parent int, root, target, vfsOptstr string, fsType, source, fsOptstr string,
-) *sandbox.MountinfoEntry {
- return &sandbox.MountinfoEntry{
- ID: id,
- Parent: parent,
- Root: root,
- Target: target,
- VfsOptstr: vfsOptstr,
- FsType: fsType,
- Source: source,
- FsOptstr: fsOptstr,
- }
-}
diff --git a/test/internal/sandbox/ptrace.go b/test/internal/sandbox/ptrace.go
deleted file mode 100644
index 8272ff5b..00000000
--- a/test/internal/sandbox/ptrace.go
+++ /dev/null
@@ -1,87 +0,0 @@
-//go:build testtool
-
-package sandbox
-
-import (
- "errors"
- "fmt"
- "syscall"
- "unsafe"
-)
-
-const (
- NULL = 0
-
- PTRACE_ATTACH = 16
- PTRACE_DETACH = 17
- PTRACE_SECCOMP_GET_FILTER = 0x420c
-)
-
-type ptraceError struct {
- op string
- errno syscall.Errno
-}
-
-func (p *ptraceError) Error() string { return fmt.Sprintf("%s: %v", p.op, p.errno) }
-
-func (p *ptraceError) Unwrap() error {
- if p.errno == 0 {
- return nil
- }
- return p.errno
-}
-
-func ptrace(op uintptr, pid, addr int, data unsafe.Pointer) (r uintptr, errno syscall.Errno) {
- r, _, errno = syscall.Syscall6(syscall.SYS_PTRACE, op, uintptr(pid), uintptr(addr), uintptr(data), NULL, NULL)
- return
-}
-
-func ptraceAttach(pid int) error {
- if _, errno := ptrace(PTRACE_ATTACH, pid, 0, nil); errno != 0 {
- return &ptraceError{"PTRACE_ATTACH", errno}
- }
-
- var status syscall.WaitStatus
- for {
- if _, err := syscall.Wait4(pid, &status, syscall.WALL, nil); err != nil {
- if errors.Is(err, syscall.EINTR) {
- continue
- }
- fatalf("cannot waitpid: %v", err)
- }
- break
- }
-
- return nil
-}
-
-func ptraceDetach(pid int) error {
- if _, errno := ptrace(PTRACE_DETACH, pid, 0, nil); errno != 0 {
- return &ptraceError{"PTRACE_DETACH", errno}
- }
- return nil
-}
-
-type sockFilter struct { /* Filter block */
- code uint16 /* Actual filter code */
- jt uint8 /* Jump true */
- jf uint8 /* Jump false */
- k uint32 /* Generic multiuse field */
-}
-
-func getFilter[T comparable](pid, index int) ([]T, error) {
- if s := unsafe.Sizeof(*new(T)); s != 8 {
- panic(fmt.Sprintf("invalid filter block size %d", s))
- }
-
- var buf []T
- if n, errno := ptrace(PTRACE_SECCOMP_GET_FILTER, pid, index, nil); errno != 0 {
- return nil, &ptraceError{"PTRACE_SECCOMP_GET_FILTER", errno}
- } else {
- buf = make([]T, n)
- }
- if _, errno := ptrace(PTRACE_SECCOMP_GET_FILTER, pid, index, unsafe.Pointer(&buf[0])); errno != 0 {
- return nil, &ptraceError{"PTRACE_SECCOMP_GET_FILTER", errno}
- }
- return buf, nil
-}
diff --git a/test/internal/sandbox/seccomp.go b/test/internal/sandbox/seccomp.go
deleted file mode 100644
index 7df781d2..00000000
--- a/test/internal/sandbox/seccomp.go
+++ /dev/null
@@ -1,44 +0,0 @@
-//go:build testtool
-
-package sandbox
-
-import (
- "os"
- "syscall"
-)
-
-/*
-#include <sys/quota.h>
-*/
-import "C"
-
-func trySyscalls() error {
- testCases := []struct {
- name string
- errno syscall.Errno
-
- trap, a1, a2, a3, a4, a5, a6 uintptr
- }{
- {"syslog", syscall.EPERM, syscall.SYS_SYSLOG, 0, NULL, NULL, NULL, NULL, NULL},
- {"acct", syscall.EPERM, syscall.SYS_ACCT, 0, NULL, NULL, NULL, NULL, NULL},
- {"quotactl", syscall.EPERM, syscall.SYS_QUOTACTL, C.Q_GETQUOTA, NULL, uintptr(os.Getuid()), NULL, NULL, NULL},
- {"add_key", syscall.EPERM, syscall.SYS_ADD_KEY, NULL, NULL, NULL, NULL, NULL, NULL},
- {"keyctl", syscall.EPERM, syscall.SYS_KEYCTL, NULL, NULL, NULL, NULL, NULL, NULL},
- {"request_key", syscall.EPERM, syscall.SYS_REQUEST_KEY, NULL, NULL, NULL, NULL, NULL, NULL},
- {"move_pages", syscall.EPERM, syscall.SYS_MOVE_PAGES, uintptr(os.Getpid()), NULL, NULL, NULL, NULL, NULL},
- {"mbind", syscall.EPERM, syscall.SYS_MBIND, NULL, NULL, NULL, NULL, NULL, NULL},
- {"get_mempolicy", syscall.EPERM, syscall.SYS_GET_MEMPOLICY, NULL, NULL, NULL, NULL, NULL, NULL},
- {"set_mempolicy", syscall.EPERM, syscall.SYS_SET_MEMPOLICY, NULL, NULL, NULL, NULL, NULL, NULL},
- {"migrate_pages", syscall.EPERM, syscall.SYS_MIGRATE_PAGES, NULL, NULL, NULL, NULL, NULL, NULL},
- }
-
- for _, tc := range testCases {
- if _, _, errno := syscall.Syscall6(tc.trap, tc.a1, tc.a2, tc.a3, tc.a4, tc.a5, tc.a6); errno != tc.errno {
- printf("[FAIL] %s: %v, want %v", tc.name, errno, tc.errno)
- return errno
- }
- printf("[ OK ] %s: %v", tc.name, tc.errno)
- }
-
- return nil
-}
diff --git a/test/nixos.nix b/test/nixos.nix
deleted file mode 100644
index 49bfffb6..00000000
--- a/test/nixos.nix
+++ /dev/null
@@ -1,407 +0,0 @@
-packages:
-{
- lib,
- pkgs,
- config,
- ...
-}:
-
-let
- inherit (lib)
- lists
- attrsets
- mkMerge
- mkIf
- mapAttrs
- foldlAttrs
- optional
- optionals
- ;
-
- cfg = config.environment.hakurei;
-
- # userid*userOffset + appStart + appid
- getsubuid = userid: appid: userid * 100000 + 10000 + appid;
- getsubname = userid: appid: "u${toString userid}_a${toString appid}";
- getsubhome = userid: appid: "${cfg.stateDir}/u${toString userid}/a${toString appid}";
-
- mountpoints = {
- ${cfg.sharefs.name} = mkIf (cfg.sharefs.source != null) {
- depends = [ cfg.sharefs.source ];
- device = "sharefs";
- fsType = "fuse.sharefs";
- noCheck = true;
- options = [
- "rw"
- "noexec"
- "nosuid"
- "nodev"
- "noatime"
- "allow_other"
- "mkdir"
- "source=${cfg.sharefs.source}"
- "setuid=${toString config.users.users.${cfg.sharefs.user}.uid}"
- "setgid=${toString config.users.groups.${cfg.sharefs.group}.gid}"
- ];
- };
- };
-in
-
-{
- imports = [ (import ./options.nix packages) ];
-
- options = {
- # Forward declare a dummy option for VM filesystems since the real one won't exist
- # unless the VM module is actually imported.
- virtualisation.fileSystems = lib.mkOption { };
- };
-
- config = mkIf cfg.enable {
- assertions = [
- (
- let
- conflictingApps = foldlAttrs (
- acc: id: app:
- (
- acc
- ++ foldlAttrs (
- acc': id': app':
- if id == id' || app.shareUid && app'.shareUid || app.identity != app'.identity then acc' else acc' ++ [ id ]
- ) [ ] cfg.apps
- )
- ) [ ] cfg.apps;
- in
- {
- assertion = (lists.length conflictingApps) == 0;
- message = "the following hakurei apps have conflicting identities: " + (builtins.concatStringsSep ", " conflictingApps);
- }
- )
- ];
-
- security.wrappers.hsu = {
- source = "${cfg.hsuPackage}/bin/hsu";
- setuid = true;
- owner = "root";
- group = "root";
- };
-
- environment.etc.hsurc = {
- mode = "0400";
- text = foldlAttrs (
- acc: username: fid:
- "${toString config.users.users.${username}.uid} ${toString fid}\n" + acc
- ) "" cfg.users;
- };
-
- environment.systemPackages = optional (cfg.sharefs.source != null) cfg.sharefs.package;
- fileSystems = mountpoints;
- virtualisation.fileSystems = mountpoints;
-
- home-manager =
- let
- privPackages = mapAttrs (_: userid: {
- home.packages = foldlAttrs (
- acc: id: app:
- [
- (
- let
- extendDBusDefault = id: ext: {
- filter = true;
-
- talk = [ "org.freedesktop.Notifications" ] ++ ext.talk;
- own = [
- "${id}.*"
- "org.mpris.MediaPlayer2.${id}.*"
- ]
- ++ ext.own;
-
- inherit (ext) call broadcast;
- };
- dbusConfig =
- let
- default = {
- talk = [ ];
- own = [ ];
- call = { };
- broadcast = { };
- };
- in
- {
- session_bus = if app.dbus.session != null then (app.dbus.session (extendDBusDefault id)) else (extendDBusDefault id default);
- system_bus = app.dbus.system;
- };
- command = if app.command == null then app.name else app.command;
- script = if app.script == null then ("exec " + command + " $@") else app.script;
- isGraphical = if app.gpu != null then app.gpu else app.enablements.wayland || app.enablements.x11;
-
- conf = {
- inherit id;
- inherit (app) identity enablements;
- inherit (dbusConfig) session_bus system_bus;
- direct_wayland = app.insecureWayland;
- sched_policy = app.schedPolicy;
- sched_priority = app.schedPriority;
- groups = app.groups ++ optional (cfg.sharefs.source != null) cfg.sharefs.group;
-
- container = {
- inherit (app)
- wait_delay
- devel
- userns
- device
- tty
- multiarch
- env
- ;
- map_real_uid = app.mapRealUid;
- host_net = app.hostNet;
- host_abstract = app.hostAbstract;
- share_runtime = app.shareRuntime;
- share_tmpdir = app.shareTmpdir;
-
- filesystem =
- let
- bind = src: {
- type = "bind";
- inherit src;
- };
- optBind = src: {
- type = "bind";
- inherit src;
- optional = true;
- };
- optDevBind = src: {
- type = "bind";
- inherit src;
- dev = true;
- optional = true;
- };
- in
- [
- (bind "/bin")
- (bind "/usr/bin")
- (bind "/nix/store")
- (optBind "/sys/block")
- (optBind "/sys/bus")
- (optBind "/sys/class")
- (optBind "/sys/dev")
- (optBind "/sys/devices")
- ]
- ++ optionals app.nix [
- (bind "/nix/var")
- ]
- ++ optionals isGraphical [
- (optDevBind "/dev/dri")
- (optDevBind "/dev/nvidiactl")
- (optDevBind "/dev/nvidia-modeset")
- (optDevBind "/dev/nvidia-uvm")
- (optDevBind "/dev/nvidia-uvm-tools")
- (optDevBind "/dev/nvidia0")
- ]
- ++ optionals app.useCommonPaths cfg.commonPaths
- ++ app.extraPaths
- ++ [
- {
- type = "bind";
- dst = "/etc/";
- src = "/etc/";
- special = true;
- }
- {
- type = "link";
- dst = "/run/current-system";
- linkname = "/run/current-system";
- dereference = true;
- }
- ]
- ++ optionals (isGraphical && config.hardware.graphics.enable) (
- [
- {
- type = "link";
- dst = "/run/opengl-driver";
- linkname = config.systemd.tmpfiles.settings.graphics-driver."/run/opengl-driver"."L+".argument;
- }
- ]
- ++ optionals (app.multiarch && config.hardware.graphics.enable32Bit) [
- {
- type = "link";
- dst = "/run/opengl-driver-32";
- linkname = config.systemd.tmpfiles.settings.graphics-driver."/run/opengl-driver-32"."L+".argument;
- }
- ]
- )
- ++ [
- {
- type = "bind";
- src = getsubhome userid app.identity;
- write = true;
- ensure = true;
- }
- ];
-
- username = getsubname userid app.identity;
- inherit (cfg) shell;
- home = getsubhome userid app.identity;
-
- path =
- if app.path == null then
- pkgs.writeScript "${app.name}-start" ''
- #!${pkgs.zsh}${pkgs.zsh.shellPath}
- ${script}
- ''
- else
- app.path;
- args = if app.args == null then [ "${app.name}-start" ] else app.args;
- };
- };
-
- checkedConfig =
- name: value:
- let
- file = pkgs.writeText name (builtins.toJSON value);
- in
- pkgs.runCommand "checked-${name}" { nativeBuildInputs = [ cfg.package ]; } ''
- ln -vs ${file} "$out"
- hakurei show --no-store ${file}
- '';
- in
- pkgs.writeShellScriptBin app.name ''
- exec hakurei${if app.verbose then " -v" else ""}${if app.insecureWayland then " --insecure" else ""} run ${checkedConfig "hakurei-app-${app.name}.json" conf} $@
- ''
- )
- ]
- ++ (
- let
- pkg = if app.share != null then app.share else pkgs.${app.name};
- copy = source: "[ -d '${source}' ] && cp -Lrv '${source}' $out/share || true";
- in
- optional (app.enablements.wayland || app.enablements.x11) (
- pkgs.runCommand "${app.name}-share" { } ''
- mkdir -p $out/share
- ${copy "${pkg}/share/applications"}
- ${copy "${pkg}/share/pixmaps"}
- ${copy "${pkg}/share/icons"}
- ${copy "${pkg}/share/man"}
-
- if test -d "$out/share/applications"; then
- substituteInPlace $out/share/applications/* \
- --replace-warn '${pkg}/bin/' "" \
- --replace-warn '${pkg}/libexec/' ""
- fi
- ''
- )
- )
- ++ acc
- ) [ cfg.package ] cfg.apps;
- }) cfg.users;
- in
- {
- useUserPackages = false; # prevent users.users entries from being added
-
- users =
- mkMerge
- (foldlAttrs
- (
- acc: _: fid:
- foldlAttrs
- (
- acc: _: app:
- (
- let
- key = getsubname fid app.identity;
- in
- {
- usernames = acc.usernames // {
- ${key} = true;
- };
- merge = acc.merge ++ [
- {
- ${key} = mkMerge (
- [
- app.extraConfig
- { home.packages = app.packages; }
- ]
- ++ lib.optional (!attrsets.hasAttrByPath [ key ] acc.usernames) cfg.extraHomeConfig
- );
- }
- ];
- }
- )
- )
- {
- inherit (acc) usernames;
- merge = acc.merge ++ [ { ${getsubname fid 0} = cfg.extraHomeConfig; } ];
- }
- cfg.apps
- )
- {
- usernames = { };
- merge = [ privPackages ];
- }
- cfg.users
- ).merge;
- };
-
- users =
- let
- getuser = userid: appid: {
- isSystemUser = true;
- createHome = true;
- description = "Hakurei subordinate user ${toString appid} (u${toString userid})";
- group = getsubname userid appid;
- home = getsubhome userid appid;
- uid = getsubuid userid appid;
- };
- getgroup = userid: appid: { gid = getsubuid userid appid; };
- in
- {
- users = mkMerge (
- foldlAttrs
- (
- acc: username: fid:
- acc
- ++
- foldlAttrs
- (
- acc': _: app:
- acc' ++ [ { ${getsubname fid app.identity} = getuser fid app.identity; } ]
- )
- [
- {
- ${getsubname fid 0} = getuser fid 0;
- ${username}.extraGroups = [ cfg.sharefs.group ];
- }
- ]
- cfg.apps
- )
- (optional (cfg.sharefs.source != null) {
- ${cfg.sharefs.user} = {
- uid = lib.mkDefault 1023;
- inherit (cfg.sharefs) group;
- isSystemUser = true;
- home = cfg.sharefs.source;
- };
- })
- cfg.users
- );
-
- groups = mkMerge (
- foldlAttrs
- (
- acc: _: fid:
- acc
- ++ foldlAttrs (
- acc': _: app:
- acc' ++ [ { ${getsubname fid app.identity} = getgroup fid app.identity; } ]
- ) [ { ${getsubname fid 0} = getgroup fid 0; } ] cfg.apps
- )
- (optional (cfg.sharefs.source != null) {
- ${cfg.sharefs.group} = {
- gid = lib.mkDefault 1023;
- };
- })
- cfg.users
- );
- };
- };
-}
diff --git a/test/options.md b/test/options.md
deleted file mode 100644
index 6f6acddd..00000000
--- a/test/options.md
+++ /dev/null
@@ -1,1175 +0,0 @@
-## environment\.hakurei\.enable
-
-
-
-Whether to enable hakurei\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.package
-
-
-
-The hakurei package to use\.
-
-
-
-*Type:*
-package
-
-
-
-*Default:*
-
-```nix
-<derivation hakurei-static-x86_64-unknown-linux-musl-0.4.3>
-```
-
-
-
-## environment\.hakurei\.apps
-
-Declaratively configured hakurei apps\.
-
-
-
-*Type:*
-attribute set of (submodule)
-
-
-
-*Default:*
-
-```nix
-{ }
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.enablements\.dbus
-
-
-
-Whether to proxy D-Bus\.
-
-
-
-*Type:*
-null or boolean
-
-
-
-*Default:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.enablements\.pipewire
-
-
-
-Whether to share the PipeWire server via pipewire-pulse on a SecurityContext socket\.
-
-
-
-*Type:*
-null or boolean
-
-
-
-*Default:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.enablements\.wayland
-
-
-
-Whether to share the Wayland server via security-context-v1\.
-
-
-
-*Type:*
-null or boolean
-
-
-
-*Default:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.enablements\.x11
-
-
-
-Whether to share the X11 socket and allow connection\.
-
-
-
-*Type:*
-null or boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.packages
-
-
-
-List of extra packages to install via home-manager\.
-
-
-
-*Type:*
-list of package
-
-
-
-*Default:*
-
-```nix
-[ ]
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.args
-
-
-
-Custom args\.
-Setting this to null will default to script name\.
-
-
-
-*Type:*
-null or (list of string)
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.command
-
-
-
-Command to run as the target user\.
-Setting this to null will default command to launcher name\.
-Has no effect when script is set\.
-
-
-
-*Type:*
-null or string
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.dbus\.session
-
-
-
-D-Bus session bus custom configuration\.
-Setting this to null will enable built-in defaults\.
-
-
-
-*Type:*
-null or (function that evaluates to a(n) anything)
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.dbus\.system
-
-
-
-D-Bus system bus custom configuration\.
-Setting this to null will disable the system bus proxy\.
-
-
-
-*Type:*
-null or anything
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.devel
-
-
-
-Whether to enable debugging-related kernel interfaces\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.device
-
-
-
-Whether to enable access to all devices\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.env
-
-
-
-Environment variables to set for the initial process in the sandbox\.
-
-
-
-*Type:*
-null or (attribute set of string)
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.extraConfig
-
-
-
-Extra home-manager configuration\.
-
-
-
-*Type:*
-anything
-
-
-
-*Default:*
-
-```nix
-{ }
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.extraPaths
-
-
-
-Extra paths to make available to the container\.
-
-
-
-*Type:*
-list of attribute set of anything
-
-
-
-*Default:*
-
-```nix
-[ ]
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.gpu
-
-
-
-Target process GPU and driver access\.
-Setting this to null will enable GPU whenever X or Wayland is enabled\.
-
-
-
-*Type:*
-null or boolean
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.groups
-
-
-
-List of groups to inherit from the privileged user\.
-
-
-
-*Type:*
-list of string
-
-
-
-*Default:*
-
-```nix
-[ ]
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.hostAbstract
-
-
-
-Whether to enable share abstract unix socket scope\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.hostNet
-
-
-
-Whether to enable share host net namespace\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-true
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.identity
-
-
-
-Application identity\. Identity 0 is reserved for system services\.
-
-
-
-*Type:*
-integer between 1 and 9999 (both inclusive)
-
-
-
-## environment\.hakurei\.apps\.\<name>\.insecureWayland
-
-
-
-Whether to enable direct access to the Wayland socket\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.mapRealUid
-
-
-
-Whether to enable mapping to priv-user uid\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.multiarch
-
-
-
-Whether to enable multiarch kernel-level support\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.name
-
-
-
-Name of the app’s launcher script\.
-
-
-
-*Type:*
-string
-
-
-
-## environment\.hakurei\.apps\.\<name>\.nix
-
-
-
-Whether to enable nix daemon access\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.path
-
-
-
-Custom executable path\.
-Setting this to null will default to the start script\.
-
-
-
-*Type:*
-null or string
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.schedPolicy
-
-
-
-Scheduling policy to set for the container\.
-The zero value retains the current scheduling policy\.
-
-
-
-*Type:*
-null or one of “fifo”, “rr”, “batch”, “idle”, “deadline”, “ext”
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.schedPriority
-
-
-
-Scheduling priority to set for the container\.
-
-
-
-*Type:*
-null or integer between 1 and 99 (both inclusive)
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.script
-
-
-
-Application launch script\.
-
-
-
-*Type:*
-null or string
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.share
-
-
-
-Package containing share files\.
-Setting this to null will default package name to wrapper name\.
-
-
-
-*Type:*
-null or package
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.shareRuntime
-
-
-
-Whether to enable sharing of XDG_RUNTIME_DIR between containers under the same identity\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.shareTmpdir
-
-
-
-Whether to enable sharing of TMPDIR between containers under the same identity\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.shareUid
-
-
-
-Whether to enable sharing identity with another application\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.tty
-
-
-
-Whether to enable access to the controlling terminal\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.useCommonPaths
-
-
-
-Whether to enable common extra paths\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-true
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.userns
-
-
-
-Whether to enable user namespace creation\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.verbose
-
-
-
-Whether to enable launchers with verbose output\.
-
-
-
-*Type:*
-boolean
-
-
-
-*Default:*
-
-```nix
-false
-```
-
-
-
-*Example:*
-
-```nix
-true
-```
-
-
-
-## environment\.hakurei\.apps\.\<name>\.wait_delay
-
-
-
-Duration to wait for after interrupting a container’s initial process in nanoseconds\.
-A negative value causes the container to be terminated immediately on cancellation\.
-Setting this to null defaults to five seconds\.
-
-
-
-*Type:*
-null or signed integer
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.commonPaths
-
-
-
-Common extra paths to make available to the container\.
-
-
-
-*Type:*
-list of attribute set of anything
-
-
-
-*Default:*
-
-```nix
-[ ]
-```
-
-
-
-## environment\.hakurei\.extraHomeConfig
-
-
-
-Extra home-manager configuration to merge with all target users\.
-
-
-
-*Type:*
-anything
-
-
-
-## environment\.hakurei\.hsuPackage
-
-
-
-The hsu package to use\.
-
-
-
-*Type:*
-package
-
-
-
-*Default:*
-
-```nix
-<derivation hakurei-hsu-0.4.3>
-```
-
-
-
-## environment\.hakurei\.sharefs\.package
-
-
-
-The sharefs package to use\.
-
-
-
-*Type:*
-package
-
-
-
-*Default:*
-
-```nix
-<derivation sharefs>
-```
-
-
-
-## environment\.hakurei\.sharefs\.group
-
-
-
-Name of the group to run the sharefs daemon as\.
-
-
-
-*Type:*
-string
-
-
-
-*Default:*
-
-```nix
-"sharefs"
-```
-
-
-
-## environment\.hakurei\.sharefs\.name
-
-
-
-Host path to mount sharefs on\.
-
-
-
-*Type:*
-string
-
-
-
-*Default:*
-
-```nix
-"/sdcard"
-```
-
-
-
-## environment\.hakurei\.sharefs\.source
-
-
-
-Writable backing directory\. Setting this to null disables sharefs\.
-
-
-
-*Type:*
-null or string
-
-
-
-*Default:*
-
-```nix
-null
-```
-
-
-
-## environment\.hakurei\.sharefs\.user
-
-
-
-Name of the user to run the sharefs daemon as\.
-
-
-
-*Type:*
-string
-
-
-
-*Default:*
-
-```nix
-"sharefs"
-```
-
-
-
-## environment\.hakurei\.shell
-
-
-
-Absolute path to preferred shell\.
-
-
-
-*Type:*
-string
-
-
-
-*Default:*
-
-```nix
-"/run/current-system/sw/bin/bash"
-```
-
-
-
-## environment\.hakurei\.stateDir
-
-
-
-The state directory where app home directories are stored\.
-
-
-
-*Type:*
-string
-
-
-
-## environment\.hakurei\.users
-
-
-
-Users allowed to spawn hakurei apps and their corresponding hakurei identity\.
-
-
-
-*Type:*
-attribute set of integer between 0 and 99 (both inclusive)
-
-
-
-*Default:*
-
-```nix
-{ }
-```
-
-
diff --git a/test/options.nix b/test/options.nix
deleted file mode 100644
index f624b6f5..00000000
--- a/test/options.nix
+++ /dev/null
@@ -1,364 +0,0 @@
-packages:
-{
- lib,
- pkgs,
- config,
- ...
-}:
-
-let
- inherit (lib) types mkOption mkEnableOption;
-
- cfg = config.environment.hakurei;
-in
-
-{
- options = {
- environment.hakurei = {
- enable = mkEnableOption "hakurei";
-
- package = mkOption {
- type = types.package;
- default = packages.${pkgs.stdenv.hostPlatform.system}.hakurei;
- description = "The hakurei package to use.";
- };
-
- hsuPackage = mkOption {
- type = types.package;
- default = packages.${pkgs.stdenv.hostPlatform.system}.hsu;
- description = "The hsu package to use.";
- };
-
- users = mkOption {
- type =
- let
- inherit (types) attrsOf ints;
- in
- attrsOf (ints.between 0 99);
- description = ''
- Users allowed to spawn hakurei apps and their corresponding hakurei identity.
- '';
- };
-
- extraHomeConfig = mkOption {
- type = types.anything;
- description = ''
- Extra home-manager configuration to merge with all target users.
- '';
- };
-
- sharefs = {
- package = mkOption {
- type = types.package;
- default = pkgs.linkFarm "sharefs" {
- "bin/sharefs" = "${cfg.package}/libexec/sharefs";
- "bin/mount.fuse.sharefs" = "${cfg.package}/libexec/sharefs";
- };
- description = "The sharefs package to use.";
- };
-
- user = mkOption {
- type = types.str;
- default = "sharefs";
- description = ''
- Name of the user to run the sharefs daemon as.
- '';
- };
-
- group = mkOption {
- type = types.str;
- default = "sharefs";
- description = ''
- Name of the group to run the sharefs daemon as.
- '';
- };
-
- name = mkOption {
- type = types.str;
- default = "/sdcard";
- description = ''
- Host path to mount sharefs on.
- '';
- };
-
- source = mkOption {
- type = types.nullOr types.str;
- default = null;
- description = ''
- Writable backing directory. Setting this to null disables sharefs.
- '';
- };
- };
-
- apps = mkOption {
- type =
- let
- inherit (types)
- int
- ints
- str
- bool
- enum
- package
- anything
- submodule
- listOf
- attrsOf
- nullOr
- functionTo
- ;
- in
- attrsOf (submodule {
- options = {
- name = mkOption {
- type = str;
- description = ''
- Name of the app's launcher script.
- '';
- };
-
- verbose = mkEnableOption "launchers with verbose output";
-
- identity = mkOption {
- type = ints.between 1 9999;
- description = ''
- Application identity. Identity 0 is reserved for system services.
- '';
- };
- shareUid = mkEnableOption "sharing identity with another application";
-
- packages = mkOption {
- type = listOf package;
- default = [ ];
- description = ''
- List of extra packages to install via home-manager.
- '';
- };
-
- extraConfig = mkOption {
- type = anything;
- default = { };
- description = ''
- Extra home-manager configuration.
- '';
- };
-
- path = mkOption {
- type = nullOr str;
- default = null;
- description = ''
- Custom executable path.
- Setting this to null will default to the start script.
- '';
- };
-
- args = mkOption {
- type = nullOr (listOf str);
- default = null;
- description = ''
- Custom args.
- Setting this to null will default to script name.
- '';
- };
-
- script = mkOption {
- type = nullOr str;
- default = null;
- description = ''
- Application launch script.
- '';
- };
-
- command = mkOption {
- type = nullOr str;
- default = null;
- description = ''
- Command to run as the target user.
- Setting this to null will default command to launcher name.
- Has no effect when script is set.
- '';
- };
-
- groups = mkOption {
- type = listOf str;
- default = [ ];
- description = ''
- List of groups to inherit from the privileged user.
- '';
- };
-
- shareRuntime = mkEnableOption "sharing of XDG_RUNTIME_DIR between containers under the same identity";
- shareTmpdir = mkEnableOption "sharing of TMPDIR between containers under the same identity";
-
- dbus = {
- session = mkOption {
- type = nullOr (functionTo anything);
- default = null;
- description = ''
- D-Bus session bus custom configuration.
- Setting this to null will enable built-in defaults.
- '';
- };
-
- system = mkOption {
- type = nullOr anything;
- default = null;
- description = ''
- D-Bus system bus custom configuration.
- Setting this to null will disable the system bus proxy.
- '';
- };
- };
-
- env = mkOption {
- type = nullOr (attrsOf str);
- default = null;
- description = ''
- Environment variables to set for the initial process in the sandbox.
- '';
- };
-
- wait_delay = mkOption {
- type = nullOr int;
- default = null;
- description = ''
- Duration to wait for after interrupting a container's initial process in nanoseconds.
- A negative value causes the container to be terminated immediately on cancellation.
- Setting this to null defaults to five seconds.
- '';
- };
-
- devel = mkEnableOption "debugging-related kernel interfaces";
- userns = mkEnableOption "user namespace creation";
- tty = mkEnableOption "access to the controlling terminal";
- multiarch = mkEnableOption "multiarch kernel-level support";
-
- hostNet = mkEnableOption "share host net namespace" // {
- default = true;
- };
- hostAbstract = mkEnableOption "share abstract unix socket scope";
-
- schedPolicy = mkOption {
- type = nullOr (enum [
- "fifo"
- "rr"
- "batch"
- "idle"
- "deadline"
- "ext"
- ]);
- default = null;
- description = ''
- Scheduling policy to set for the container.
- The zero value retains the current scheduling policy.
- '';
- };
- schedPriority = mkOption {
- type = nullOr (ints.between 1 99);
- default = null;
- description = ''
- Scheduling priority to set for the container.
- '';
- };
-
- nix = mkEnableOption "nix daemon access";
- mapRealUid = mkEnableOption "mapping to priv-user uid";
- device = mkEnableOption "access to all devices";
- insecureWayland = mkEnableOption "direct access to the Wayland socket";
-
- gpu = mkOption {
- type = nullOr bool;
- default = null;
- description = ''
- Target process GPU and driver access.
- Setting this to null will enable GPU whenever X or Wayland is enabled.
- '';
- };
-
- useCommonPaths = mkEnableOption "common extra paths" // {
- default = true;
- };
-
- extraPaths = mkOption {
- type = listOf (attrsOf anything);
- default = [ ];
- description = ''
- Extra paths to make available to the container.
- '';
- };
-
- enablements = {
- wayland = mkOption {
- type = nullOr bool;
- default = true;
- description = ''
- Whether to share the Wayland server via security-context-v1.
- '';
- };
-
- x11 = mkOption {
- type = nullOr bool;
- default = false;
- description = ''
- Whether to share the X11 socket and allow connection.
- '';
- };
-
- dbus = mkOption {
- type = nullOr bool;
- default = true;
- description = ''
- Whether to proxy D-Bus.
- '';
- };
-
- pipewire = mkOption {
- type = nullOr bool;
- default = true;
- description = ''
- Whether to share the PipeWire server via pipewire-pulse on a SecurityContext socket.
- '';
- };
- };
-
- share = mkOption {
- type = nullOr package;
- default = null;
- description = ''
- Package containing share files.
- Setting this to null will default package name to wrapper name.
- '';
- };
- };
- });
- default = { };
- description = ''
- Declaratively configured hakurei apps.
- '';
- };
-
- commonPaths = mkOption {
- type = types.listOf (types.attrsOf types.anything);
- default = [ ];
- description = ''
- Common extra paths to make available to the container.
- '';
- };
-
- shell = mkOption {
- type = types.str;
- default = "/run/current-system/sw/bin/bash";
- description = ''
- Absolute path to preferred shell.
- '';
- };
-
- stateDir = mkOption {
- type = types.str;
- description = ''
- The state directory where app home directories are stored.
- '';
- };
- };
- };
-}
diff --git a/test/package.nix b/test/package.nix
deleted file mode 100644
index e68420e3..00000000
--- a/test/package.nix
+++ /dev/null
@@ -1,144 +0,0 @@
-{
- lib,
- stdenv,
- buildGo127Module,
- makeBinaryWrapper,
- xdg-dbus-proxy,
- pkg-config,
- libffi,
- libseccomp,
- acl,
- wayland,
- wayland-protocols,
- wayland-scanner,
-
- libxcb,
- libxau,
- libxdmcp,
-
- # for sharefs
- fuse3,
-
- # for passthru.buildInputs
- go_1_27,
- clang,
- xorgproto,
-
- # for check
- util-linux,
- nettools,
-
- glibc, # for ldd
- withStatic ? stdenv.hostPlatform.isStatic,
-}:
-
-buildGo127Module rec {
- pname = "hakurei";
- version = with lib.strings; removePrefix "v" (trim (builtins.readFile ../cmd/dist/VERSION));
-
- srcFiltered = builtins.path {
- name = "${pname}-src";
- path = lib.cleanSource ../.;
- filter = path: type: !(type == "regular" && (lib.hasSuffix ".nix" path || lib.hasSuffix ".py" path)) && !(type == "directory" && lib.hasSuffix "/test" path) && !(type == "directory" && lib.hasSuffix "/cmd/hsu" path);
- };
- vendorHash = null;
-
- src = stdenv.mkDerivation {
- name = "${pname}-src-full";
- inherit version;
- enableParallelBuilding = true;
- src = srcFiltered;
-
- buildInputs = [
- wayland
- wayland-protocols
- ];
-
- nativeBuildInputs = [
- go_1_27
- pkg-config
- wayland-scanner
- ];
-
- buildPhase = "GOCACHE=$(mktemp -d) go generate ./...";
- installPhase = "cp -r . $out";
- };
-
- ldflags =
- lib.attrsets.foldlAttrs
- (
- ldflags: name: value:
- ldflags ++ [ "-X hakurei.app/internal/info.${name}=${value}" ]
- )
- (
- [ "-s -w" ]
- ++ lib.optionals withStatic [
- "-linkmode external"
- "-extldflags \"-static\""
- ]
- )
- {
- buildVersion = "v${version}";
- hakureiPath = "${placeholder "out"}/libexec/hakurei";
- hsuPath = "/run/wrappers/bin/hsu";
- };
-
- env = {
- # use clang instead of gcc
- CC = "clang -O3 -Werror";
- };
-
- buildInputs = [
- libffi
- libseccomp
- fuse3
- acl
- wayland
-
- libxcb
- libxau
- libxdmcp
- ];
-
- nativeBuildInputs = [
- pkg-config
- makeBinaryWrapper
-
- # for container example
- nettools
- ];
-
- postInstall =
- let
- appPackages = [
- glibc
- xdg-dbus-proxy
- ];
- in
- ''
- install -D --target-directory=$out/share/zsh/site-functions cmd/dist/comp/*
-
- mkdir "$out/libexec"
- mv "$out"/bin/* "$out/libexec/"
-
- makeBinaryWrapper "$out/libexec/hakurei" "$out/bin/hakurei" \
- --inherit-argv0 --prefix PATH : ${lib.makeBinPath appPackages}
- '';
-
- passthru = {
- go = go_1_27;
-
- targetPkgs = [
- go_1_27
- clang
- xorgproto
- util-linux
-
- # for go generate
- wayland-protocols
- wayland-scanner
- ]
- ++ buildInputs
- ++ nativeBuildInputs;
- };
-}
diff --git a/test/sandbox/case/default.nix b/test/sandbox/case/default.nix
deleted file mode 100644
index 337f4bf2..00000000
--- a/test/sandbox/case/default.nix
+++ /dev/null
@@ -1,97 +0,0 @@
-system: lib: testProgram:
-let
- fs = mode: dir: data: {
- mode = lib.fromHexString mode;
- inherit
- dir
- data
- ;
- };
-
- ignore = "//ignore";
-
- ent = root: target: vfs_optstr: fstype: source: fs_optstr: {
- id = -1;
- parent = -1;
- inherit
- root
- target
- vfs_optstr
- fstype
- source
- fs_optstr
- ;
- };
-
- importTestCase =
- path:
- import path {
- inherit
- fs
- ent
- ignore
- system
- ;
- };
-
- callTestCase =
- path: identity:
- let
- tc = importTestCase path;
- in
- {
- name = "check-sandbox-${tc.name}";
- inherit identity;
- verbose = true;
- inherit (tc)
- tty
- device
- mapRealUid
- useCommonPaths
- userns
- hostAbstract
- shareRuntime
- shareTmpdir
- ;
- enablements = {
- inherit (tc) x11;
- };
- share = testProgram;
- packages = [ ];
- path = "${testProgram}/bin/hakurei-test";
- args = [
- "hakurei-test"
- "-p"
- "/var/tmp/.hakurei-check-ok.${toString identity}"
- "-t"
- (toString (builtins.toFile "hakurei-${tc.name}-want.json" (builtins.toJSON tc.want)))
- "-s"
- tc.expectedFilter.${system}
- ];
-
- extraPaths =
- if tc.useCommonPaths then
- [ ]
- else
- [
- {
- type = "bind";
- src = "/var/tmp";
- write = true;
- }
- ];
- };
-
- testCaseName = name: "cat.gensokyo.hakurei.test." + name;
-in
-{
- apps = {
- ${testCaseName "preset"} = callTestCase ./preset.nix 1;
- ${testCaseName "tty"} = callTestCase ./tty.nix 2;
- ${testCaseName "mapuid"} = callTestCase ./mapuid.nix 3;
- ${testCaseName "device"} = callTestCase ./device.nix 4;
- ${testCaseName "pdlike"} = callTestCase ./pdlike.nix 5;
- };
-
- pd = importTestCase ./pd.nix;
-}
diff --git a/test/sandbox/case/device.nix b/test/sandbox/case/device.nix
deleted file mode 100644
index 889e0a06..00000000
--- a/test/sandbox/case/device.nix
+++ /dev/null
@@ -1,255 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- sr = { };
- };
- };
-in
-{
- name = "device";
- tty = false;
- device = true;
- mapRealUid = false;
- useCommonPaths = true;
- userns = false;
- x11 = true;
- hostAbstract = false;
- shareRuntime = false;
- shareTmpdir = true;
-
- # 0, PresetStrict
- expectedFilter = {
- x86_64-linux = "e880298df2bd6751d0040fc21bc0ed4c00f95dc0d7ba506c244d8b8cf6866dba8ef4a33296f287b66cccc1d78e97026597f84cc7dec1573e148960fbd35cd735";
- aarch64-linux = "79318538a3dc851314b6bd96f10d5861acb2aa7e13cb8de0619d0f6a76709d67f01ef3fd67e195862b02f9711e5b769bc4d1eb4fc0dfc41a723c89c968a93297";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
- "DISPLAY=unix:/tmp/.X11-unix/X0"
- "HOME=/var/lib/hakurei/u0/a4"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a4"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/65534/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" {
- ".ro-store" = fs "801001fd" null null;
- store = fs "800001ff" null null;
- } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" null null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a4:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a4:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "65534" = fs "800001c0" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "800001f8" {
- ".X11-unix" = fs "801001ff" { X0 = fs "10001fd" null null; } null;
- } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a4 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- cache = fs "800001ed" { private = fs "800001c0" null null; } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10004,gid=10004")
- (ent "/" "/dev" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
- (ent "/" ignore ignore ignore ignore ignore) # not deterministic
- (ent "/" ignore ignore ignore ignore ignore)
- (ent "/" ignore ignore ignore ignore ignore)
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10004,gid=10004")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10004,gid=10004")
- (ent "/tmp/hakurei.0/tmpdir/4" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
- (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/.hakurei/.ro-store" "rw,relatime" "overlay" "overlay" "ro,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,redirect_dir=nofollow,userxattr")
- (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,userxattr")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a4" "/var/lib/hakurei/u0/a4" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = false;
- socket_pathname = true;
- };
-}
diff --git a/test/sandbox/case/mapuid.nix b/test/sandbox/case/mapuid.nix
deleted file mode 100644
index 1b6ef0e7..00000000
--- a/test/sandbox/case/mapuid.nix
+++ /dev/null
@@ -1,282 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- "/dev/dri" = {
- by-path = fs "800001ed" {
- "pci-0000:00:09.0-card" = fs "80001ff" null null;
- "pci-0000:00:09.0-render" = fs "80001ff" null null;
- } null;
- card0 = fs "42001b0" null null;
- renderD128 = fs "42001b6" null null;
- };
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- "/dev/dri" = null;
- sr = { };
- };
- };
-in
-{
- name = "mapuid";
- tty = false;
- device = false;
- mapRealUid = true;
- useCommonPaths = true;
- userns = false;
- x11 = false;
- hostAbstract = false;
- shareRuntime = true;
- shareTmpdir = true;
-
- # 0, PresetStrict
- expectedFilter = {
- x86_64-linux = "e880298df2bd6751d0040fc21bc0ed4c00f95dc0d7ba506c244d8b8cf6866dba8ef4a33296f287b66cccc1d78e97026597f84cc7dec1573e148960fbd35cd735";
- aarch64-linux = "79318538a3dc851314b6bd96f10d5861acb2aa7e13cb8de0619d0f6a76709d67f01ef3fd67e195862b02f9711e5b769bc4d1eb4fc0dfc41a723c89c968a93297";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
- "HOME=/var/lib/hakurei/u0/a3"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a3"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/1000"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/1000/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" {
- ".ro-store" = fs "801001fd" null null;
- store = fs "800001ff" null null;
- } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- core = fs "80001ff" null null;
- dri = fs "800001ed" extraPaths.${system}."/dev/dri" null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:100:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a3:x:1000:100:Hakurei:/var/lib/hakurei/u0/a3:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "1000" = fs "800001f8" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "800001f8" { } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a3 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- cache = fs "800001ed" { private = fs "800001c0" null null; } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10003,gid=10003")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10003,gid=10003")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10003,gid=10003")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10003,gid=10003")
- (ent "/tmp/hakurei.0/runtime/3" "/run/user/1000" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/hakurei.0/tmpdir/3" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
- (ent ignore "/run/user/1000/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/1000/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/.hakurei/.ro-store" "rw,relatime" "overlay" "overlay" "ro,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,redirect_dir=nofollow,userxattr")
- (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,userxattr")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a3" "/var/lib/hakurei/u0/a3" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/1000/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = false;
- socket_pathname = false;
- };
-}
diff --git a/test/sandbox/case/pd.nix b/test/sandbox/case/pd.nix
deleted file mode 100644
index 25f42979..00000000
--- a/test/sandbox/case/pd.nix
+++ /dev/null
@@ -1,206 +0,0 @@
-{
- fs,
- ent,
- ignore,
- ...
-}:
-{
- # 0, PresetExt | PresetDenyDevel
- expectedFilter = {
- x86_64-linux = "c698b081ff957afe17a6d94374537d37f2a63f6f9dd75da7546542407a9e32476ebda3312ba7785d7f618542bcfaf27ca27dcc2dddba852069d28bcfe8cad39a";
- aarch64-linux = "433ce9b911282d6dcc8029319fb79b816b60d5a795ec8fc94344dd027614d68f023166a91bb881faaeeedd26e3d89474e141e5a69a97e93b8984ca8f14999980";
- };
-
- want = {
- env = [
- "HOME=/var/lib/hakurei/u0/a0"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=tty"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" { } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- console = fs "4200190" null null;
- core = fs "80001ff" null null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- kvm = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a0:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a0:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- home = fs "800001ed" { alice = fs "800001c0" null null; } null;
- lib64 = fs "800001ed" { "ld-linux-x86-64.so.2" = fs "80001ff" null null; } null;
- "lost+found" = fs "800001c0" null null;
- nix = fs "800001ed" {
- ".ro-store" = fs "801001fd" null null;
- ".rw-store" = fs "800001ed" null null;
- store = fs "801001fd" null null;
- var = fs "800001ed" {
- log = fs "800001ed" null null;
- nix = fs "800001ed" null null;
- } null;
- } null;
- proc = fs "8000016d" null null;
- root = fs "800001c0" null null;
- run = fs "800001ed" null null;
- srv = fs "800001ed" { } null;
- sys = fs "8000016d" null null;
- tmp = fs "800001f8" { } null;
- usr = fs "800001ed" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001ed" null null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
- (ent "/bin" "/bin" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/home" "/home" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/lib64" "/lib64" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/lost+found" "/lost+found" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/nix" "/nix" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- # systemd nondeterminism: ro-store rw-store
- (ent "/" ignore "rw,nosuid,nodev,relatime" ignore ignore ignore)
- (ent "/" ignore "rw,nosuid,nodev,relatime" ignore ignore ignore)
- (ent "/" "/nix/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/root" "/root" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/run" "rw,nosuid,nodev" "tmpfs" "tmpfs" ignore)
- (ent "/" "/run/keys" "rw,nosuid,nodev,relatime" "ramfs" "ramfs" "rw,mode=750")
- (ent "/" "/run/credentials/systemd-journald.service" "rw,nosuid,nodev,noexec,relatime,nosymfollow" "tmpfs" "none" "ro,size=1024k,nr_inodes=1024,mode=700,noswap")
- (ent "/" "/run/wrappers" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
- (ent "/" "/run/credentials/getty@tty1.service" "rw,nosuid,nodev,noexec,relatime,nosymfollow" "tmpfs" "none" "ro,size=1024k,nr_inodes=1024,mode=700,noswap")
- (ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
- (ent "/srv" "/srv" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/sys" "rw,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/" "/sys/kernel/security" "rw,nosuid,nodev,noexec,relatime" "securityfs" "securityfs" "rw")
- (ent "/../../.." "/sys/fs/cgroup" "rw,nosuid,nodev,noexec,relatime" "cgroup2" "cgroup2" "rw,nsdelegate,memory_recursiveprot,memory_hugetlb_accounting")
- (ent "/" "/sys/fs/pstore" "rw,nosuid,nodev,noexec,relatime" "pstore" "none" "rw")
- (ent "/" "/sys/fs/bpf" "rw,nosuid,nodev,noexec,relatime" "bpf" "bpf" "rw,mode=700")
- # systemd nondeterminism: tracefs debugfs configfs fusectl
- (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
- (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
- (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
- (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
- (ent "/usr" "/usr" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var" "/var" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10000,gid=10000")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10000,gid=10000")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10000,gid=10000")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10000,gid=10000")
- (ent "/tmp/hakurei.0/runtime/0" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/hakurei.0/tmpdir/0" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
- (ent "/kvm" "/dev/kvm" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
- (ent "/" "/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
- (ent "/" "/run/dbus" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = true;
- socket_pathname = false;
- };
-}
diff --git a/test/sandbox/case/pdlike.nix b/test/sandbox/case/pdlike.nix
deleted file mode 100644
index 7f0716fb..00000000
--- a/test/sandbox/case/pdlike.nix
+++ /dev/null
@@ -1,277 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- "/dev/dri" = {
- by-path = fs "800001ed" {
- "pci-0000:00:09.0-card" = fs "80001ff" null null;
- "pci-0000:00:09.0-render" = fs "80001ff" null null;
- } null;
- card0 = fs "42001b0" null null;
- renderD128 = fs "42001b6" null null;
- };
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- "/dev/dri" = null;
- sr = { };
- };
- };
-in
-{
- name = "pdlike";
- tty = true;
- device = false;
- mapRealUid = false;
- useCommonPaths = false;
- userns = true;
- x11 = false;
- hostAbstract = false;
- shareRuntime = true;
- shareTmpdir = true;
-
- # 0, PresetExt | PresetDenyDevel
- expectedFilter = {
- x86_64-linux = "c698b081ff957afe17a6d94374537d37f2a63f6f9dd75da7546542407a9e32476ebda3312ba7785d7f618542bcfaf27ca27dcc2dddba852069d28bcfe8cad39a";
- aarch64-linux = "433ce9b911282d6dcc8029319fb79b816b60d5a795ec8fc94344dd027614d68f023166a91bb881faaeeedd26e3d89474e141e5a69a97e93b8984ca8f14999980";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
- "HOME=/var/lib/hakurei/u0/a5"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a5"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/65534/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" { } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- console = fs "4200190" null null;
- core = fs "80001ff" null null;
- dri = fs "800001ed" extraPaths.${system}."/dev/dri" null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a5:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a5:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "65534" = fs "800001f8" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "800001f8" { } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a5 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10005,gid=10005")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10005,gid=10005")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10005,gid=10005")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10005,gid=10005")
- (ent "/tmp/hakurei.0/runtime/5" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/hakurei.0/tmpdir/5" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
- (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a5" "/var/lib/hakurei/u0/a5" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = false;
- socket_pathname = false;
- };
-}
diff --git a/test/sandbox/case/preset.nix b/test/sandbox/case/preset.nix
deleted file mode 100644
index 33cc3b8b..00000000
--- a/test/sandbox/case/preset.nix
+++ /dev/null
@@ -1,274 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- "/dev/dri" = {
- by-path = fs "800001ed" {
- "pci-0000:00:09.0-card" = fs "80001ff" null null;
- "pci-0000:00:09.0-render" = fs "80001ff" null null;
- } null;
- card0 = fs "42001b0" null null;
- renderD128 = fs "42001b6" null null;
- };
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- "/dev/dri" = null;
- sr = { };
- };
- };
-in
-{
- name = "preset";
- tty = false;
- device = false;
- mapRealUid = false;
- useCommonPaths = false;
- userns = false;
- x11 = false;
- hostAbstract = false;
- shareRuntime = false;
- shareTmpdir = false;
-
- # 0, PresetStrict
- expectedFilter = {
- x86_64-linux = "e880298df2bd6751d0040fc21bc0ed4c00f95dc0d7ba506c244d8b8cf6866dba8ef4a33296f287b66cccc1d78e97026597f84cc7dec1573e148960fbd35cd735";
- aarch64-linux = "79318538a3dc851314b6bd96f10d5861acb2aa7e13cb8de0619d0f6a76709d67f01ef3fd67e195862b02f9711e5b769bc4d1eb4fc0dfc41a723c89c968a93297";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
- "HOME=/var/lib/hakurei/u0/a1"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a1"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/65534/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" { } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- core = fs "80001ff" null null;
- dri = fs "800001ed" extraPaths.${system}."/dev/dri" null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a1:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a1:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "65534" = fs "800001c0" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "801001ff" { } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a1 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10001,gid=10001")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10001,gid=10001")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10001,gid=10001")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10001,gid=10001")
- (ent "/" "/tmp" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10001,gid=10001")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
- (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a1" "/var/lib/hakurei/u0/a1" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = false;
- socket_pathname = false;
- };
-}
diff --git a/test/sandbox/case/tty.nix b/test/sandbox/case/tty.nix
deleted file mode 100644
index 4ba9360e..00000000
--- a/test/sandbox/case/tty.nix
+++ /dev/null
@@ -1,288 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- "/dev/dri" = {
- by-path = fs "800001ed" {
- "pci-0000:00:09.0-card" = fs "80001ff" null null;
- "pci-0000:00:09.0-render" = fs "80001ff" null null;
- } null;
- card0 = fs "42001b0" null null;
- renderD128 = fs "42001b6" null null;
- };
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- "/dev/dri" = null;
- sr = { };
- };
- };
-in
-{
- name = "tty";
- tty = true;
- device = false;
- mapRealUid = false;
- useCommonPaths = true;
- userns = false;
- x11 = true;
- hostAbstract = true;
- shareRuntime = true;
- shareTmpdir = false;
-
- # 0, PresetExt | PresetDenyNS | PresetDenyDevel
- expectedFilter = {
- x86_64-linux = "0b76007476c1c9e25dbf674c29fdf609a1656a70063e49327654e1b5360ad3da06e1a3e32bf80e961c5516ad83d4b9e7e9bde876a93797e27627d2555c25858b";
- aarch64-linux = "cf1f4dc87436ba8ec95d268b663a6397bb0b4a5ac64d8557e6cc529d8b0f6f65dad3a92b62ed29d85eee9c6dde1267757a4d0f86032e8a45ca1bceadfa34cf5e";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
- "DISPLAY=:0"
- "HOME=/var/lib/hakurei/u0/a2"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a2"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/65534/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" {
- ".ro-store" = fs "801001fd" null null;
- store = fs "800001ff" null null;
- } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- console = fs "4200190" null null;
- core = fs "80001ff" null null;
- dri = fs "800001ed" extraPaths.${system}."/dev/dri" null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a2:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a2:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "65534" = fs "800001f8" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "801001ff" {
- ".X11-unix" = fs "801001ff" { X0 = fs "10001fd" null null; } null;
- } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a2 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- cache = fs "800001ed" { private = fs "800001c0" null null; } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10002,gid=10002")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10002,gid=10002")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10002,gid=10002")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10002,gid=10002")
- (ent "/tmp/hakurei.0/runtime/2" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/tmp" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10002,gid=10002")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
- (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/.hakurei/.ro-store" "rw,relatime" "overlay" "overlay" "ro,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,redirect_dir=nofollow,userxattr")
- (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,uuid=on,userxattr")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a2" "/var/lib/hakurei/u0/a2" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = true;
- socket_pathname = true;
- };
-}
diff --git a/test/sandbox/configuration.nix b/test/sandbox/configuration.nix
deleted file mode 100644
index bc189f7d..00000000
--- a/test/sandbox/configuration.nix
+++ /dev/null
@@ -1,113 +0,0 @@
-{
- lib,
- pkgs,
- config,
- ...
-}:
-let
- testProgram = pkgs.callPackage ./tool/package.nix { inherit (config.environment.hakurei.package) version; };
- testCases = import ./case pkgs.stdenv.hostPlatform.system lib testProgram;
-in
-{
- users.users = {
- alice = {
- isNormalUser = true;
- description = "Alice Foobar";
- password = "foobar";
- uid = 1000;
- };
- };
-
- home-manager.users.alice.home.stateVersion = "24.11";
-
- # Automatically login on tty1 as a normal user:
- services.getty.autologinUser = "alice";
-
- environment = {
- systemPackages = [
- # For checking seccomp outcome:
- testProgram
-
- # For checking pd outcome:
- (pkgs.writeShellScriptBin "check-sandbox-pd" ''
- hakurei -v exec hakurei-test \
- -p "/var/tmp/.hakurei-check-ok.0" \
- -t ${toString (builtins.toFile "hakurei-pd-want.json" (builtins.toJSON testCases.pd.want))} \
- -s ${testCases.pd.expectedFilter.${pkgs.stdenv.hostPlatform.system}} "$@"
- '')
- ];
-
- variables = {
- SWAYSOCK = "/tmp/sway-ipc.sock";
- WLR_RENDERER = "pixman";
- };
- };
-
- # Automatically configure and start Sway when logging in on tty1:
- programs.bash.loginShellInit = ''
- if [ "$(tty)" = "/dev/tty1" ]; then
- set -e
-
- mkdir -p ~/.config/sway
- (sed s/Mod4/Mod1/ /etc/sway/config &&
- echo 'output * bg ${pkgs.nixos-artwork.wallpapers.simple-light-gray.gnomeFilePath} fill' &&
- echo 'output Virtual-1 res 1680x1050') > ~/.config/sway/config
-
- sway --validate
- systemd-cat --identifier=session sway && touch /tmp/sway-exit-ok
- fi
- '';
-
- programs.sway.enable = true;
-
- virtualisation.qemu.options = [
- # Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch:
- "-vga none -device virtio-gpu-pci"
-
- # Increase performance:
- "-smp 8"
- ];
-
- environment.hakurei = {
- enable = true;
- stateDir = "/var/lib/hakurei";
- users.alice = 0;
-
- extraHomeConfig = {
- home.stateVersion = "23.05";
- };
-
- commonPaths = [
- {
- type = "bind";
- src = "/var/tmp";
- write = true;
- }
- {
- type = "bind";
- src = "/var/cache";
- write = true;
- }
- {
- type = "overlay";
- dst = "/.hakurei/.ro-store";
- lower = [
- "/nix/.ro-store"
- "/nix/.rw-store/upper"
- ];
- }
- {
- type = "overlay";
- dst = "/.hakurei/store";
- lower = [
- "/nix/.ro-store"
- "/nix/.rw-store/upper"
- ];
- upper = "/tmp/.hakurei-store-rw/upper";
- work = "/tmp/.hakurei-store-rw/work";
- }
- ];
-
- inherit (testCases) apps;
- };
-}
diff --git a/test/sandbox/default.nix b/test/sandbox/default.nix
deleted file mode 100644
index 47a59de9..00000000
--- a/test/sandbox/default.nix
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- lib,
- testers,
-
- self,
- withRace ? false,
-}:
-
-testers.nixosTest {
- name = "hakurei-sandbox" + (if withRace then "-race" else "");
- nodes.machine =
- { options, pkgs, ... }:
- {
- # Run with Go race detector:
- environment.hakurei = lib.mkIf withRace rec {
- # race detector does not support static linking
- package = (pkgs.callPackage ../package.nix { }).overrideAttrs (previousAttrs: {
- env = previousAttrs.env // {
- GOFLAGS = previousAttrs.env.GOFLAGS + " -race";
- };
- });
- hsuPackage = options.environment.hakurei.hsuPackage.default.override { hakurei = package; };
- };
-
- imports = [
- ./configuration.nix
-
- self.nixosModules.hakurei
- self.inputs.home-manager.nixosModules.home-manager
- ];
- };
-
- # adapted from nixos sway integration tests
-
- # testScriptWithTypes:49: error: Cannot call function of unknown type
- # (machine.succeed if succeed else machine.execute)(
- # ^
- # Found 1 error in 1 file (checked 1 source file)
- skipTypeCheck = true;
- testScript = builtins.readFile ./test.py;
-}
diff --git a/test/sandbox/test.py b/test/sandbox/test.py
deleted file mode 100644
index a431daab..00000000
--- a/test/sandbox/test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-import json
-import shlex
-
-q = shlex.quote
-
-
-def swaymsg(command: str = "", succeed=True, type="command"):
- assert command != "" or type != "command", "Must specify command or type"
- shell = q(f"swaymsg -t {q(type)} -- {q(command)}")
- with machine.nested(
- f"sending swaymsg {shell!r}" + " (allowed to fail)" * (not succeed)
- ):
- ret = (machine.succeed if succeed else machine.execute)(
- f"su - alice -c {shell}"
- )
-
- # execute also returns a status code, but disregard.
- if not succeed:
- _, ret = ret
-
- if not succeed and not ret:
- return None
-
- parsed = json.loads(ret)
- return parsed
-
-
-def check_filter(check_offset, name, pname):
- pid = int(machine.wait_until_succeeds(f"pgrep -U {10000+check_offset} -x {pname}"))
- hash = machine.succeed(f"sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-1 check-sandbox-{name} hash")
- print(machine.succeed(f"hakurei-test -s {hash} filter {pid}"))
-
-
-start_all()
-machine.wait_for_unit("multi-user.target")
-
-# To check hakurei's version:
-print(machine.succeed("sudo -u alice -i hakurei version"))
-
-# Wait for Sway to complete startup:
-machine.wait_for_file("/run/user/1000/wayland-1")
-machine.wait_for_file("/tmp/sway-ipc.sock")
-
-# Check pd seccomp outcome:
-swaymsg("exec hakurei exec cat")
-check_filter(0, "pdlike", "cat")
-
-# Check fd leak:
-swaymsg("exec exec 127</proc/cmdline && hakurei -v exec sleep infinity")
-pd_identity0_sleep_pid = int(machine.wait_until_succeeds("pgrep -U 10000 -x sleep"))
-print(machine.succeed(f"hakurei-test fd {pd_identity0_sleep_pid}"))
-machine.succeed(f"kill -INT {pd_identity0_sleep_pid}")
-
-# Verify capabilities/securebits in user namespace:
-print(machine.succeed("sudo -u alice -i hakurei exec capsh --print"))
-print(machine.succeed("sudo -u alice -i hakurei exec capsh --has-no-new-privs"))
-print(machine.fail("sudo -u alice -i hakurei exec capsh --has-a=CAP_SYS_ADMIN"))
-print(machine.fail("sudo -u alice -i hakurei exec capsh --has-b=CAP_SYS_ADMIN"))
-print(machine.fail("sudo -u alice -i hakurei exec capsh --has-i=CAP_SYS_ADMIN"))
-print(machine.fail("sudo -u alice -i hakurei exec capsh --has-p=CAP_SYS_ADMIN"))
-print(machine.fail("sudo -u alice -i hakurei exec umount -R /dev"))
-
-# Check sandbox outcome:
-machine.succeed("install -dm0777 /tmp/.hakurei-store-rw/{upper,work}")
-check_offset = 0
-def check_sandbox(name):
- global check_offset
- swaymsg(f"exec script /dev/null -E always -qec check-sandbox-{name}")
- machine.wait_for_file(f"/var/tmp/.hakurei-check-ok.{check_offset}")
- check_filter(check_offset, name, "hakurei-test")
- check_offset += 1
-
-
-check_sandbox("pd")
-check_sandbox("preset")
-check_sandbox("tty")
-check_sandbox("mapuid")
-check_sandbox("device")
-check_sandbox("pdlike")
-
-# Exit Sway and verify process exit status 0:
-machine.wait_until_fails("pgrep -x hakurei")
-swaymsg("exit", succeed=False)
-machine.wait_for_file("/tmp/sway-exit-ok")
-
-# Print hakurei runDir contents:
-print(machine.fail("ls /run/user/1000/hakurei"))
-machine.succeed("find /tmp -maxdepth 1 -type d -name '.hakurei-shim-*' -print -exec false '{}' +")
diff --git a/test/sandbox/tool/main.go b/test/sandbox/tool/main.go
deleted file mode 100644
index 889142d4..00000000
--- a/test/sandbox/tool/main.go
+++ /dev/null
@@ -1,106 +0,0 @@
-//go:build testtool
-
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "os"
- "os/signal"
- "strconv"
- "strings"
- "syscall"
-
- "hakurei.app/test/internal/sandbox"
-)
-
-var (
- flagMarkerPath string
- flagTestCase string
- flagBpfHash string
-)
-
-func init() {
- flag.StringVar(&flagMarkerPath, "p", "/tmp/sandbox-ok", "Pathname of completion marker")
- flag.StringVar(&flagTestCase, "t", "", "Nix store path to test case file")
- flag.StringVar(&flagBpfHash, "s", "", "String representation of expected bpf sha512 hash")
-}
-
-func main() {
- log.SetFlags(0)
- log.SetPrefix("test: ")
- flag.Parse()
-
- args := flag.Args()
- if len(args) < 1 {
- s := make(chan os.Signal, 1)
- signal.Notify(s, syscall.SIGINT)
- go func() { <-s; log.Println("exiting on signal (likely from verifier)"); os.Exit(0) }()
-
- (&sandbox.T{FS: os.DirFS("/")}).MustCheckFile(flagTestCase)
- if _, err := os.Create(flagMarkerPath); err != nil {
- log.Fatalf("cannot create success marker: %v", err)
- }
- log.Printf("blocking for seccomp check (%s)", flagMarkerPath)
- select {}
- return
- }
-
- switch args[0] {
- case "filter":
- if len(args) != 2 {
- log.Fatal("invalid argument")
- }
-
- if pid, err := strconv.Atoi(strings.TrimSpace(args[1])); err != nil {
- log.Fatalf("%s", err)
- } else if pid < 1 {
- log.Fatalf("%d out of range", pid)
- } else {
- sandbox.MustCheckFilter(pid, flagBpfHash)
- if err = syscall.Kill(pid, syscall.SIGINT); err != nil {
- log.Fatalf("cannot signal check process: %v", err)
- }
- }
-
- case "hash": // this eases the pain of passing the hash to python
- fmt.Print(flagBpfHash)
-
- case "fd":
- if len(args) != 2 {
- log.Fatal("invalid argument")
- }
- prefix := fmt.Sprintf("/proc/%s/fd/", args[1])
-
- var fail bool
- if entries, err := os.ReadDir(prefix); err != nil {
- log.Fatal(err.Error())
- } else {
- for _, ent := range entries {
- var fd int
- if fd, err = strconv.Atoi(ent.Name()); err != nil {
- log.Fatal(err.Error())
- }
-
- // skip standard streams
- if fd <= 2 {
- continue
- }
- fail = true
-
- var d string
- if d, err = os.Readlink(prefix + ent.Name()); err != nil {
- log.Fatal(err.Error())
- }
- log.Printf("[FAIL] extra fd %d -> %s", fd, d)
- }
- }
- if fail {
- log.Fatal("[FAIL] file descriptors leaked")
- }
-
- default:
- log.Fatal("invalid argument")
- }
-}
diff --git a/test/sandbox/tool/package.nix b/test/sandbox/tool/package.nix
deleted file mode 100644
index 13e18272..00000000
--- a/test/sandbox/tool/package.nix
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- lib,
- buildGoModule,
- pkg-config,
- util-linux,
-
- version,
-}:
-buildGoModule rec {
- pname = "check-sandbox";
- inherit version;
-
- src = builtins.path {
- name = "${pname}-src";
- path = lib.cleanSource ../../.;
- filter = path: type: (type == "directory") || (type == "regular" && lib.hasSuffix ".go" path);
- };
- vendorHash = null;
-
- tags = [ "testtool" ];
-
- buildInputs = [ util-linux ];
- nativeBuildInputs = [ pkg-config ];
-
- preBuild = ''
- go mod init hakurei.app/test >& /dev/null
- '';
-
- postInstall = ''
- mv $out/bin/tool $out/bin/hakurei-test
- '';
-}
diff --git a/test/sharefs/configuration.nix b/test/sharefs/configuration.nix
deleted file mode 100644
index 05d67dcb..00000000
--- a/test/sharefs/configuration.nix
+++ /dev/null
@@ -1,44 +0,0 @@
-{ pkgs, ... }:
-{
- users.users = {
- alice = {
- isNormalUser = true;
- description = "Alice Foobar";
- password = "foobar";
- uid = 1000;
- };
- };
-
- home-manager.users.alice.home.stateVersion = "24.11";
-
- # Automatically login on tty1 as a normal user:
- services.getty.autologinUser = "alice";
-
- environment = {
- # For benchmarking sharefs:
- systemPackages = [ pkgs.fsmark ];
- };
-
- virtualisation = {
- # Hopefully reduces spurious test failures:
- memorySize = if pkgs.stdenv.hostPlatform.is32bit then 2046 else 8192;
-
- diskSize = 6 * 1024;
-
- qemu.options = [
- # Increase test performance:
- "-smp 16"
- ];
- };
-
- environment.hakurei = rec {
- enable = true;
- stateDir = "/var/lib/hakurei";
- sharefs.source = "${stateDir}/sdcard";
- users.alice = 0;
-
- extraHomeConfig = {
- home.stateVersion = "23.05";
- };
- };
-}
diff --git a/test/sharefs/default.nix b/test/sharefs/default.nix
deleted file mode 100644
index e963eaa6..00000000
--- a/test/sharefs/default.nix
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- testers,
-
- system,
- self,
-}:
-testers.nixosTest {
- name = "sharefs";
- nodes.machine =
- { options, pkgs, ... }:
- let
- fhs =
- let
- hakurei = options.environment.hakurei.package.default;
- in
- pkgs.buildFHSEnv {
- pname = "hakurei-fhs";
- inherit (hakurei) version;
- targetPkgs = _: hakurei.targetPkgs;
- extraOutputsToInstall = [ "dev" ];
- profile = ''
- export PKG_CONFIG_PATH="/usr/share/pkgconfig:$PKG_CONFIG_PATH"
- '';
- };
- in
- {
- environment.systemPackages = [
- # For go tests:
- (pkgs.writeShellScriptBin "sharefs-workload-hakurei-tests" ''
- cp -r "${self.packages.${system}.hakurei.src}" "/sdcard/hakurei" && cd "/sdcard/hakurei"
- ${fhs}/bin/hakurei-fhs -c 'ROSA_SKIP_BINFMT=1 CC="clang -O3 -Werror" go test ./...'
- '')
- ];
-
- imports = [
- ./configuration.nix
-
- self.nixosModules.hakurei
- self.inputs.home-manager.nixosModules.home-manager
- ];
- };
-
- testScript = builtins.readFile ./test.py;
-}
diff --git a/test/sharefs/raceattr.go b/test/sharefs/raceattr.go
deleted file mode 100644
index 412cb2b3..00000000
--- a/test/sharefs/raceattr.go
+++ /dev/null
@@ -1,122 +0,0 @@
-//go:build raceattr
-
-// The raceattr program reproduces vfs inode file attribute race.
-//
-// Even though libfuse high-level API presents the address of a struct stat
-// alongside struct fuse_context, file attributes are actually inherent to the
-// inode, instead of the specific call from userspace. The kernel implementation
-// in fs/fuse/xattr.c appears to make stale data in the inode (set by a previous
-// call) impossible or very unlikely to reach userspace via the stat family of
-// syscalls. However, when using default_permissions to have the VFS check
-// permissions, this race still happens, despite the resulting struct stat being
-// correct when overriding the check via capabilities otherwise.
-//
-// This program reproduces the failure, but because of its continuous nature, it
-// is provided independent of the vm integration test suite.
-package main
-
-import (
- "context"
- "flag"
- "log"
- "os"
- "os/signal"
- "runtime"
- "sync"
- "sync/atomic"
- "syscall"
-)
-
-func newStatAs(
- ctx context.Context, cancel context.CancelFunc,
- n *atomic.Uint64, ok *atomic.Bool,
- uid uint32, pathname string,
- continuous bool,
-) func() {
- return func() {
- runtime.LockOSThread()
- defer cancel()
-
- if _, _, errno := syscall.Syscall(
- syscall.SYS_SETUID, uintptr(uid),
- 0, 0,
- ); errno != 0 {
- cancel()
- log.Printf("cannot set uid to %d: %s", uid, errno)
- }
-
- var stat syscall.Stat_t
- for {
- if ctx.Err() != nil {
- return
- }
-
- if err := syscall.Lstat(pathname, &stat); err != nil {
- // SHAREFS_PERM_DIR not world executable, or
- // SHAREFS_PERM_REG not world readable
- if !continuous {
- cancel()
- }
- ok.Store(true)
- log.Printf("uid %d: %v", uid, err)
- } else if stat.Uid != uid {
- // appears to be unreachable
- if !continuous {
- cancel()
- }
- ok.Store(true)
- log.Printf("got uid %d instead of %d", stat.Uid, uid)
- }
- n.Add(1)
- }
- }
-}
-
-func main() {
- log.SetFlags(0)
- log.SetPrefix("raceattr: ")
-
- p := flag.String("target", "/sdcard/raceattr", "pathname of test file")
- u0 := flag.Int("uid0", 1<<10-1, "first uid")
- u1 := flag.Int("uid1", 1<<10-2, "second uid")
- count := flag.Int("count", 1, "threads per uid")
- continuous := flag.Bool("continuous", false, "keep running even after reproduce")
- flag.Parse()
-
- if os.Geteuid() != 0 {
- log.Fatal("this program must run as root")
- }
-
- ctx, cancel := signal.NotifyContext(
- context.Background(),
- syscall.SIGINT,
- syscall.SIGTERM,
- syscall.SIGHUP,
- )
-
- if err := os.WriteFile(*p, nil, 0); err != nil {
- log.Fatal(err)
- }
-
- var (
- wg sync.WaitGroup
-
- n atomic.Uint64
- ok atomic.Bool
- )
-
- if *count < 1 {
- *count = 1
- }
- for range *count {
- wg.Go(newStatAs(ctx, cancel, &n, &ok, uint32(*u0), *p, *continuous))
- if *u1 >= 0 {
- wg.Go(newStatAs(ctx, cancel, &n, &ok, uint32(*u1), *p, *continuous))
- }
- }
-
- wg.Wait()
- if !*continuous && ok.Load() {
- log.Printf("reproduced after %d calls", n.Load())
- }
-}
diff --git a/test/sharefs/test.py b/test/sharefs/test.py
deleted file mode 100644
index 4b925c9c..00000000
--- a/test/sharefs/test.py
+++ /dev/null
@@ -1,60 +0,0 @@
-start_all()
-machine.wait_for_unit("multi-user.target")
-
-# To check sharefs version:
-print(machine.succeed("sharefs -V"))
-
-# Make sure sharefs started:
-machine.wait_for_unit("sdcard.mount")
-
-machine.succeed("mkdir /mnt")
-def check_bad_opts_output(opts, want, source="/etc", privileged=False):
- output = machine.fail(("" if privileged else "sudo -u alice -i ") + f"sharefs -f -o source={source},{opts} /mnt 2>&1")
- if output != want:
- raise Exception(f"unexpected output: {output}")
-
-# Malformed setuid/setgid representation:
-check_bad_opts_output("setuid=ff", "sharefs: invalid value for option setuid\n")
-check_bad_opts_output("setgid=ff", "sharefs: invalid value for option setgid\n")
-
-# Bounds check for setuid/setgid:
-check_bad_opts_output("setuid=0", "sharefs: invalid value for option setuid\n")
-check_bad_opts_output("setgid=0", "sharefs: invalid value for option setgid\n")
-check_bad_opts_output("setuid=-1", "sharefs: invalid value for option setuid\n")
-check_bad_opts_output("setgid=-1", "sharefs: invalid value for option setgid\n")
-
-# Non-root setuid/setgid:
-check_bad_opts_output("setuid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
-check_bad_opts_output("setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
-check_bad_opts_output("setuid=1023,setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n")
-check_bad_opts_output("mkdir", "sharefs: mkdir has no effect when not starting as root\n")
-
-# Starting as root without setuid/setgid:
-check_bad_opts_output("allow_other", "sharefs: setuid and setgid must not be 0\n", privileged=True)
-check_bad_opts_output("setuid=1023", "sharefs: setuid and setgid must not be 0\n", privileged=True)
-check_bad_opts_output("setgid=1023", "sharefs: setuid and setgid must not be 0\n", privileged=True)
-
-# Make sure nothing actually got mounted:
-machine.fail("umount /mnt")
-machine.succeed("rmdir /mnt")
-
-# Unprivileged mount/unmount:
-machine.succeed("sudo -u alice -i mkdir /home/alice/{sdcard,persistent}")
-machine.succeed("sudo -u alice -i sharefs -o source=/home/alice/persistent /home/alice/sdcard")
-machine.succeed("sudo -u alice -i touch /home/alice/sdcard/check")
-machine.succeed("sudo -u alice -i umount /home/alice/sdcard")
-machine.succeed("sudo -u alice -i rm /home/alice/persistent/check")
-machine.succeed("sudo -u alice -i rmdir /home/alice/{sdcard,persistent}")
-
-# Benchmark sharefs:
-machine.succeed("fs_mark -v -d /sdcard/fs_mark -l /tmp/fs_log.txt")
-machine.copy_from_vm("/tmp/fs_log.txt", "")
-
-# Check permissions:
-machine.succeed("sudo -u sharefs touch /var/lib/hakurei/sdcard/fs_mark/.check")
-machine.succeed("sudo -u sharefs rm /var/lib/hakurei/sdcard/fs_mark/.check")
-machine.succeed("sudo -u alice rm -rf /sdcard/fs_mark")
-machine.fail("ls /var/lib/hakurei/sdcard/fs_mark")
-
-# Run hakurei tests on sharefs:
-machine.succeed("sudo -u alice -i sharefs-workload-hakurei-tests")
diff --git a/test/test.py b/test/test.py
deleted file mode 100644
index 98f08275..00000000
--- a/test/test.py
+++ /dev/null
@@ -1,315 +0,0 @@
-import json
-import shlex
-
-q = shlex.quote
-NODE_GROUPS = ["nodes", "floating_nodes"]
-
-
-def swaymsg(command: str = "", succeed=True, type="command"):
- assert command != "" or type != "command", "Must specify command or type"
- shell = q(f"swaymsg -t {q(type)} -- {q(command)}")
- with machine.nested(f"sending swaymsg {shell!r}" + " (allowed to fail)" * (not succeed)):
- ret = (machine.succeed if succeed else machine.execute)(
- f"su - alice -c {shell}"
- )
-
- # execute also returns a status code, but disregard.
- if not succeed:
- _, ret = ret
-
- if not succeed and not ret:
- return None
-
- parsed = json.loads(ret)
- return parsed
-
-
-def walk(tree):
- yield tree
- for group in NODE_GROUPS:
- for node in tree.get(group, []):
- yield from walk(node)
-
-
-def wait_for_window(pattern):
- def func(last_chance):
- nodes = (node["name"] for node in walk(swaymsg(type="get_tree")))
-
- if last_chance:
- nodes = list(nodes)
- machine.log(f"Last call! Current list of windows: {nodes}")
-
- return any(pattern in name for name in nodes)
-
- retry(func)
-
-
-def collect_state_ui(name):
- swaymsg(f"exec hakurei ps > '/tmp/{name}.ps'")
- machine.wait_for_file(f"/tmp/{name}.ps")
- machine.copy_from_vm(f"/tmp/{name}.ps", "")
- swaymsg(f"exec hakurei --json ps > '/tmp/{name}.json'")
- machine.wait_for_file(f"/tmp/{name}.json")
- machine.copy_from_vm(f"/tmp/{name}.json", "")
- machine.screenshot(name)
-
-
-def check_state(name, enablements):
- instances = json.loads(machine.succeed("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei --json ps"))
- if len(instances) != 1:
- raise Exception(f"unexpected state length {len(instances)}")
- instance = instances[0]
-
- command = f"{name}-start"
- if not (instance['container']['path'].startswith("/nix/store/")) or not (instance['container']['path'].endswith(command)):
- raise Exception(f"unexpected path {instance['path']}")
-
- if len(instance['container']['args']) != 1 or instance['container']['args'][0] != command:
- raise Exception(f"unexpected args {instance['args']}")
-
- if instance['enablements'] != enablements:
- raise Exception(f"unexpected enablements {instance['enablements']['enablements']}")
-
-
-def hakurei(command):
- swaymsg(f"exec hakurei {command}")
-
-
-start_all()
-machine.wait_for_unit("multi-user.target")
-
-# To check hakurei's version:
-print(machine.succeed("sudo -u alice -i hakurei version"))
-
-# Wait for Sway to complete startup:
-machine.wait_for_file("/run/user/1000/wayland-1")
-machine.wait_for_file("/tmp/sway-ipc.sock")
-
-# Run hakurei Go tests outside of nix build in the background:
-swaymsg("exec hakurei-test")
-
-# Deny unmapped uid:
-denyOutput = machine.fail("sudo -u untrusted -i hakurei exec &>/dev/stdout")
-print(denyOutput)
-denyOutputVerbose = machine.fail("sudo -u untrusted -i hakurei -v exec &>/dev/stdout")
-print(denyOutputVerbose)
-
-# Direct hsu call:
-userid = machine.succeed("sudo -u alice -i hsu")
-if userid != "0":
- raise Exception(f"unexpected userid: {userid}")
-
-# Verify hsu fault behaviour:
-if denyOutput != "hsu: uid 1001 is not in the hsurc file\n":
- raise Exception(f"unexpected deny output:\n{denyOutput}")
-if denyOutputVerbose != "hsu: uid 1001 is not in the hsurc file\nhakurei: *cannot retrieve user id from setuid wrapper: current user is not in the hsurc file\n":
- raise Exception(f"unexpected deny verbose output:\n{denyOutputVerbose}")
-
-# Verify timeout behaviour:
-machine.succeed('sudo -u alice -i hakurei-check-linger-timeout > /var/tmp/linger-stdout 2> /var/tmp/linger-stderr || (cat /var/tmp/linger-stderr; false)')
-linger_stdout = machine.succeed("cat /var/tmp/linger-stdout")
-linger_stderr = machine.succeed("cat /var/tmp/linger-stderr")
-if linger_stdout != "":
- raise Exception(f"unexpected stdout: {linger_stdout}")
-if linger_stderr != "init: timeout exceeded waiting for lingering processes\n":
- raise Exception(f"unexpected stderr: {linger_stderr}")
-
-check_offset = 0
-
-
-def hakurei_identity(offset):
- return 1+check_offset+offset
-
-
-# Start hakurei permissive defaults outside Wayland session:
-print(machine.succeed("sudo -u alice -i hakurei -v exec -a 0 touch /tmp/pd-bare-ok"))
-machine.wait_for_file("/tmp/hakurei.0/tmpdir/0/pd-bare-ok")
-
-# Verify silent output permissive defaults:
-output = machine.succeed("sudo -u alice -i hakurei exec -a 0 true &>/dev/stdout")
-if output != "":
- raise Exception(f"unexpected output\n{output}")
-
-# Verify silent output permissive defaults signal:
-def silent_output_interrupt(flags):
- swaymsg("exec foot")
- wait_for_window("alice@machine")
- # identity 0 does not have home-manager
- machine.send_chars(f"exec hakurei exec {flags}-a 0 sh -c 'export PATH=/run/current-system/sw/bin:$PATH && touch /tmp/pd-silent-ready && sleep infinity' &>/tmp/pd-silent\n")
- machine.wait_for_file("/tmp/hakurei.0/tmpdir/0/pd-silent-ready")
- machine.succeed("rm /tmp/hakurei.0/tmpdir/0/pd-silent-ready")
- machine.send_key("ctrl-c")
- machine.wait_until_fails("pgrep foot")
- machine.wait_until_fails(f"pgrep -u alice -f 'hakurei exec {flags}-a 0 '")
- output = machine.succeed("cat /tmp/pd-silent && rm /tmp/pd-silent")
- if output != "":
- raise Exception(f"unexpected output\n{output}")
-
-
-silent_output_interrupt("")
-silent_output_interrupt("--dbus ") # this one is especially painful as it maintains a helper
-silent_output_interrupt("--wayland -X --dbus --pulse ")
-
-# Verify graceful failure on bad Wayland display name:
-print(machine.fail("sudo -u alice -i hakurei -v exec --wayland true"))
-
-# Start hakurei permissive defaults within Wayland session:
-hakurei('-v exec --wayland --dbus --dbus-log notify-send -a "NixOS Tests" "Test notification" "Notification from within sandbox." && touch /tmp/dbus-ok')
-machine.wait_for_file("/tmp/dbus-ok")
-collect_state_ui("dbus_notify_exited")
-# not in pid namespace, verify termination
-machine.wait_until_fails("pgrep xdg-dbus-proxy")
-machine.succeed("pkill -9 mako")
-
-# Check revert type selection:
-hakurei("-v exec --wayland -X --dbus --pulse -u p0 foot && touch /tmp/p0-exit-ok")
-wait_for_window("p0@machine")
-print(machine.succeed("getfacl --absolute-names --omit-header --numeric /tmp/hakurei.0/runtime | grep 10000"))
-hakurei("-v exec --wayland -X --dbus --pulse -u p1 foot && touch /tmp/p1-exit-ok")
-wait_for_window("p1@machine")
-print(machine.succeed("getfacl --absolute-names --omit-header --numeric /tmp/hakurei.0/runtime | grep 10000"))
-machine.send_chars("exit\n")
-machine.wait_for_file("/tmp/p1-exit-ok")
-# Verify acl is kept alive:
-print(machine.succeed("getfacl --absolute-names --omit-header --numeric /tmp/hakurei.0/runtime | grep 10000"))
-machine.send_chars("exit\n")
-machine.wait_for_file("/tmp/p0-exit-ok")
-machine.fail("getfacl --absolute-names --omit-header --numeric /tmp/hakurei.0/runtime | grep 10000")
-
-# Check invalid identifier fd behaviour:
-machine.fail('echo \'{"container":{"shell":"/proc/nonexistent","home":"/proc/nonexistent","path":"/proc/nonexistent"}}\' | sudo -u alice -i hakurei -v run --identifier-fd 32767 - 2>&1 | tee > /tmp/invalid-identifier-fd')
-machine.wait_for_file("/tmp/invalid-identifier-fd")
-print(machine.succeed('grep "^hakurei: cannot write identifier: bad file descriptor$" /tmp/invalid-identifier-fd'))
-
-# Check interrupt shim behaviour:
-swaymsg("exec sh -c 'ne-foot; echo -n $? > /tmp/monitor-exit-code'")
-wait_for_window(f"u0_a{hakurei_identity(0)}@machine")
-machine.succeed("pkill -INT -f 'hakurei -v run '")
-machine.wait_until_fails("pgrep foot")
-machine.wait_for_file("/tmp/monitor-exit-code")
-interrupt_exit_code = int(machine.succeed("cat /tmp/monitor-exit-code"))
-if interrupt_exit_code != 230:
- raise Exception(f"unexpected exit code {interrupt_exit_code}")
-
-# Check interrupt shim behaviour immediate termination:
-swaymsg("exec sh -c 'ne-foot-immediate; echo -n $? > /tmp/monitor-exit-code'")
-wait_for_window(f"u0_a{hakurei_identity(0)}@machine")
-machine.succeed("pkill -INT -f 'hakurei -v run '")
-machine.wait_until_fails("pgrep foot")
-machine.wait_for_file("/tmp/monitor-exit-code")
-interrupt_exit_code = int(machine.succeed("cat /tmp/monitor-exit-code"))
-if interrupt_exit_code != 254:
- raise Exception(f"unexpected exit code {interrupt_exit_code}")
-
-# Check shim SIGCONT from unexpected process behaviour:
-swaymsg("exec sh -c 'ne-foot &> /tmp/shim-cont-unexpected-pid'")
-wait_for_window(f"u0_a{hakurei_identity(0)}@machine")
-machine.succeed("pkill -CONT -f 'hakurei shim'")
-machine.succeed("pkill -INT -f 'hakurei -v run '")
-machine.wait_until_fails("pgrep foot")
-machine.wait_for_file("/tmp/shim-cont-unexpected-pid")
-print(machine.succeed('grep "shim: got SIGCONT from unexpected process$" /tmp/shim-cont-unexpected-pid'))
-
-# Check setscheduler:
-sched_unset = int(machine.succeed("sudo -u alice -i hakurei -v exec cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2"))
-if sched_unset != 0:
- raise Exception(f"unexpected unset policy: {sched_unset}")
-sched_idle = int(machine.succeed("sudo -u alice -i hakurei -v exec --policy=idle cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2"))
-if sched_idle != 5:
- raise Exception(f"unexpected idle policy: {sched_idle}")
-sched_rr = int(machine.succeed("sudo -u alice -i hakurei -v exec --policy=rr cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2"))
-if sched_rr != 2:
- raise Exception(f"unexpected round-robin policy: {sched_idle}")
-
-# Start app (foot) with Wayland enablement:
-swaymsg("exec ne-foot")
-wait_for_window(f"u0_a{hakurei_identity(0)}@machine")
-machine.send_chars("clear; wayland-info && touch /var/tmp/client-ok\n")
-machine.wait_for_file("/var/tmp/client-ok")
-collect_state_ui("foot_wayland")
-check_state("ne-foot", {"wayland": True})
-# Verify lack of acl on XDG_RUNTIME_DIR:
-machine.fail(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(0) + 10000}")
-machine.send_chars("exit\n")
-machine.wait_until_fails("pgrep foot")
-machine.fail(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(0) + 10000}")
-
-# Test pipewire-pulse:
-swaymsg("exec pa-foot")
-wait_for_window(f"u0_a{hakurei_identity(1)}@machine")
-machine.send_chars("clear; pactl info && touch /var/tmp/pulse-ok\n")
-machine.wait_for_file("/var/tmp/pulse-ok")
-collect_state_ui("pulse_wayland")
-check_state("pa-foot", {"wayland": True, "pipewire": True})
-machine.fail("find /tmp -maxdepth 1 -type d -name '.hakurei-shim-*' -print -exec false '{}' +")
-machine.send_chars("exit\n")
-machine.wait_until_fails("pgrep foot")
-machine.wait_until_fails("pgrep -x hakurei")
-machine.succeed("find /tmp -maxdepth 1 -type d -name '.hakurei-shim-*' -print -exec false '{}' +")
-# Test PipeWire SecurityContext:
-machine.succeed("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei -v exec --pulse pactl info")
-machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei -v exec --pulse pactl set-sink-mute @DEFAULT_SINK@ toggle")
-# Test PipeWire direct access:
-machine.succeed("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 pw-dump")
-machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei -v exec --pipewire pw-dump")
-
-# Test XWayland (foot does not support X):
-swaymsg("exec x11-alacritty")
-wait_for_window(f"u0_a{hakurei_identity(0)}@machine")
-machine.send_chars("clear; glinfo && touch /var/tmp/x11-ok\n")
-machine.wait_for_file("/var/tmp/x11-ok")
-collect_state_ui("alacritty_x11")
-check_state("x11-alacritty", {"x11": True})
-machine.send_chars("exit\n")
-machine.wait_until_fails("pgrep alacritty")
-
-# Start app (foot) with direct Wayland access:
-swaymsg("exec da-foot")
-wait_for_window(f"u0_a{hakurei_identity(3)}@machine")
-machine.send_chars("clear; wayland-info && touch /var/tmp/direct-ok\n")
-collect_state_ui("foot_direct")
-machine.wait_for_file("/var/tmp/direct-ok")
-check_state("da-foot", {"wayland": True})
-# Verify acl on XDG_RUNTIME_DIR:
-print(machine.succeed(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(3) + 10000}"))
-machine.send_chars("exit\n")
-machine.wait_until_fails("pgrep foot")
-# Verify acl cleanup on XDG_RUNTIME_DIR:
-machine.wait_until_fails(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(3) + 10000}")
-
-# Test syscall filter:
-print(machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 strace-failure"))
-
-# Start app (foot) with Wayland enablement from a terminal:
-swaymsg("exec foot $SHELL -c '(ne-foot) & disown && exec $SHELL'")
-wait_for_window(f"u0_a{hakurei_identity(0)}@machine")
-machine.send_chars("clear; wayland-info && touch /var/tmp/term-ok\n")
-machine.wait_for_file("/var/tmp/term-ok")
-machine.send_key("alt-h")
-machine.send_chars("clear; hakurei show $(hakurei ps --short) && touch /tmp/ps-show-ok && exec cat\n")
-machine.wait_for_file("/tmp/ps-show-ok")
-collect_state_ui("foot_wayland_term")
-check_state("ne-foot", {"wayland": True})
-machine.send_key("alt-l")
-machine.send_chars("exit\n")
-wait_for_window("alice@machine")
-machine.send_key("ctrl-c")
-machine.wait_until_fails("pgrep foot")
-
-# Exit Sway and verify process exit status 0:
-machine.wait_until_fails("pgrep -x hakurei")
-swaymsg("exit", succeed=False)
-machine.wait_for_file("/tmp/sway-exit-ok")
-
-# Print hakurei share and rundir contents:
-print(machine.succeed("find /tmp/hakurei.0 "
- + "-path '/tmp/hakurei.0/runtime/*/*' -prune -o "
- + "-path '/tmp/hakurei.0/tmpdir/*/*' -prune -o "
- + "-print"))
-print(machine.succeed("find /run/user/1000/hakurei"))
-machine.succeed("find /tmp -maxdepth 1 -type d -name '.hakurei-shim-*' -print -exec false '{}' +")
-
-# Verify go test status:
-machine.wait_for_file("/tmp/hakurei-test-done")
-print(machine.succeed("cat /tmp/hakurei-test.log"))
-machine.wait_for_file("/tmp/hakurei-test-ok")