1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
{ pkgs, lib, ... }:
let
testCDIScript = pkgs.writeShellScriptBin "test-cdi" ''
die() {
echo "$1"
exit 1
}
check_file_referential_integrity() {
echo "checking $1 referential integrity"
( ${pkgs.glibc.bin}/bin/ldd "$1" | ${lib.getExe pkgs.gnugrep} "not found" &> /dev/null ) && return 1
return 0
}
check_directory_referential_integrity() {
${lib.getExe pkgs.findutils} "$1" -type f -print0 | while read -d $'\0' file; do
if [[ $(${lib.getExe pkgs.file} "$file" | ${lib.getExe pkgs.gnugrep} ELF) ]]; then
check_file_referential_integrity "$file" || exit 1
else
echo "skipping $file: not an ELF file"
fi
done
}
check_directory_referential_integrity "/usr/bin" || exit 1
check_directory_referential_integrity "${pkgs.addDriverRunpath.driverLink}" || exit 1
check_directory_referential_integrity "/usr/local/nvidia" || exit 1
'';
testContainerImage = pkgs.dockerTools.buildImage {
name = "cdi-test";
tag = "latest";
config = {
Cmd = [ (lib.getExe testCDIScript) ];
};
copyToRoot = with pkgs.dockerTools; [
usrBinEnv
binSh
];
};
emptyCDISpec = ''
{
"cdiVersion": "0.5.0",
"kind": "nvidia.com/gpu",
"devices": [
{
"name": "all",
"containerEdits": {
"deviceNodes": [
{
"path": "/dev/urandom"
}
],
"hooks": [],
"mounts": []
}
}
],
"containerEdits": {
"deviceNodes": [],
"hooks": [],
"mounts": []
}
}
'';
nvidia-container-toolkit = {
enable = true;
package = pkgs.stdenv.mkDerivation {
pname = "nvidia-ctk-dummy";
version = "1.0.0";
dontUnpack = true;
dontBuild = true;
inherit emptyCDISpec;
passAsFile = [ "emptyCDISpec" ];
installPhase = ''
mkdir -p $out/bin $out/share/nvidia-container-toolkit
cp "$emptyCDISpecPath" "$out/share/nvidia-container-toolkit/spec.json"
echo -n "$emptyCDISpec" > "$out/bin/nvidia-ctk";
cat << EOF > "$out/bin/nvidia-ctk"
#!${pkgs.runtimeShell}
cat "$out/share/nvidia-container-toolkit/spec.json"
EOF
chmod +x $out/bin/nvidia-ctk
'';
meta.mainProgram = "nvidia-ctk";
};
suppressNvidiaDriverAssertion = true;
};
in
{
name = "nvidia-container-toolkit";
meta = with lib.maintainers; {
maintainers = [
ereslibre
christoph-heiss
];
};
defaults =
{ config, ... }:
{
environment.systemPackages = with pkgs; [ jq ];
virtualisation.diskSize = lib.mkDefault 10240;
virtualisation.containers = {
containersConf.settings.engine.cdi_spec_dirs = [ "/var/run/cdi" ];
enable = lib.mkDefault true;
};
hardware = {
inherit nvidia-container-toolkit;
nvidia = {
open = true;
package = config.boot.kernelPackages.nvidiaPackages.stable.open;
};
graphics.enable = lib.mkDefault true;
};
};
nodes = {
no-gpus = {
virtualisation.containers.enable = false;
};
one-gpu =
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [ podman ];
hardware.graphics.enable = true;
};
one-gpu-invalid-host-paths = {
hardware.nvidia-container-toolkit.mounts = [
{
hostPath = "/non-existant-path";
containerPath = "/some/path";
}
];
};
};
testScript = ''
start_all()
with subtest("Generate an empty CDI spec for a machine with no Nvidia GPUs"):
no_gpus.wait_for_unit("nvidia-container-toolkit-cdi-generator.service")
no_gpus.succeed("cat /var/run/cdi/nvidia-container-toolkit.json | jq")
with subtest("Podman loads the generated CDI spec for a machine with an Nvidia GPU"):
one_gpu.wait_for_unit("nvidia-container-toolkit-cdi-generator.service")
one_gpu.succeed("cat /var/run/cdi/nvidia-container-toolkit.json | jq")
one_gpu.succeed("podman load < ${testContainerImage}")
one_gpu.succeed("podman run --pull=never --device=nvidia.com/gpu=all -v /run/opengl-driver:/run/opengl-driver:ro cdi-test:latest")
# Issue: https://github.com/NixOS/nixpkgs/issues/319201
with subtest("The generated CDI spec skips specified non-existant paths in the host"):
one_gpu_invalid_host_paths.wait_for_unit("nvidia-container-toolkit-cdi-generator.service")
one_gpu_invalid_host_paths.fail("grep 'non-existant-path' /var/run/cdi/nvidia-container-toolkit.json")
'';
}
|