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:
parent
7418e4fefd
commit
5560f6a514
5 changed files with 52 additions and 16 deletions
|
@ -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";
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
''
|
''
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue