nixpkgs/pkgs/build-support/singularity-tools/default.nix

162 lines
4.8 KiB
Nix
Raw Normal View History

{
lib,
# Build helpers
stdenv,
runCommand,
vmTools,
writeClosure,
writeDirectReferencesToFile,
writeScript,
writeStringReferencesToFile,
# Native build inputs
buildPackages,
e2fsprogs,
util-linux,
# Build inputs
bashInteractive,
runtimeShell,
singularity,
2023-01-28 17:02:47 +00:00
}:
let
defaultSingularity = singularity;
in
2024-08-10 14:34:01 +00:00
lib.makeExtensible (final: {
# TODO(@ShamrockLee): Remove after Nixpkgs 24.11 branch-off.
shellScript =
lib.warn
"`singularity-tools.shellScript` is deprecated. Use `writeScript`, `writeShellScripts` or `writers.writeBash` instead."
(
name: text:
writeScript name ''
#!${runtimeShell}
set -e
${text}
''
);
2016-11-14 01:26:59 +00:00
# TODO(@ShamrockLee): Remove after Nixpkgs 24.11 branch-off.
2023-01-28 17:02:47 +00:00
mkLayer =
lib.warn
"`singularity-tools.mkLayer` is deprecated, as it is no longer used to implement `singularity-tools.buildImages`."
(
{
name,
contents ? [ ],
# May be "apptainer" instead of "singularity"
projectName ? (singularity.projectName or "singularity"),
}:
runCommand "${projectName}-layer-${name}" { inherit contents; } ''
mkdir $out
for f in $contents ; do
cp -ra $f $out/
done
''
);
2016-11-14 01:26:59 +00:00
2023-01-28 17:02:47 +00:00
buildImage =
{
name,
contents ? [ ],
diskSize ? 1024,
memSize ? 1024,
runAsRoot ? null,
runScript ? "#!${stdenv.shell}\nexec /bin/sh",
singularity ? defaultSingularity,
2023-01-28 17:02:47 +00:00
}:
let
projectName = singularity.projectName or "singularity";
runAsRootFile = buildPackages.writers.writeBash "run-as-root.sh" ''
set -e
${runAsRoot}
'';
runScriptFile = writeScript "run-script.sh" ''
#!/bin/sh
set -e
${runScript}
'';
runScriptReferences =
if builtins ? getContext then
lib.splitString "\n" (writeStringReferencesToFile runScriptFile.text).text
else
[ (writeDirectReferencesToFile runScriptFile) ];
2023-01-28 17:02:47 +00:00
result = vmTools.runInLinuxVM (
runCommand "${projectName}-image-${name}.sif"
2023-01-28 17:02:47 +00:00
{
nativeBuildInputs = [
singularity
e2fsprogs
util-linux
];
strictDeps = true;
layerClosure = writeClosure ([ bashInteractive ] ++ runScriptReferences ++ contents);
2016-11-14 01:26:59 +00:00
preVM = vmTools.createEmptyImage {
size = diskSize;
fullName = "${projectName}-run-disk";
# Leaving "$out" for the Singularity/Container image
destination = "disk-image";
2016-11-14 01:26:59 +00:00
};
inherit memSize;
2016-11-14 01:26:59 +00:00
}
''
rmdir "$out"
mkdir workspace
2016-11-14 01:26:59 +00:00
mkfs -t ext3 -b 4096 /dev/${vmTools.hd}
mount /dev/${vmTools.hd} workspace
mkdir -p workspace/img
cd workspace/img
2017-11-07 03:47:20 +00:00
mkdir proc sys dev
2016-11-14 01:26:59 +00:00
# Run root script
2021-01-24 00:40:18 +00:00
${lib.optionalString (runAsRoot != null) ''
mkdir -p ./${builtins.storeDir}
mount --rbind "${builtins.storeDir}" ./${builtins.storeDir}
2016-11-14 01:26:59 +00:00
unshare -imnpuf --mount-proc chroot ./ ${runAsRootFile}
umount -R ./${builtins.storeDir}
2016-11-14 01:26:59 +00:00
''}
# Build /bin and copy across closure
mkdir -p bin ./${builtins.storeDir}
# Loop over the line-separated paths in $layerClosure
while IFS= read -r f; do
cp -r "$f" "./$f"
done < "$layerClosure"
# TODO(@ShamrockLee):
# Once vmTools.runInLinuxVMm works with `__structuredAttrs = true` (#334705),
# set __structuredAttrs = true and pass contents as an attribute
# so that we could loop with `for c in ''${contents[@]}`
# instead of expanding all the paths in contents into the Bash string.
for c in ${lib.escapeShellArgs contents} ; do
for f in "$c"/bin/* ; do
if [ ! -e "bin/$(basename "$f")" ] ; then
ln -s "$f" bin/
2016-11-14 01:26:59 +00:00
fi
done
done
# Link /bin/sh
if [ ! -e bin/sh ]; then
ln -s ${lib.getExe bashInteractive} bin/sh
fi
mkdir -p .singularity.d
# Create runscript
cp "${runScriptFile}" .singularity.d/runscript
2016-11-14 01:26:59 +00:00
# Fill out .singularity.d
mkdir -p .singularity.d/env
touch .singularity.d/env/94-appsbase.sh
2016-11-14 01:26:59 +00:00
2018-11-01 00:21:02 +00:00
cd ..
mkdir -p /var/lib/${projectName}/mnt/session
2018-11-01 00:21:02 +00:00
echo "root:x:0:0:System administrator:/root:/bin/sh" > /etc/passwd
2020-07-15 12:05:37 +00:00
echo > /etc/resolv.conf
TMPDIR="$(pwd -P)" ${projectName} build "$out" ./img
''
);
2016-11-14 01:26:59 +00:00
2023-01-28 17:02:47 +00:00
in
result;
2024-08-10 14:34:01 +00:00
})