2016-11-14 02:26:59 +01:00
|
|
|
{ runCommand
|
2021-01-24 01:40:18 +01:00
|
|
|
, lib
|
2016-11-14 02:26:59 +01:00
|
|
|
, stdenv
|
|
|
|
, storeDir ? builtins.storeDir
|
|
|
|
, writeScript
|
|
|
|
, singularity
|
|
|
|
, writeReferencesToFile
|
|
|
|
, bash
|
|
|
|
, vmTools
|
|
|
|
, gawk
|
2020-11-24 16:29:28 +01:00
|
|
|
, util-linux
|
2019-02-26 12:45:54 +01:00
|
|
|
, runtimeShell
|
2023-01-28 18:02:47 +01:00
|
|
|
, e2fsprogs
|
|
|
|
}:
|
2016-11-14 02:26:59 +01:00
|
|
|
rec {
|
|
|
|
shellScript = name: text:
|
|
|
|
writeScript name ''
|
2019-02-26 12:45:54 +01:00
|
|
|
#!${runtimeShell}
|
2016-11-14 02:26:59 +01:00
|
|
|
set -e
|
|
|
|
${text}
|
|
|
|
'';
|
|
|
|
|
2023-01-28 18:02:47 +01:00
|
|
|
mkLayer =
|
|
|
|
{ name
|
|
|
|
, contents ? [ ]
|
2023-01-28 18:02:47 +01:00
|
|
|
# May be "apptainer" instead of "singularity"
|
|
|
|
, projectName ? (singularity.projectName or "singularity")
|
2023-01-28 18:02:47 +01:00
|
|
|
}:
|
2023-01-28 18:02:47 +01:00
|
|
|
runCommand "${projectName}-layer-${name}"
|
2023-01-28 18:02:47 +01:00
|
|
|
{
|
|
|
|
inherit contents;
|
|
|
|
} ''
|
2016-11-14 02:26:59 +01:00
|
|
|
mkdir $out
|
|
|
|
for f in $contents ; do
|
|
|
|
cp -ra $f $out/
|
|
|
|
done
|
|
|
|
'';
|
|
|
|
|
2023-01-28 18:02:47 +01:00
|
|
|
buildImage =
|
2023-01-28 18:02:47 +01:00
|
|
|
let
|
|
|
|
defaultSingularity = singularity;
|
|
|
|
in
|
2023-01-28 18:02:47 +01:00
|
|
|
{ name
|
|
|
|
, contents ? [ ]
|
|
|
|
, diskSize ? 1024
|
|
|
|
, runScript ? "#!${stdenv.shell}\nexec /bin/sh"
|
|
|
|
, runAsRoot ? null
|
|
|
|
, memSize ? 512
|
2023-01-28 18:02:47 +01:00
|
|
|
, singularity ? defaultSingularity
|
2023-01-28 18:02:47 +01:00
|
|
|
}:
|
|
|
|
let
|
2023-01-28 18:02:47 +01:00
|
|
|
projectName = singularity.projectName or "singularity";
|
2023-01-28 18:02:47 +01:00
|
|
|
layer = mkLayer {
|
|
|
|
inherit name;
|
|
|
|
contents = contents ++ [ bash runScriptFile ];
|
2023-01-28 18:02:47 +01:00
|
|
|
inherit projectName;
|
2023-01-28 18:02:47 +01:00
|
|
|
};
|
|
|
|
runAsRootFile = shellScript "run-as-root.sh" runAsRoot;
|
|
|
|
runScriptFile = shellScript "run-script.sh" runScript;
|
|
|
|
result = vmTools.runInLinuxVM (
|
2023-01-28 18:02:47 +01:00
|
|
|
runCommand "${projectName}-image-${name}.img"
|
2023-01-28 18:02:47 +01:00
|
|
|
{
|
2020-11-24 16:29:28 +01:00
|
|
|
buildInputs = [ singularity e2fsprogs util-linux gawk ];
|
2016-11-14 02:26:59 +01:00
|
|
|
layerClosure = writeReferencesToFile layer;
|
|
|
|
preVM = vmTools.createEmptyImage {
|
|
|
|
size = diskSize;
|
2023-01-28 18:02:47 +01:00
|
|
|
fullName = "${projectName}-run-disk";
|
2016-11-14 02:26:59 +01:00
|
|
|
};
|
2022-03-03 20:54:17 +01:00
|
|
|
inherit memSize;
|
2016-11-14 02:26:59 +01:00
|
|
|
}
|
|
|
|
''
|
|
|
|
rm -rf $out
|
|
|
|
mkdir disk
|
|
|
|
mkfs -t ext3 -b 4096 /dev/${vmTools.hd}
|
|
|
|
mount /dev/${vmTools.hd} disk
|
2020-01-31 00:44:01 +01:00
|
|
|
mkdir -p disk/img
|
|
|
|
cd disk/img
|
2017-11-07 04:47:20 +01:00
|
|
|
mkdir proc sys dev
|
2016-11-14 02:26:59 +01:00
|
|
|
|
|
|
|
# Run root script
|
2021-01-24 01:40:18 +01:00
|
|
|
${lib.optionalString (runAsRoot != null) ''
|
2016-11-14 02:26:59 +01:00
|
|
|
mkdir -p ./${storeDir}
|
|
|
|
mount --rbind ${storeDir} ./${storeDir}
|
|
|
|
unshare -imnpuf --mount-proc chroot ./ ${runAsRootFile}
|
|
|
|
umount -R ./${storeDir}
|
|
|
|
''}
|
|
|
|
|
|
|
|
# Build /bin and copy across closure
|
2021-10-27 08:11:31 +02:00
|
|
|
mkdir -p bin ./${builtins.storeDir}
|
2016-11-14 02:26:59 +01:00
|
|
|
for f in $(cat $layerClosure) ; do
|
|
|
|
cp -ar $f ./$f
|
2017-10-10 20:41:54 +02:00
|
|
|
done
|
|
|
|
|
|
|
|
for c in ${toString contents} ; do
|
|
|
|
for f in $c/bin/* ; do
|
2016-11-14 02:26:59 +01:00
|
|
|
if [ ! -e bin/$(basename $f) ] ; then
|
|
|
|
ln -s $f bin/
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
done
|
|
|
|
|
2020-01-31 00:44:01 +01:00
|
|
|
# Create runScript and link shell
|
2020-07-13 23:20:14 +02:00
|
|
|
if [ ! -e bin/sh ]; then
|
|
|
|
ln -s ${runtimeShell} bin/sh
|
|
|
|
fi
|
2023-01-28 18:02:47 +01:00
|
|
|
mkdir -p .${projectName}.d
|
|
|
|
ln -s ${runScriptFile} .${projectName}.d/runscript
|
2016-11-14 02:26:59 +01:00
|
|
|
|
2023-01-28 18:02:47 +01:00
|
|
|
# Fill out .${projectName}.d
|
|
|
|
mkdir -p .${projectName}.d/env
|
|
|
|
touch .${projectName}.d/env/94-appsbase.sh
|
2016-11-14 02:26:59 +01:00
|
|
|
|
2018-11-01 01:21:02 +01:00
|
|
|
cd ..
|
2023-01-28 18:02:47 +01:00
|
|
|
mkdir -p /var/lib/${projectName}/mnt/{container,final,overlay,session,source}
|
2018-11-01 01:21:02 +01:00
|
|
|
echo "root:x:0:0:System administrator:/root:/bin/sh" > /etc/passwd
|
2020-07-15 14:05:37 +02:00
|
|
|
echo > /etc/resolv.conf
|
2023-01-28 18:02:47 +01:00
|
|
|
TMPDIR=$(pwd -P) ${projectName} build $out ./img
|
2016-11-14 02:26:59 +01:00
|
|
|
'');
|
|
|
|
|
2023-01-28 18:02:47 +01:00
|
|
|
in
|
|
|
|
result;
|
2016-11-14 02:26:59 +01:00
|
|
|
}
|