default.nix (2945B)
1 # The ideal is that a Liminix system can boot with only the files in 2 # /nix/store. This package generates a small program that is run at early 3 # boot (from the initramfs) to populate directories such as /etc, 4 # /bin, /home according to whatever the configuration says 5 # they should contain 6 7 { 8 writeText 9 , lib 10 , s6-init-bin 11 , closureInfo 12 , stdenv 13 }: 14 let 15 inherit (lib.attrsets) mapAttrsToList; 16 escaped = msg : builtins.replaceStrings 17 ["\n" "=" "\"" "$" ] 18 ["\\x0a" "\\x3d" "\\x22" "\\x24"] 19 msg; 20 21 visit = prefix: attrset: 22 let makeFile = prefix : filename: { 23 type ? "f" 24 , mode ? null 25 , target ? null 26 , contents ? null 27 , file ? null 28 , major ? null 29 , minor ? null 30 , uid ? 0 31 , gid ? 0 32 }: 33 let 34 pathname = "${prefix}/${filename}"; 35 qpathname = builtins.toJSON pathname; 36 mode' = if mode != null 37 then mode 38 else 39 (if type == "d" then "0755" else "0644"); 40 cmds = { 41 "f" = "PRINTFILE(${qpathname}, ${mode'}, ${builtins.toJSON (escaped file)});"; 42 "d" = "MKDIR(${qpathname}, ${mode'});\n" + 43 (builtins.concatStringsSep "\n" 44 (visit pathname contents)); 45 "c" = "MKNOD_C(${qpathname}, ${mode'}, ${major}, ${minor});"; 46 "b" = "MKNOD_B(${qpathname}, ${mode'}, ${major}, ${minor});"; 47 "s" = "LN_S(${builtins.toJSON target}, ${qpathname});"; 48 "l" = "LN(${builtins.toJSON target}, ${qpathname})"; 49 "i" = "MKNOD_P(${qpathname}, ${mode'});"; 50 }; 51 cmd = cmds.${type}; 52 chown = if uid>0 || gid>0 53 then "\nCHOWN(${qpathname},${toString uid},${toString gid});\n" 54 else ""; 55 in "${cmd} ${chown}"; 56 in mapAttrsToList (makeFile prefix) attrset; 57 activateScript = attrset: writeText "makedevs.c" '' 58 #include "defs.h" 59 int main(int argc, char* argv[]) { 60 chdir(argv[1]); 61 ${(builtins.concatStringsSep "\n" (visit "." attrset))} 62 } 63 ''; 64 in attrset: 65 let makedevs = activateScript attrset; 66 in stdenv.mkDerivation { 67 name="make-stuff"; 68 src = ./.; 69 70 CFLAGS = "-Os"; 71 LDFLAGS = "-static -Xlinker -static"; 72 73 postConfigure = '' 74 cp ${makedevs} makedevs.c 75 ''; 76 makeFlags = ["makedevs"]; 77 installPhase = '' 78 closure=${closureInfo { rootPaths = [ makedevs ]; }} 79 mkdir -p $out/bin $out/etc 80 cp $closure/store-paths $out/etc/nix-store-paths 81 $STRIP --remove-section=.note --remove-section=.comment --strip-all makedevs -o $out/bin/activate 82 ln -s ${s6-init-bin}/bin/init $out/bin/init 83 cat > $out/bin/install <<EOF 84 #!/bin/sh 85 cp -v -fP $out/bin/* $out/etc/* \''${1-/}/persist 86 EOF 87 chmod +x $out/bin/install 88 ''; 89 }