at 24.11-pre 117 lines 3.1 kB view raw
1{ runCommand 2, lib 3, stdenv 4, storeDir ? builtins.storeDir 5, writeScript 6, singularity 7, writeClosure 8, bash 9, vmTools 10, gawk 11, util-linux 12, runtimeShell 13, e2fsprogs 14}: 15rec { 16 shellScript = name: text: 17 writeScript name '' 18 #!${runtimeShell} 19 set -e 20 ${text} 21 ''; 22 23 mkLayer = 24 { name 25 , contents ? [ ] 26 # May be "apptainer" instead of "singularity" 27 , projectName ? (singularity.projectName or "singularity") 28 }: 29 runCommand "${projectName}-layer-${name}" 30 { 31 inherit contents; 32 } '' 33 mkdir $out 34 for f in $contents ; do 35 cp -ra $f $out/ 36 done 37 ''; 38 39 buildImage = 40 let 41 defaultSingularity = singularity; 42 in 43 { name 44 , contents ? [ ] 45 , diskSize ? 1024 46 , runScript ? "#!${stdenv.shell}\nexec /bin/sh" 47 , runAsRoot ? null 48 , memSize ? 512 49 , singularity ? defaultSingularity 50 }: 51 let 52 projectName = singularity.projectName or "singularity"; 53 runAsRootFile = shellScript "run-as-root.sh" runAsRoot; 54 runScriptFile = shellScript "run-script.sh" runScript; 55 result = vmTools.runInLinuxVM ( 56 runCommand "${projectName}-image-${name}.img" 57 { 58 buildInputs = [ singularity e2fsprogs util-linux gawk ]; 59 layerClosure = writeClosure contents; 60 preVM = vmTools.createEmptyImage { 61 size = diskSize; 62 fullName = "${projectName}-run-disk"; 63 }; 64 inherit memSize; 65 } 66 '' 67 rm -rf $out 68 mkdir disk 69 mkfs -t ext3 -b 4096 /dev/${vmTools.hd} 70 mount /dev/${vmTools.hd} disk 71 mkdir -p disk/img 72 cd disk/img 73 mkdir proc sys dev 74 75 # Run root script 76 ${lib.optionalString (runAsRoot != null) '' 77 mkdir -p ./${storeDir} 78 mount --rbind ${storeDir} ./${storeDir} 79 unshare -imnpuf --mount-proc chroot ./ ${runAsRootFile} 80 umount -R ./${storeDir} 81 ''} 82 83 # Build /bin and copy across closure 84 mkdir -p bin ./${builtins.storeDir} 85 for f in $(cat $layerClosure) ; do 86 cp -ar $f ./$f 87 done 88 89 for c in ${toString contents} ; do 90 for f in $c/bin/* ; do 91 if [ ! -e bin/$(basename $f) ] ; then 92 ln -s $f bin/ 93 fi 94 done 95 done 96 97 # Create runScript and link shell 98 if [ ! -e bin/sh ]; then 99 ln -s ${runtimeShell} bin/sh 100 fi 101 mkdir -p .${projectName}.d 102 ln -s ${runScriptFile} .${projectName}.d/runscript 103 104 # Fill out .${projectName}.d 105 mkdir -p .${projectName}.d/env 106 touch .${projectName}.d/env/94-appsbase.sh 107 108 cd .. 109 mkdir -p /var/lib/${projectName}/mnt/session 110 echo "root:x:0:0:System administrator:/root:/bin/sh" > /etc/passwd 111 echo > /etc/resolv.conf 112 TMPDIR=$(pwd -P) ${projectName} build $out ./img 113 ''); 114 115 in 116 result; 117}