pytrainer: unpin python 3.10
[NixPkgs.git] / pkgs / build-support / singularity-tools / default.nix
blob2a671696287955e6e3f69c92405d7c102989616c
2   lib,
3   # Build helpers
4   stdenv,
5   runCommand,
6   vmTools,
7   writeClosure,
8   writeDirectReferencesToFile,
9   writeScript,
10   writeStringReferencesToFile,
11   # Native build inputs
12   buildPackages,
13   e2fsprogs,
14   util-linux,
15   # Build inputs
16   bashInteractive,
17   runtimeShell,
18   singularity,
21 let
22   defaultSingularity = singularity;
24 lib.makeExtensible (final: {
25   # TODO(@ShamrockLee): Remove after Nixpkgs 24.11 branch-off.
26   shellScript =
27     lib.warn
28       "`singularity-tools.shellScript` is deprecated. Use `writeScript`, `writeShellScripts` or `writers.writeBash` instead."
29       (
30         name: text:
31         writeScript name ''
32           #!${runtimeShell}
33           set -e
34           ${text}
35         ''
36       );
38   # TODO(@ShamrockLee): Remove after Nixpkgs 24.11 branch-off.
39   mkLayer =
40     lib.warn
41       "`singularity-tools.mkLayer` is deprecated, as it is no longer used to implement `singularity-tools.buildImages`."
42       (
43         {
44           name,
45           contents ? [ ],
46           # May be "apptainer" instead of "singularity"
47           projectName ? (singularity.projectName or "singularity"),
48         }:
49         runCommand "${projectName}-layer-${name}" { inherit contents; } ''
50           mkdir $out
51           for f in $contents ; do
52             cp -ra $f $out/
53           done
54         ''
55       );
57   buildImage =
58     {
59       name,
60       contents ? [ ],
61       diskSize ? 1024,
62       memSize ? 1024,
63       runAsRoot ? null,
64       runScript ? "#!${stdenv.shell}\nexec /bin/sh",
65       singularity ? defaultSingularity,
66     }:
67     let
68       projectName = singularity.projectName or "singularity";
69       runAsRootFile = buildPackages.writers.writeBash "run-as-root.sh" ''
70         set -e
71         ${runAsRoot}
72       '';
73       runScriptFile = writeScript "run-script.sh" ''
74         #!/bin/sh
75         set -e
76         ${runScript}
77       '';
78       runScriptReferences =
79         if builtins ? getContext then
80           lib.splitString "\n" (writeStringReferencesToFile runScriptFile.text).text
81         else
82           [ (writeDirectReferencesToFile runScriptFile) ];
83       result = vmTools.runInLinuxVM (
84         runCommand "${projectName}-image-${name}.sif"
85           {
86             nativeBuildInputs = [
87               singularity
88               e2fsprogs
89               util-linux
90             ];
91             strictDeps = true;
92             layerClosure = writeClosure ([ bashInteractive ] ++ runScriptReferences ++ contents);
93             preVM = vmTools.createEmptyImage {
94               size = diskSize;
95               fullName = "${projectName}-run-disk";
96               # Leaving "$out" for the Singularity/Container image
97               destination = "disk-image";
98             };
99             inherit memSize;
100           }
101           ''
102             rmdir "$out"
103             mkdir workspace
104             mkfs -t ext3 -b 4096 /dev/${vmTools.hd}
105             mount /dev/${vmTools.hd} workspace
106             mkdir -p workspace/img
107             cd workspace/img
108             mkdir proc sys dev
110             # Run root script
111             ${lib.optionalString (runAsRoot != null) ''
112               mkdir -p ./${builtins.storeDir}
113               mount --rbind "${builtins.storeDir}" ./${builtins.storeDir}
114               unshare -imnpuf --mount-proc chroot ./ ${runAsRootFile}
115               umount -R ./${builtins.storeDir}
116             ''}
118             # Build /bin and copy across closure
119             mkdir -p bin ./${builtins.storeDir}
120             # Loop over the line-separated paths in $layerClosure
121             while IFS= read -r f; do
122               cp -r "$f" "./$f"
123             done < "$layerClosure"
125             # TODO(@ShamrockLee):
126             # Once vmTools.runInLinuxVMm works with `__structuredAttrs = true` (#334705),
127             # set __structuredAttrs = true and pass contents as an attribute
128             # so that we could loop with `for c in ''${contents[@]}`
129             # instead of expanding all the paths in contents into the Bash string.
130             for c in ${lib.escapeShellArgs contents} ; do
131               for f in "$c"/bin/* ; do
132                 if [ ! -e "bin/$(basename "$f")" ] ; then
133                   ln -s "$f" bin/
134                 fi
135               done
136             done
138             # Link /bin/sh
139             if [ ! -e bin/sh ]; then
140               ln -s ${lib.getExe bashInteractive} bin/sh
141             fi
142             mkdir -p .singularity.d
144             # Create runscript
145             cp "${runScriptFile}" .singularity.d/runscript
147             # Fill out .singularity.d
148             mkdir -p .singularity.d/env
149             touch .singularity.d/env/94-appsbase.sh
151             cd ..
152             mkdir -p /var/lib/${projectName}/mnt/session
153             echo "root:x:0:0:System administrator:/root:/bin/sh" > /etc/passwd
154             echo > /etc/resolv.conf
155             TMPDIR="$(pwd -P)" ${projectName} build "$out" ./img
156           ''
157       );
159     in
160     result;