0
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-14 06:00:33 +03:00

nix-required-mounts: guest and host paths may differ

This commit is contained in:
Someone Serge 2023-11-11 14:02:54 +00:00
parent 7418e4fefd
commit 5560f6a514
5 changed files with 52 additions and 16 deletions

View file

@ -5,16 +5,23 @@ let
package = pkgs.nix-required-mounts; package = pkgs.nix-required-mounts;
overridenPackage = package.override { inherit (cfg) allowedPatterns; }; overridenPackage = package.override { inherit (cfg) allowedPatterns; };
Mount = with lib; types.submodule {
options.host = mkOption { type = types.str; description = "Host path to mount"; };
options.guest = mkOption {
type = types.str;
description = "Location in the sandbox to mount the host path at";
};
};
Pattern = with lib.types; Pattern = with lib.types;
submodule ({ config, name, ... }: { types.submodule ({ config, name, ... }: {
options.onFeatures = lib.mkOption { options.onFeatures = lib.mkOption {
type = listOf str; type = listOf types.str;
description = description =
"Which requiredSystemFeatures should trigger relaxation of the sandbox"; "Which requiredSystemFeatures should trigger relaxation of the sandbox";
default = [ name ]; default = [ name ];
}; };
options.paths = lib.mkOption { options.paths = lib.mkOption {
type = listOf path; type = listOf (oneOf [ path Mount ]);
description = description =
"A list of glob patterns, indicating which paths to expose to the sandbox"; "A list of glob patterns, indicating which paths to expose to the sandbox";
}; };

View file

@ -19,10 +19,19 @@ in
programs.nix-required-mounts.enable = true; programs.nix-required-mounts.enable = true;
programs.nix-required-mounts.allowedPatterns.supported-feature = { programs.nix-required-mounts.allowedPatterns.supported-feature = {
onFeatures = [ "supported-feature" ]; onFeatures = [ "supported-feature" ];
paths = [ "/supported-feature-files" ]; paths = [
"/supported-feature-files"
{
host = "/usr/lib/imaginary-fhs-drivers";
guest = "/run/opengl-driver/lib";
}
];
}; };
users.users.person.isNormalUser = true; users.users.person.isNormalUser = true;
virtualisation.fileSystems."/supported-feature-files".fsType = "tmpfs"; systemd.tmpfiles.rules = [
"d /supported-feature-files 0755 person users -"
"f /usr/lib/imaginary-fhs-drivers/libcuda.so 0444 root root -"
];
}; };
testScript = '' testScript = ''
import shlex import shlex

View file

@ -4,9 +4,13 @@ pkgs.runCommandNoCC "${feature}-present"
{ {
requiredSystemFeatures = [ feature ]; requiredSystemFeatures = [ feature ];
} '' } ''
if [[ -e /${feature}-files ]]; then if [[ ! -e /${feature}-files ]]; then
touch $out
else
echo "The host declares ${feature} support, but doesn't expose /${feature}-files" >&2 echo "The host declares ${feature} support, but doesn't expose /${feature}-files" >&2
exit 1
fi fi
if [[ ! -f /run/opengl-driver/lib/libcuda.so ]] ; then
echo "The host declares ${feature} support, but it the hook fails to handle the hostPath != guestPath cases" >&2
exit 1
fi
touch $out
'' ''

View file

@ -8,12 +8,20 @@ from argparse import ArgumentParser
from itertools import chain from itertools import chain
from pathlib import Path from pathlib import Path
from sys import stderr from sys import stderr
from typing import Dict, List, TypedDict from typing import Dict, List, Tuple, TypeAlias, TypedDict
Glob: TypeAlias = str
PathString: TypeAlias = str
class Mount(TypedDict):
host: PathString
guest: PathString
class Pattern(TypedDict): class Pattern(TypedDict):
onFeatures: List[str] onFeatures: List[str]
paths: List[str] # List of glob patterns paths: List[Glob | Mount]
class HookConfig(TypedDict): class HookConfig(TypedDict):
@ -106,12 +114,21 @@ def entrypoint():
features = get_strings(drv_env, "requiredSystemFeatures") features = get_strings(drv_env, "requiredSystemFeatures")
features = list(filter(known_features.__contains__, features)) features = list(filter(known_features.__contains__, features))
patterns = list( patterns: List[PathString | Mount] = list(
chain.from_iterable(allowed_patterns[f]["paths"] for f in features) chain.from_iterable(allowed_patterns[f]["paths"] for f in features)
) # noqa: E501 ) # noqa: E501
roots = sorted( # TODO: Would it make sense to preserve the original order instead?
set(Path(path) for pattern in patterns for path in glob.glob(pattern)) roots: List[Tuple[PathString, PathString]] = sorted(
set(
mnt
for pattern in patterns
for mnt in (
((path, path) for path in glob.glob(pattern))
if isinstance(pattern, PathString)
else [(pattern["guest"], pattern["host"])]
)
)
) )
# the pre-build-hook command # the pre-build-hook command
@ -121,8 +138,7 @@ def entrypoint():
print("extra-sandbox-paths") print("extra-sandbox-paths")
# arguments, one per line # arguments, one per line
for p in roots: for guest_path, host_path in roots:
guest_path, host_path = p, p
print(f"{guest_path}={host_path}") print(f"{guest_path}={host_path}")
# terminated by an empty line # terminated by an empty line

View file

@ -3,7 +3,7 @@
, allowedPatterns ? rec { , allowedPatterns ? rec {
# This config is just an example. # This config is just an example.
# When the hook observes either of the following requiredSystemFeatures: # When the hook observes either of the following requiredSystemFeatures:
nvidia-gpu.onFeatures = [ "gpu" "opengl" "vulkan" "cuda" ]; nvidia-gpu.onFeatures = [ "gpu" "nvidia-gpu" "opengl" "cuda" ];
# It exposes these paths in the sandbox: # It exposes these paths in the sandbox:
nvidia-gpu.paths = [ nvidia-gpu.paths = [
# Note that mounting /run/opengl-driver/lib actually isn't sufficient, # Note that mounting /run/opengl-driver/lib actually isn't sufficient,